<commit_before>package edu.indiana.lib.twinpeaks.search.sru;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import edu.indiana.lib.twinpeaks.util.*;


public class CqlParser extends org.xml.sax.helpers.DefaultHandler
{
  private static org.apache.commons.logging.Log	_log = LogUtils.getLog(CqlParser.class);
  //
	// Index mappings (CQL -> 360 Search) (this is pretty much CQL to CQL)
	//
	private static final java.util.Map INDEX_MAP = new java.util.HashMap();
	static
	{
		INDEX_MAP.put("keyword",  " ");
		INDEX_MAP.put("title",    "cs.title=");
		INDEX_MAP.put("author",   "cs.author=");
		INDEX_MAP.put("subject",  "cs.subject=");
		INDEX_MAP.put("year",     "cs.date=");
	}
  //
	// Boolean mappings (CQL -> 360 Search)
	//
	private static final java.util.Map BOOL_RELATION_MAP = new java.util.HashMap();
	static
	{
		BOOL_RELATION_MAP.put("and", " and ");
		BOOL_RELATION_MAP.put("or",  " or ");
		BOOL_RELATION_MAP.put("not", " not ");
	}
  //
	// SAX Parsing
	//
	SAXParser       saxParser;
	StringBuilder   textBuffer;
	StringBuilder   searchClause;
	boolean         inSearchClause;
	java.util.Stack cqlStack;
  //
  // Treat all non-keyword fields as phrases?
  //
	final static boolean TREAT_ALL_FIELDS_AS_PHRASE = true;
	//
	// Are we currently parsing a keyword field?
	//
	boolean inKeyword;

  /**
   * Constructor
   */
	public CqlParser()
	{
		// initialize stack
		cqlStack = new java.util.Stack();

		// initialize SAX Parser
		SAXParserFactory factory;

		factory = SAXParserFactory.newInstance();
		factory.setNamespaceAware(true);

		try
		{
			saxParser = factory.newSAXParser();
		}
		catch (org.xml.sax.SAXException e)
		{
			_log.error("SAX exception: " + e);
		}
		catch (ParserConfigurationException e)
		{
			_log.error("Parse failed: " + e);
		}
	}

