content: package org.apache.solr.search;
  
  import org.apache.lucene.queryparser.flexible.aqp.AqpQueryParser;
  import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardLuceneParser;
  import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryConfigHandler;
  import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryNodeProcessorPipeline;
  import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryTreeBuilder;
  import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
  import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
  import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
  import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
  import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator;
  import org.apache.lucene.search.Query;
  import org.apache.solr.common.SolrException;
  import org.apache.solr.common.params.CommonParams;
  import org.apache.solr.common.params.SolrParams;
  import org.apache.solr.request.SolrQueryRequest;
  import org.apache.solr.schema.IndexSchema;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * This is the MAIN solr entry point - this instantiates a query
   * parser - it sets some default parameters from the config and prepares
   * ulr parameters.
   *
   * <p>
   * <p>
   * TODO: the parser needs to know configuration of data/numeric fields
   *       so that the analysis is done correctly. It is not done here
   *       for the moment (as this is SOLR-specific and needs more
   *       components)
   * <p>
   *       In principle, it is configured like this:
   *
   * <pre>
   *      HashMap&lt;String, NumericConfig&gt; ncm = new HashMap&lt;String, NumericConfig&gt;();
   *   		config.set(StandardQueryConfigHandler.ConfigurationKeys.NUMERIC_CONFIG_MAP, ncm);
   *      ncm.put(field_name, new NumericConfig(4, NumberFormat.getNumberInstance(Locale.US), NumericType.INT));
   * </pre>
   *
   * @see AqpLuceneQParserPlugin
   * @see AqpStandardLuceneParser
   * @see AqpStandardQueryConfigHandler
   * @see AqpStandardQueryNodeProcessorPipeline
   * @see AqpStandardQueryTreeBuilder
   */
  public class AqpLuceneQParser extends QParser {
  
      public static final Logger log = LoggerFactory
              .getLogger(AqpLuceneQParser.class);
  
      private final AqpQueryParser qParser;
  
      public AqpLuceneQParser(AqpQueryParser parser, String qstr, SolrParams localParams,
                              SolrParams params, SolrQueryRequest req)
              throws QueryNodeParseException {
  
          super(qstr, localParams, params, req);
          qParser = parser;
  
          if (getString() == null) {
              throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
                      "The query is empty");
          }
  
  
          IndexSchema schema = req.getSchema();
  
  
          // now configure the parser using the request params, likely incomplete (yet)
          QueryConfigHandler config = qParser.getQueryConfigHandler();
          qParser.setAnalyzer(schema.getQueryAnalyzer()); //CHECK: this used to be getAnalyzer(); potentially dangerous
          qParser.setDefaultField(params.get(CommonParams.DF, qParser.getDefaultField()));
  
          String opParam = getParam(QueryParsing.OP);
          if (opParam != null) {
              // other operators could also become default, eg. NEAR
              qParser.setDefaultOperator("AND".equalsIgnoreCase(opParam) ? Operator.AND
                      : Operator.OR);
          } else {
              qParser.setDefaultOperator(Operator.OR);
          }
  
  
          // this is not useful in solr world (?) - but must be available
          config.set(ConfigurationKeys.MULTI_FIELDS, new CharSequence[0]);
  
          if (params.getBool("debugQuery", false)) {
              try {
                  qParser.setDebug(true);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
  
          // your components may need access to solr, if there is some 'semantic analysis'
          // involved, eg. multi-step parsing of a query. I do it this way (the component
          // may be committed to solr in other tickets)
          // AqpRequestParams reqAttr = config.get(AqpAdsabsQueryConfigHandler.ConfigurationKeys.SOLR_REQUEST);
          // reqAttr.setQueryString(getString());
          // reqAttr.setRequest(req);
          // reqAttr.setLocalParams(localParams);
          // reqAttr.setParams(params);
  
      }
  
      @Override
      public Query parse() throws SyntaxError {
          try {
              return qParser.parse(getString(), null);
          } catch (QueryNodeException e) {
              throw new SyntaxError(e.getMessage(), e);
          } catch (SolrException e1) {
              throw new SyntaxError(e1.getMessage(), e1);
          }
      }
  
      public AqpQueryParser getParser() {
          return qParser;
      }
  }
  