test_class.file: oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParserTest.java
test_class.identifier: FilterQueryParserTest
test_case.body: @Test
      public void testCollapseJcrContentNodes() throws Exception {
          String query = "select [jcr:path], [jcr:score], * from [nt:hierarchy] as a where isdescendantnode(a, '/')";
          Filter filter = mock(Filter.class);
          OakSolrConfiguration configuration = new DefaultSolrConfiguration(){
              @Override
              public boolean collapseJcrContentNodes() {
                  return true;
              }
          };
          when(filter.getQueryStatement()).thenReturn(query);
          QueryIndex.IndexPlan plan = mock(QueryIndex.IndexPlan.class);
          SolrQuery solrQuery = FilterQueryParser.getQuery(filter, plan, configuration);
          assertNotNull(solrQuery);
          String[] filterQueries = solrQuery.getFilterQueries();
          assertTrue(Arrays.asList(filterQueries).contains("{!collapse field=" + configuration.getCollapsedPathField()
                  + " min=" + configuration.getPathDepthField() + " hint=top_fc nullPolicy=expand}"));
          assertEquals("*:*", solrQuery.get("q"));
      }
test_case.class_method_signature: FilterQueryParserTest.testCollapseJcrContentNodes()
test_case.full_signature: @Test public void testCollapseJcrContentNodes()
test_case.identifier: testCollapseJcrContentNodes
test_case.invocations: mock thenReturn when getQueryStatement mock getQuery assertNotNull getFilterQueries assertTrue contains asList getCollapsedPathField getPathDepthField assertEquals get
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testCollapseJcrContentNodes()
focal_class.declarator: log = LoggerFactory.getLogger(FilterQueryParser.class)
focal_class.modifier: private static final
focal_class.original_string: private static final Logger log = LoggerFactory.getLogger(FilterQueryParser.class);
focal_class.type: Logger
focal_class.var_name: log
focal_class.file: oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/FilterQueryParser.java
focal_class.identifier: FilterQueryParser
focal_class.class_method_signature: FilterQueryParser.getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_class.full_signature: static SolrQuery getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_class.identifier: getQuery
focal_class.modifiers: static
focal_class.parameters: (Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_class.return: SolrQuery
focal_class.signature: SolrQuery getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_class.class_method_signature: FilterQueryParser.parseFullTextExpression(FullTextExpression ft, final OakSolrConfiguration configuration)
focal_class.full_signature: private static String parseFullTextExpression(FullTextExpression ft, final OakSolrConfiguration configuration)
focal_class.identifier: parseFullTextExpression
focal_class.modifiers: private static
focal_class.parameters: (FullTextExpression ft, final OakSolrConfiguration configuration)
focal_class.return: String
focal_class.signature: String parseFullTextExpression(FullTextExpression ft, final OakSolrConfiguration configuration)
focal_class.class_method_signature: FilterQueryParser.isSupportedHttpRequest(String nativeQueryString)
focal_class.full_signature: private static boolean isSupportedHttpRequest(String nativeQueryString)
focal_class.identifier: isSupportedHttpRequest
focal_class.modifiers: private static
focal_class.parameters: (String nativeQueryString)
focal_class.return: boolean
focal_class.signature: boolean isSupportedHttpRequest(String nativeQueryString)
focal_class.class_method_signature: FilterQueryParser.setDefaults(SolrQuery solrQuery, OakSolrConfiguration configuration)
focal_class.full_signature: private static void setDefaults(SolrQuery solrQuery, OakSolrConfiguration configuration)
focal_class.identifier: setDefaults
focal_class.modifiers: private static
focal_class.parameters: (SolrQuery solrQuery, OakSolrConfiguration configuration)
focal_class.return: void
focal_class.signature: void setDefaults(SolrQuery solrQuery, OakSolrConfiguration configuration)
focal_class.class_method_signature: FilterQueryParser.createRangeQuery(String first, String last, boolean firstIncluding, boolean lastIncluding)
focal_class.full_signature: private static String createRangeQuery(String first, String last, boolean firstIncluding, boolean lastIncluding)
focal_class.identifier: createRangeQuery
focal_class.modifiers: private static
focal_class.parameters: (String first, String last, boolean firstIncluding, boolean lastIncluding)
focal_class.return: String
focal_class.signature: String createRangeQuery(String first, String last, boolean firstIncluding, boolean lastIncluding)
focal_class.class_method_signature: FilterQueryParser.purgePath(Filter filter, String pathPrefix)
focal_class.full_signature: private static String purgePath(Filter filter, String pathPrefix)
focal_class.identifier: purgePath
focal_class.modifiers: private static
focal_class.parameters: (Filter filter, String pathPrefix)
focal_class.return: String
focal_class.signature: String purgePath(Filter filter, String pathPrefix)
focal_method.body: static SolrQuery getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration) {
  
          SolrQuery solrQuery = new SolrQuery();
          setDefaults(solrQuery, configuration);
  
          StringBuilder queryBuilder = new StringBuilder();
  
          FullTextExpression ft = filter.getFullTextConstraint();
          if (ft != null) {
              queryBuilder.append(parseFullTextExpression(ft, configuration));
              queryBuilder.append(' ');
          } else if (filter.getFulltextConditions() != null) {
              Collection<String> fulltextConditions = filter.getFulltextConditions();
              for (String fulltextCondition : fulltextConditions) {
                  queryBuilder.append(fulltextCondition).append(" ");
              }
          }
  
          if (plan != null && plan.getSortOrder() != null) {
              List<QueryIndex.OrderEntry> sortOrder = plan.getSortOrder();
              for (QueryIndex.OrderEntry orderEntry : sortOrder) {
                  SolrQuery.ORDER order;
                  if (QueryIndex.OrderEntry.Order.ASCENDING.equals(orderEntry.getOrder())) {
                      order = SolrQuery.ORDER.asc;
                  } else {
                      order = SolrQuery.ORDER.desc;
                  }
                  String sortingField;
                  if (JcrConstants.JCR_PATH.equals(orderEntry.getPropertyName())) {
                      sortingField = partialEscape(configuration.getPathField()).toString();
                  } else if (JcrConstants.JCR_SCORE.equals(orderEntry.getPropertyName())) {
                      sortingField = "score";
                  } else {
                      if (orderEntry.getPropertyName().indexOf('/') >= 0) {
                          log.warn("cannot sort on relative properties, ignoring {} clause", orderEntry);
                          continue; // sorting by relative properties not supported until index time aggregation is supported
                      }
                      sortingField = partialEscape(getSortingField(orderEntry.getPropertyType().tag(), orderEntry.getPropertyName())).toString();
                  }
                  solrQuery.addOrUpdateSort(sortingField, order);
              }
          }
  
          Collection<Filter.PropertyRestriction> propertyRestrictions = filter.getPropertyRestrictions();
          if (propertyRestrictions != null && !propertyRestrictions.isEmpty()) {
              for (Filter.PropertyRestriction pr : propertyRestrictions) {
                  if (pr.isNullRestriction()) {
                      // can not use full "x is null"
                      continue;
                  }
                  // facets
                  if (QueryConstants.REP_FACET.equals(pr.propertyName)) {
                      solrQuery.setFacetMinCount(1);
                      solrQuery.setFacet(true);
                      String value = pr.first.getValue(Type.STRING);
                      solrQuery.addFacetField(value.substring(QueryConstants.REP_FACET.length() + 1, value.length() - 1) + "_facet");
                  }
  
                  // native query support
                  if (SolrQueryIndex.NATIVE_SOLR_QUERY.equals(pr.propertyName) || SolrQueryIndex.NATIVE_LUCENE_QUERY.equals(pr.propertyName)) {
                      String nativeQueryString = String.valueOf(pr.first.getValue(pr.first.getType()));
                      if (isSupportedHttpRequest(nativeQueryString)) {
                          // pass through the native HTTP Solr request
                          String requestHandlerString = nativeQueryString.substring(0, nativeQueryString.indexOf('?'));
                          if (!"select".equals(requestHandlerString)) {
                              if (requestHandlerString.charAt(0) != '/') {
                                  requestHandlerString = "/" + requestHandlerString;
                              }
                              solrQuery.setRequestHandler(requestHandlerString);
                          }
                          String parameterString = nativeQueryString.substring(nativeQueryString.indexOf('?') + 1);
                          for (String param : parameterString.split("&")) {
                              String[] kv = param.split("=");
                              if (kv.length != 2) {
                                  throw new RuntimeException("Unparsable native HTTP Solr query");
                              } else {
                                  // more like this
                                  if ("/mlt".equals(requestHandlerString)) {
                                      if ("stream.body".equals(kv[0])) {
                                          kv[0] = "q";
                                          String mltFlString = "mlt.fl=";
                                          int mltFlIndex = parameterString.indexOf(mltFlString);
                                          if (mltFlIndex > -1) {
                                              int beginIndex = mltFlIndex + mltFlString.length();
                                              int endIndex = parameterString.indexOf('&', beginIndex);
                                              String fields;
                                              if (endIndex > beginIndex) {
                                                  fields = parameterString.substring(beginIndex, endIndex);
                                              } else {
                                                  fields = parameterString.substring(beginIndex);
                                              }
                                              kv[1] = "_query_:\"{!dismax qf=" + fields + " q.op=OR}" + kv[1] + "\"";
                                          }
                                      }
                                      if ("mlt.fl".equals(kv[0]) && ":path".equals(kv[1])) {
                                          // rep:similar passes the path of the node to find similar documents for in the :path
                                          // but needs its indexed content to find similar documents
                                          kv[1] = configuration.getCatchAllField();
                                      }
                                  }
                                  if ("/spellcheck".equals(requestHandlerString)) {
                                      if ("term".equals(kv[0])) {
                                          kv[0] = "spellcheck.q";
                                      }
                                      solrQuery.setParam("spellcheck", true);
                                  }
                                  if ("/suggest".equals(requestHandlerString)) {
                                      if ("term".equals(kv[0])) {
                                          kv[0] = "suggest.q";
                                      }
                                      solrQuery.setParam("suggest", true);
                                  }
                                  solrQuery.setParam(kv[0], kv[1]);
                              }
                          }
                          return solrQuery;
                      } else {
                          queryBuilder.append(nativeQueryString);
                      }
                  } else {
                      if (SolrQueryIndex.isIgnoredProperty(pr, configuration)) {
                          continue;
                      }
  
                      String first = null;
                      if (pr.first != null) {
                          first = partialEscape(String.valueOf(pr.first.getValue(pr.first.getType()))).toString();
                      }
                      String last = null;
                      if (pr.last != null) {
                          last = partialEscape(String.valueOf(pr.last.getValue(pr.last.getType()))).toString();
                      }
  
                      String prField = configuration.getFieldForPropertyRestriction(pr);
                      CharSequence fieldName = partialEscape(prField != null ?
                              prField : pr.propertyName);
                      if ("jcr\\:path".equals(fieldName.toString())) {
                          queryBuilder.append(configuration.getPathField());
                          queryBuilder.append(':');
                          queryBuilder.append(first);
                      } else {
                          if (pr.first != null && pr.last != null && pr.first.equals(pr.last)) {
                              queryBuilder.append(fieldName).append(':');
                              queryBuilder.append(first);
                          } else if (pr.first == null && pr.last == null) {
                              if (!queryBuilder.toString().contains(fieldName + ":")) {
                                  queryBuilder.append(fieldName).append(':');
                                  queryBuilder.append('*');
                              }
                          } else if ((pr.first != null && pr.last == null) || (pr.last != null && pr.first == null) || (!pr.first.equals(pr.last))) {
                              // TODO : need to check if this works for all field types (most likely not!)
                              queryBuilder.append(fieldName).append(':');
                              queryBuilder.append(createRangeQuery(first, last, pr.firstIncluding, pr.lastIncluding));
                          } else if (pr.isLike) {
                              // TODO : the current parameter substitution is not expected to work well
                              queryBuilder.append(fieldName).append(':');
                              queryBuilder.append(partialEscape(String.valueOf(pr.first.getValue(pr.first.getType())).replace('%', '*').replace('_', '?')));
                          } else {
                              throw new RuntimeException("[unexpected!] not handled case");
                          }
                      }
                  }
                  queryBuilder.append(" ");
              }
          }
  
          if (configuration.useForPrimaryTypes()) {
              String[] pts = filter.getPrimaryTypes().toArray(new String[filter.getPrimaryTypes().size()]);
              StringBuilder ptQueryBuilder = new StringBuilder();
              for (int i = 0; i < pts.length; i++) {
                  String pt = pts[i];
                  if (i == 0) {
                      ptQueryBuilder.append("(");
                  }
                  if (i > 0 && i < pts.length) {
                      ptQueryBuilder.append("OR ");
                  }
                  ptQueryBuilder.append("jcr\\:primaryType").append(':').append(partialEscape(pt)).append(" ");
                  if (i == pts.length - 1) {
                      ptQueryBuilder.append(")");
                      ptQueryBuilder.append(' ');
                  }
              }
              solrQuery.addFilterQuery(ptQueryBuilder.toString());
          }
  
          if (filter.getQueryStatement() != null && filter.getQueryStatement().contains(QueryConstants.REP_EXCERPT)) {
              if (!solrQuery.getHighlight()) {
                  // enable highlighting
                  solrQuery.setHighlight(true);
                  // defaults
                  solrQuery.set("hl.fl", "*");
                  solrQuery.set("hl.encoder", "html");
                  solrQuery.set("hl.mergeContiguous", true);
                  solrQuery.setHighlightSimplePre("<strong>");
                  solrQuery.setHighlightSimplePost("</strong>");
              }
          }
  
          if (configuration.useForPathRestrictions()) {
              Filter.PathRestriction pathRestriction = filter.getPathRestriction();
              if (pathRestriction != null) {
                  String path = purgePath(filter, plan.getPathPrefix());
                  String fieldName = configuration.getFieldForPathRestriction(pathRestriction);
                  if (fieldName != null) {
                      if (pathRestriction.equals(Filter.PathRestriction.ALL_CHILDREN)) {
                          solrQuery.addFilterQuery(fieldName + ':' + path);
                      } else {
                          queryBuilder.append(fieldName);
                          queryBuilder.append(':');
                          queryBuilder.append(path);
                      }
                  }
              }
          }
  
          if (configuration.collapseJcrContentNodes()) {
              solrQuery.addFilterQuery("{!collapse field=" + configuration.getCollapsedPathField() + " min=" +
                      configuration.getPathDepthField() + " hint=top_fc nullPolicy=expand}");
          }
  
          if (queryBuilder.length() == 0) {
              queryBuilder.append("*:*");
          }
          String escapedQuery = queryBuilder.toString();
          solrQuery.setQuery(escapedQuery);
  
          if (log.isDebugEnabled()) {
              log.debug("JCR query {} has been converted to Solr query {}",
                      filter.getQueryStatement(), solrQuery.toString());
          }
  
          return solrQuery;
      }