	/**
	 * Converts a CQL-formatted search query into a format that 360 Search
	 * can understand.  Uses org.z3950.zing.cql.CQLNode.toXCQL() and SAX Parsing
	 * to convert the cqlSearchQuery into an almost identical query parameter.
	 *
	 * @param cqlSearchQuery CQL-formatted search query.
	 * @return A 360 Search query
	 * @see org.z3950.zing.cql.CQLNode.toXCQL()
	 */
	public String doCQL2MetasearchCommand( String cqlSearchQuery )
	{
		if (cqlSearchQuery == null || cqlSearchQuery.equals( "" ))
		{
			return null;
		}

		org.z3950.zing.cql.CQLParser parser = new org.z3950.zing.cql.CQLParser();
		org.z3950.zing.cql.CQLNode root = null;

    // Parse the user criteria
		try
		{
			root = parser.parse(cqlSearchQuery);
		}
		catch (Exception exception)
		{
			_log.error("Exception in CQL parse: " + exception);
		}

		String cqlXml = root.toXCQL( 0 );

		_log.debug("CQL XML:");
		_log.debug(cqlXml);

		// Open the CQL XML string as a stream
		java.io.ByteArrayInputStream byteInputStream = null;
		try
		{
			byteInputStream = new java.io.ByteArrayInputStream(cqlXml.getBytes("UTF8"));
		}
		catch (Exception exception)
		{
			_log.error("Exception opening input stream: " + exception);
		}

		// clear the stack
		cqlStack.removeAllElements();

		// Parse
		try
		{
			saxParser.parse(byteInputStream, this);
			byteInputStream.close();<commit_msg>SAK-13026 - Added a return null is root == null<commit_after>package edu.indiana.lib.twinpeaks.search.sru;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import edu.indiana.lib.twinpeaks.util.*;


public class CqlParser extends org.xml.sax.helpers.DefaultHandler
{
  private static org.apache.commons.logging.Log	_log = LogUtils.getLog(CqlParser.class);
  //
	// Index mappings (CQL -> 360 Search) (this is pretty much CQL to CQL)
	//
	private static final java.util.Map INDEX_MAP = new java.util.HashMap();
	static
	{
		INDEX_MAP.put("keyword",  " ");
		INDEX_MAP.put("title",    "cs.title=");
		INDEX_MAP.put("author",   "cs.author=");
		INDEX_MAP.put("subject",  "cs.subject=");
		INDEX_MAP.put("year",     "cs.date=");
	}
  //
	// Boolean mappings (CQL -> 360 Search)
	//
	private static final java.util.Map BOOL_RELATION_MAP = new java.util.HashMap();
	static
	{
		BOOL_RELATION_MAP.put("and", " and ");
		BOOL_RELATION_MAP.put("or",  " or ");
		BOOL_RELATION_MAP.put("not", " not ");
	}
  //
	// SAX Parsing
	//
	SAXParser       saxParser;
	StringBuilder   textBuffer;
	StringBuilder   searchClause;
	boolean         inSearchClause;
	java.util.Stack cqlStack;
  //
  // Treat all non-keyword fields as phrases?
  //
	final static boolean TREAT_ALL_FIELDS_AS_PHRASE = true;
	//
	// Are we currently parsing a keyword field?
	//
	boolean inKeyword;

  /**
   * Constructor
   */
	public CqlParser()
	{
		// initialize stack
		cqlStack = new java.util.Stack();

		// initialize SAX Parser
		SAXParserFactory factory;

		factory = SAXParserFactory.newInstance();
		factory.setNamespaceAware(true);

		try
		{
			saxParser = factory.newSAXParser();
		}
		catch (org.xml.sax.SAXException e)
		{
			_log.error("SAX exception: " + e);
		}
		catch (ParserConfigurationException e)
		{
			_log.error("Parse failed: " + e);
		}
	}

	/**
	 * Converts a CQL-formatted search query into a format that 360 Search
	 * can understand.  Uses org.z3950.zing.cql.CQLNode.toXCQL() and SAX Parsing
	 * to convert the cqlSearchQuery into an almost identical query parameter.
	 *
	 * @param cqlSearchQuery CQL-formatted search query.
	 * @return A 360 Search query
	 * @see org.z3950.zing.cql.CQLNode.toXCQL()
	 */
	public String doCQL2MetasearchCommand( String cqlSearchQuery )
	{
		if (cqlSearchQuery == null || cqlSearchQuery.equals( "" ))
		{
			return null;
		}

		org.z3950.zing.cql.CQLParser parser = new org.z3950.zing.cql.CQLParser();
		org.z3950.zing.cql.CQLNode root = null;

    // Parse the user criteria
		try
		{
			root = parser.parse(cqlSearchQuery);
		}
		catch (Exception exception)
		{
			_log.error("Exception in CQL parse: " + exception);
		}

		if (root == null)
		{
			return null;
		}

		String cqlXml = root.toXCQL( 0 );

		_log.debug("CQL XML:");
		_log.debug(cqlXml);

		// Open the CQL XML string as a stream
		java.io.ByteArrayInputStream byteInputStream = null;
		try
		{
			byteInputStream = new java.io.ByteArrayInputStream(cqlXml.getBytes("UTF8"));
		}
		catch (Exception exception)
		{
			_log.error("Exception opening input stream: " + exception);
		}

		// clear the stack
		cqlStack.removeAllElements();

		// Parse
		try
		{
			saxParser.parse(byteInputStream, this);
			byteInputStream.close();
{'fraction_non_alphanumeric': 0.12865936045638793, 'fraction_numerical': 0.011259570635039785, 'mean_word_length': 3.3599476439790577, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 14}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3026111', 'n_tokens_mistral': 2587, 'n_tokens_neox': 2352, 'n_words': 505}