All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.analytics.request.AnalyticsContentHandler Maven / Gradle / Ivy

There is a newer version: 9.9.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.solr.analytics.request;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortDirection;
import org.apache.solr.analytics.request.FieldFacetRequest.FacetSortSpecification;
import org.apache.solr.common.params.FacetParams.FacetRangeInclude;
import org.apache.solr.common.params.FacetParams.FacetRangeOther;
import org.apache.solr.schema.IndexSchema;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

/**
 * Handles the parsing of the AnalysisRequestEnvelope elements if passed in through XML.
 */
public class AnalyticsContentHandler implements ContentHandler {
  // XML Element/Attribute Name Constants
  public final String ANALYTICS_REQUEST_ENVELOPE="analyticsRequestEnvelope";
  
  public final String ANALYTICS_REQUEST="analyticsRequest";
  public final String NAME="name";
  
  public final String STATISTIC="statistic";
  public final String EXPRESSION="expression";
  
  public final String FIELD_FACET="fieldFacet";
  public final String FIELD="field";
  public final String SHOW_MISSING="showMissing";
  public final String LIMIT="limit";
  public final String MIN_COUNT="minCount";
  
  public final String SORT_SPECIFICATION="sortSpecification";
  public final String STAT_NAME="statName";
  public final String DIRECTION="direction";
  
  public final String RANGE_FACET="rangeFacet";
  public final String START="start";
  public final String END="end";
  public final String GAP="gap";
  public final String INCLUDE_BOUNDARY="includeBoundary";
  public final String OTHER_RANGE="otherRange";
  public final String HARD_END="hardend";
  
  public final String QUERY_FACET="queryFacet";
  public final String QUERY="query";
  
  // Default Values
  public static final int DEFAULT_FACET_LIMIT = -1;
  public static final boolean DEFAULT_FACET_HARDEND = false;
  public static final int DEFAULT_FACET_MINCOUNT = 0;
  public static final boolean DEFAULT_FACET_FIELD_SHOW_MISSING = false;

  boolean inEnvelope = false;
  boolean inRequest = false;
  boolean inStatistic = false;
  boolean inFieldFacet = false;
  boolean inSortSpecification = false;
  boolean inQueryFacet = false;
  boolean inRangeFacet = false;
  
  private final IndexSchema schema;
  
  // Objects to use while building the Analytics Requests
  
  String currentElementText;
  
  List requests;
  
  AnalyticsRequest analyticsRequest;
  List expressionList;
  List fieldFacetList;
  List rangeFacetList;
  List queryFacetList;
  
  ExpressionRequest expression;
  
  FieldFacetRequest fieldFacet;
  int limit;
  int minCount;
  boolean showMissing;
  FacetSortSpecification sortSpecification;
  
  RangeFacetRequest rangeFacet;
  boolean hardend;
  List gaps;
  EnumSet includeBoundaries;
  EnumSet otherRanges;
  
  String queryName;
  List queries;
  
  public AnalyticsContentHandler(IndexSchema schema) {
    this.schema = schema;
  }

  @Override
  public void setDocumentLocator(Locator locator) { }

  @Override
  public void startDocument() throws SAXException { }

  @Override
  public void endDocument() throws SAXException { }

  @Override
  public void startPrefixMapping(String prefix, String uri) throws SAXException { }

  @Override
  public void endPrefixMapping(String prefix) throws SAXException { }