focal_method.class_method_signature: FilterQueryParser.getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_method.full_signature: static SolrQuery getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_method.identifier: getQuery
focal_method.invocations: setDefaults getFullTextConstraint append parseFullTextExpression append getFulltextConditions getFulltextConditions append append getSortOrder getSortOrder equals getOrder equals getPropertyName toString partialEscape getPathField equals getPropertyName indexOf getPropertyName warn toString partialEscape getSortingField tag getPropertyType getPropertyName addOrUpdateSort getPropertyRestrictions isEmpty isNullRestriction equals setFacetMinCount setFacet getValue addFacetField substring length length equals equals valueOf getValue getType isSupportedHttpRequest substring indexOf equals charAt setRequestHandler substring indexOf split split equals equals indexOf length indexOf substring substring equals equals getCatchAllField equals equals setParam equals equals setParam setParam append isIgnoredProperty toString partialEscape valueOf getValue getType toString partialEscape valueOf getValue getType getFieldForPropertyRestriction partialEscape equals toString append getPathField append append equals append append append contains toString append append append equals append append append createRangeQuery append append append partialEscape replace replace valueOf getValue getType append useForPrimaryTypes toArray getPrimaryTypes size getPrimaryTypes append append append append append append partialEscape append append addFilterQuery toString getQueryStatement contains getQueryStatement getHighlight setHighlight set set set setHighlightSimplePre setHighlightSimplePost useForPathRestrictions getPathRestriction purgePath getPathPrefix getFieldForPathRestriction equals addFilterQuery append append append collapseJcrContentNodes addFilterQuery getCollapsedPathField getPathDepthField length append toString setQuery isDebugEnabled debug getQueryStatement toString
focal_method.modifiers: static
focal_method.parameters: (Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)
focal_method.return: SolrQuery
focal_method.signature: SolrQuery getQuery(Filter filter, QueryIndex.IndexPlan plan, OakSolrConfiguration configuration)