/* * ModeShape (http://www.modeshape.org) * * Licensed 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.modeshape.jcr.index.lucene.query; import static org.modeshape.jcr.value.ValueComparators.PATH_COMPARATOR; import java.util.function.BiPredicate; import java.util.function.Function; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.Query; import org.apache.lucene.search.Weight; import org.modeshape.common.annotation.Immutable; import org.modeshape.jcr.value.Path; import org.modeshape.jcr.value.ValueFactories; import org.modeshape.jcr.value.ValueFactory; /** * A Lucene {@link Query} implementation that is used to apply a {@link javax.jcr.query.qom.Comparison} constraint against the * Path of nodes. This query implementation works by using the weight and {@link Weight#scorer(LeafReaderContext)} * scorer} of the wrapped query to score (and return) only those documents that correspond to nodes with Paths that satisfy the * constraint. */ @Immutable public class ComparePathQuery extends CompareQuery<Path> { private final ValueFactory<Path> pathFactory; /** * Construct a {@link Query} implementation that scores nodes according to the supplied comparator. * * @param fieldName the name of the document field containing the path value; may not be null * @param constraintPath the constraint path; may not be null * @param pathFactory the value factory that can be used during the scoring; may not be null * @param evaluator the {@link BiPredicate} implementation that returns whether the node path satisfies the * constraint; may not be null * @param caseOperation the operation that should be performed on the indexed values before the constraint value is being * evaluated */ protected ComparePathQuery(String fieldName, Path constraintPath, ValueFactory<Path> pathFactory, BiPredicate<Path, Path> evaluator, Function<String, String> caseOperation) { super(fieldName, constraintPath, evaluator, caseOperation); this.pathFactory = pathFactory; } @Override protected Path convertValue(String casedValue) { return pathFactory.create(casedValue); } @Override public Query clone() { return new ComparePathQuery(field(), constraintValue, pathFactory, evaluator, caseOperation); } /** * Construct a {@link Query} implementation that scores documents such that the node represented by the document has a path * that is greater than the supplied constraint path. * * @param constraintPath the constraint path; may not be null * @param fieldName the name of the document field containing the path value; may not be null * @param factories the value factories that can be used during the scoring; may not be null * @param caseOperation the operation that should be performed on the indexed values before the constraint value is being * evaluated; may be null which indicates that no case conversion should be done * @return the path query; never null */ public static ComparePathQuery createQueryForNodesWithPathGreaterThan( Path constraintPath, String fieldName, ValueFactories factories, Function<String, String> caseOperation) { return new ComparePathQuery(fieldName, constraintPath, factories.getPathFactory(), (path1, path2) -> PATH_COMPARATOR.compare(path1, path2) > 0, caseOperation); } /** * Construct a {@link Query} implementation that scores documents such that the node represented by the document has a path * that is greater than or equal to the supplied constraint path. * * @param constraintPath the constraint path; may not be null * @param fieldName the name of the document field containing the path value; may not be null * @param factories the value factories that can be used during the scoring; may not be null * @param caseOperation the operation that should be performed on the indexed values before the constraint value is being * evaluated; may be null which indicates that no case conversion should be done * @return the path query; never null */ public static ComparePathQuery createQueryForNodesWithPathGreaterThanOrEqualTo( Path constraintPath, String fieldName, ValueFactories factories, Function<String, String> caseOperation ) { return new ComparePathQuery(fieldName, constraintPath, factories.getPathFactory(), (path1, path2) -> PATH_COMPARATOR.compare(path1, path2) >= 0, caseOperation); } /** * Construct a {@link Query} implementation that scores documents such that the node represented by the document has a path * that is less than the supplied constraint path. * * @param constraintPath the constraint path; may not be null * @param fieldName the name of the document field containing the path value; may not be null * @param factories the value factories that can be used during the scoring; may not be null * @param caseOperation the operation that should be performed on the indexed values before the constraint value is being * evaluated; may be null which indicates that no case conversion should be done * @return the path query; never null */ public static ComparePathQuery createQueryForNodesWithPathLessThan( Path constraintPath, String fieldName, ValueFactories factories, Function<String, String> caseOperation ) { return new ComparePathQuery(fieldName, constraintPath, factories.getPathFactory(), (path1, path2) -> PATH_COMPARATOR.compare(path1, path2) < 0, caseOperation); } /** * Construct a {@link Query} implementation that scores documents such that the node represented by the document has a path * that is less than or equal to the supplied constraint path. * * @param constraintPath the constraint path; may not be null * @param fieldName the name of the document field containing the path value; may not be null * @param factories the value factories that can be used during the scoring; may not be null * @param caseOperation the operation that should be performed on the indexed values before the constraint value is being * evaluated; may be null which indicates that no case conversion should be done * @return the path query; never null */ public static ComparePathQuery createQueryForNodesWithPathLessThanOrEqualTo( Path constraintPath, String fieldName, ValueFactories factories, Function<String, String> caseOperation ) { return new ComparePathQuery(fieldName, constraintPath, factories.getPathFactory(), (path1, path2) -> PATH_COMPARATOR.compare(path1, path2) <= 0, caseOperation); } }