Index: src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java (revision 1643064) +++ src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java (working copy) @@ -22,6 +22,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.apache.jackrabbit.oak.query.fulltext.FullTextAnd; +import org.apache.jackrabbit.oak.query.fulltext.FullTextContains; import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression; import org.apache.jackrabbit.oak.query.fulltext.FullTextOr; import org.apache.jackrabbit.oak.query.fulltext.FullTextTerm; @@ -112,6 +113,11 @@ composite.set(false); ft.accept(new FullTextVisitor() { + + @Override + public boolean visit(FullTextContains contains) { + return contains.getBase().accept(this); + } @Override public boolean visit(FullTextTerm term) { @@ -163,6 +169,11 @@ } final AtomicReference result = new AtomicReference(); constraint.accept(new FullTextVisitor() { + + @Override + public boolean visit(FullTextContains contains) { + return contains.getBase().accept(this); + } @Override public boolean visit(FullTextTerm term) { @@ -216,6 +227,11 @@ final String path) { constraint.accept(new FullTextVisitor() { + + @Override + public boolean visit(FullTextContains contains) { + return contains.getBase().accept(this); + } @Override public boolean visit(FullTextTerm term) { Index: src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java (revision 1643064) +++ src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java (working copy) @@ -31,6 +31,7 @@ import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.query.fulltext.FullTextContains; import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression; import org.apache.jackrabbit.oak.query.fulltext.FullTextParser; import org.apache.jackrabbit.oak.query.index.FilterImpl; @@ -139,7 +140,9 @@ p = PathUtils.concat(relativePath, p); } String p2 = normalizePropertyName(p); - return FullTextParser.parse(p2, v.getValue(Type.STRING)); + String rawText = v.getValue(Type.STRING); + FullTextExpression e = FullTextParser.parse(p2, rawText); + return new FullTextContains(p2, rawText, e); } catch (ParseException e) { throw new IllegalArgumentException("Invalid expression: " + fullTextSearchExpression, e); } Index: src/main/java/org/apache/jackrabbit/oak/query/fulltext/FullTextContains.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/fulltext/FullTextContains.java (revision 0) +++ src/main/java/org/apache/jackrabbit/oak/query/fulltext/FullTextContains.java (working copy) @@ -0,0 +1,78 @@ +/* + * 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.jackrabbit.oak.query.fulltext; + +/** + * A group of full-text expressions that reflects a "contains(...)" expression, + * and allows to access the original (unparsed) full text term. + */ +public class FullTextContains extends FullTextExpression { + + private final String propertyName; + private final String rawText; + private final FullTextExpression base; + + public FullTextContains(String propertyName, String rawText, FullTextExpression base) { + this.propertyName = propertyName; + this.rawText = rawText; + this.base = base; + } + + @Override + public int getPrecedence() { + return base.getPrecedence(); + } + + @Override + public boolean evaluate(String value) { + return base.evaluate(value); + } + + @Override + FullTextExpression simplify() { + FullTextExpression s = base.simplify(); + if (s == base) { + return this; + } + return new FullTextContains(propertyName, rawText, s); + } + + @Override + public String toString() { + return base.toString(); + } + + @Override + public boolean accept(FullTextVisitor v) { + return v.visit(this); + } + + public FullTextExpression getBase() { + return base; + } + + public String getPropertyName() { + return propertyName; + } + + public String getRawText() { + return rawText; + } + +} Index: src/main/java/org/apache/jackrabbit/oak/query/fulltext/FullTextVisitor.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/fulltext/FullTextVisitor.java (revision 1643064) +++ src/main/java/org/apache/jackrabbit/oak/query/fulltext/FullTextVisitor.java (working copy) @@ -24,6 +24,14 @@ * likely visit(FullTextTerm). */ public interface FullTextVisitor { + + /** + * Visit an "contains" expression. + * + * @param contains the "contains" expression + * @return true if visiting should continue + */ + boolean visit(FullTextContains contains); /** * Visit an "and" expression. @@ -55,6 +63,11 @@ public abstract static class FullTextVisitorBase implements FullTextVisitor { @Override + public boolean visit(FullTextContains contains) { + return contains.accept(this); + } + + @Override public boolean visit(FullTextAnd and) { for (FullTextExpression e : and.list) { if (!e.accept(this)) { @@ -73,7 +86,7 @@ } return true; } - + } }