  @Override
  public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
    currentElementText = "";
    if (inEnvelope) {
      if (inRequest) {
        if (localName.equals(STATISTIC)) {
          // Start a Statistic Request
          inStatistic = true;
        } else if (inFieldFacet) {
          if (localName.equals(SORT_SPECIFICATION)) {
            // Start a Sort Specification
            inSortSpecification = true;
            sortSpecification = new FacetSortSpecification();
          }
        } else if (localName.equals(FIELD_FACET)) {
          // Start a Field Facet Request
          // Get attributes (limit, minCount, showMissing)
          String att = atts.getValue(uri,LIMIT);
          if (att!=null) {
            limit = Integer.parseInt(att);
          } else {
            limit = DEFAULT_FACET_LIMIT;
          }
          att = atts.getValue(uri,MIN_COUNT);
          if (att!=null) {
            minCount = Integer.parseInt(att);
          } else {
            minCount = DEFAULT_FACET_MINCOUNT;
          }
          att = atts.getValue(uri,SHOW_MISSING);
          if (att!=null) {
            showMissing = Boolean.parseBoolean(att);
          } else {
            showMissing = DEFAULT_FACET_FIELD_SHOW_MISSING;
          }
          
          inFieldFacet = true;
        } else if (localName.equals(RANGE_FACET)) {
          // Start a Range Facet Request
          // Get attributes (hardEnd)
          String att = atts.getValue(uri,HARD_END);
          if (att!=null) {
            hardend = Boolean.parseBoolean(att);
          } else {
            hardend = false;
          }
          
          // Initiate Range Facet classes
          gaps = new ArrayList<>();
          includeBoundaries = EnumSet.noneOf(FacetRangeInclude.class);
          otherRanges = EnumSet.noneOf(FacetRangeOther.class);
          inRangeFacet = true;
        } else if (localName.equals(QUERY_FACET)) {
          // Start a Query Facet Request
          queries = new ArrayList<>();
          inQueryFacet = true;
        }
      } else if (localName.equals(ANALYTICS_REQUEST)){
        // Start an Analytics Request
        
        // Renew each list.
        fieldFacetList = new ArrayList<>();
        rangeFacetList = new ArrayList<>();
        queryFacetList = new ArrayList<>();
        expressionList = new ArrayList<>();
        inRequest = true;
      }
    } else if (localName.equals(ANALYTICS_REQUEST_ENVELOPE)){
      //Begin the parsing of the Analytics Requests
      requests = new ArrayList<>();
      inEnvelope = true;
    }
  }

  @Override
  public void endElement(String uri, String localName, String qName) throws SAXException {
    if (inEnvelope) {
      if (inRequest) {
        if (inStatistic) {
          if (localName.equals(EXPRESSION)) {
            expression = new ExpressionRequest(currentElementText,currentElementText);
          } else if (localName.equals(NAME)) {
            expression.setName(currentElementText);
          } else if (localName.equals(STATISTIC)) {
            // Finished Parsing the Statistic Request
            expressionList.add(expression);
            inStatistic = false;
          } 
        } else if (inFieldFacet) {
          if (inSortSpecification) {
            if (localName.equals(STAT_NAME)) {
              sortSpecification.setStatistic(currentElementText);
            } else if (localName.equals(DIRECTION)) {
              sortSpecification.setDirection(FacetSortDirection.fromExternal(currentElementText));
            } else if (localName.equals(SORT_SPECIFICATION)) {
              // Finished Parsing the Sort Specification
              fieldFacet.setSort(sortSpecification);
              inSortSpecification = false;
            } 
          } else if (localName.equals(FIELD)) {
            fieldFacet = new FieldFacetRequest(schema.getField(currentElementText));
          } else if (localName.equals(FIELD_FACET)) {
            // Finished Parsing the Field Facet Request
            fieldFacet.setLimit(limit);
            fieldFacet.showMissing(showMissing);
            fieldFacetList.add(fieldFacet);
            inFieldFacet = false;
          } 
        } else if (inRangeFacet) {
          if (localName.equals(FIELD)) {
            rangeFacet = new RangeFacetRequest(schema.getField(currentElementText), "", "", new String[1]);
          } else if (localName.equals(START)) {
            rangeFacet.setStart(currentElementText);
          } else if (localName.equals(END)) {
            rangeFacet.setEnd(currentElementText);
          } else if (localName.equals(GAP)) {
            gaps.add(currentElementText);
          } else if (localName.equals(INCLUDE_BOUNDARY)) {
            includeBoundaries.add(FacetRangeInclude.get(currentElementText));
          } else if (localName.equals(OTHER_RANGE)) {
            otherRanges.add(FacetRangeOther.get(currentElementText));
          } else if (localName.equals(RANGE_FACET)) {
            // Finished Parsing the Range Facet Request
            rangeFacet.setHardEnd(hardend);
            rangeFacet.setGaps(gaps.toArray(new String[1]));
            rangeFacet.setInclude(includeBoundaries);
            rangeFacet.setOthers(otherRanges);
            inRangeFacet = false;
            rangeFacetList.add(rangeFacet);
          } 
        } else if (inQueryFacet) {
          if (localName.equals(NAME)) {
            queryName = currentElementText;
          } else if (localName.equals(QUERY)) {
            queries.add(currentElementText);
          } else if (localName.equals(QUERY_FACET)) {
            // Finished Parsing the Query Facet Request
            QueryFacetRequest temp = new QueryFacetRequest(queryName);
            temp.setQueries(queries);
            queryFacetList.add(temp);
            inQueryFacet = false;
          }
        } else if (localName.equals(NAME)) {
          analyticsRequest = new AnalyticsRequest(currentElementText);
        } else if (localName.equals(ANALYTICS_REQUEST)){
          // Finished Parsing the Analytics Request
          analyticsRequest.setExpressions(expressionList);
          analyticsRequest.setFieldFacets(fieldFacetList);
          analyticsRequest.setRangeFacets(rangeFacetList);
          analyticsRequest.setQueryFacets(queryFacetList);
          requests.add(analyticsRequest);
          inRequest = false;
        }
      } else if (localName.equals(ANALYTICS_REQUEST_ENVELOPE)){
        // Finished Parsing
        inEnvelope = false;
      }
    }
  }

  @Override
  public void characters(char[] ch, int start, int length) throws SAXException {
    currentElementText += new String(ch,start,length);
  }

  @Override
  public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { }

  @Override
  public void processingInstruction(String target, String data) throws SAXException { }

  @Override
  public void skippedEntity(String name) throws SAXException { }
  
  /**
   * Returns the list of Analytics Requests built during parsing.
   * 
   * @return List of {@link AnalyticsRequest} objects specified by the given XML file
   */
  public List getAnalyticsRequests() {
    return requests;
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy