You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by al...@apache.org on 2013/05/14 22:30:52 UTC
svn commit: r1482567 - in /jackrabbit/oak/trunk:
oak-core/src/test/java/org/apache/jackrabbit/oak/query/ oak-lucene/
oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/
oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/ind...
Author: alexparvulescu
Date: Tue May 14 20:30:51 2013
New Revision: 1482567
URL: http://svn.apache.org/r1482567
Log:
OAK-819 Lucene fulltext on node not working properly - WIP
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
jackrabbit/oak/trunk/oak-lucene/pom.xml
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java Tue May 14 20:30:51 2013
@@ -205,12 +205,16 @@ public abstract class AbstractQueryTest
}
protected List<String> executeQuery(String query, String language) {
+ return executeQuery(query, language, false);
+ }
+
+ protected List<String> executeQuery(String query, String language, boolean pathsOnly) {
long time = System.currentTimeMillis();
List<String> lines = new ArrayList<String>();
try {
Result result = executeQuery(query, language, null);
for (ResultRow row : result.getRows()) {
- lines.add(readRow(row));
+ lines.add(readRow(row, pathsOnly));
}
if (!query.contains("order by")) {
Collections.sort(lines);
@@ -228,8 +232,14 @@ public abstract class AbstractQueryTest
}
protected List<String> assertQuery(String sql, List<String> expected) {
- List<String> paths = executeQuery(sql, SQL2);
- assertEquals(expected.size(), paths.size());
+ return assertQuery(sql, SQL2, expected);
+ }
+
+ protected List<String> assertQuery(String sql, String language,
+ List<String> expected) {
+ List<String> paths = executeQuery(sql, language, true);
+ assertEquals("Result set size is different", expected.size(),
+ paths.size());
for (String p : expected) {
assertTrue(paths.contains(p));
}
@@ -240,7 +250,10 @@ public abstract class AbstractQueryTest
((QueryEngineImpl) qe).setTravesalFallback(traversal);
}
- protected static String readRow(ResultRow row) {
+ protected static String readRow(ResultRow row, boolean pathOnly) {
+ if (pathOnly) {
+ return row.getValue(Query.JCR_PATH).getValue(Type.STRING);
+ }
StringBuilder buff = new StringBuilder();
PropertyValue[] values = row.getValues();
for (int i = 0; i < values.length; i++) {
Modified: jackrabbit/oak/trunk/oak-lucene/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/pom.xml?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-lucene/pom.xml Tue May 14 20:30:51 2013
@@ -39,7 +39,6 @@
org.apache.jackrabbit.core.query.FulltextQueryTest <!-- OAK-819 -->
org.apache.jackrabbit.core.query.JoinTest#testJoinWithOR4 <!-- OAK-819 -->
org.apache.jackrabbit.core.query.JoinTest#testJoinWithOR5 <!-- OAK-819 -->
- org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexQueryTest <!-- OAK-819 -->
</known.issues>
</properties>
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldFactory.java Tue May 14 20:30:51 2013
@@ -18,8 +18,10 @@ package org.apache.jackrabbit.oak.plugin
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
+import org.apache.lucene.document.TextField;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.PATH;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.FULLTEXT;
import static org.apache.lucene.document.Field.Store.NO;
import static org.apache.lucene.document.Field.Store.YES;
@@ -44,4 +46,9 @@ public final class FieldFactory {
// return new TextField(name, value, NO);
return new StringField(name, value, NO);
}
+
+ public static Field newFulltextField(String value) {
+ return new TextField(FULLTEXT, value, NO);
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java Tue May 14 20:30:51 2013
@@ -38,6 +38,11 @@ public final class FieldNames {
public static final String PATH = ":path";
/**
+ * Name of the field that contains the fulltext index.
+ */
+ public static final String FULLTEXT = ":fulltext";
+
+ /**
* Used to select only the PATH field from the lucene documents
*/
public static final Set<String> PATH_SELECTOR = new HashSet<String>(
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Tue May 14 20:30:51 2013
@@ -25,8 +25,10 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.PATH_SELECTOR;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_DATA_CHILD_NAME;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newFulltextTerm;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm;
import static org.apache.jackrabbit.oak.query.Query.JCR_PATH;
+import static org.apache.lucene.search.BooleanClause.Occur.MUST;
import static org.apache.lucene.search.BooleanClause.Occur.SHOULD;
import java.io.IOException;
@@ -50,10 +52,10 @@ import org.apache.lucene.index.Directory
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
@@ -69,17 +71,20 @@ import org.slf4j.LoggerFactory;
* Provides a QueryIndex that does lookups against a Lucene-based index
*
* <p>
- * To define a lucene index on a subtree you have to add an <code>oak:index<code> node.
+ * To define a lucene index on a subtree you have to add an
+ * <code>oak:index<code> node.
*
* Under it follows the index definition node that:
* <ul>
* <li>must be of type <code>oak:queryIndexDefinition</code></li>
- * <li>must have the <code>type</code> property set to <b><code>lucene</code></b></li>
+ * <li>must have the <code>type</code> property set to <b><code>lucene</code>
+ * </b></li>
* </ul>
* </p>
*
* <p>
- * Note: <code>reindex<code> is a property that when set to <code>true</code>, triggers a full content reindex.
+ * Note: <code>reindex<code> is a property that when set to <code>true</code>,
+ * triggers a full content reindex.
* </p>
*
* <pre>
@@ -191,7 +196,8 @@ public class LuceneIndex implements Full
}
}
- private static Query getQuery(Filter filter, NodeState root, IndexReader reader) {
+ private static Query getQuery(Filter filter, NodeState root,
+ IndexReader reader) {
List<Query> qs = new ArrayList<Query>();
if (!filter.matchesAllTypes()) {
@@ -293,9 +299,10 @@ public class LuceneIndex implements Full
qs.add(TermRangeQuery.newStringRange(name, first, last,
pr.firstIncluding, pr.lastIncluding));
-
}
+ addFulltextConstraints(qs, filter);
+
if (qs.size() == 0) {
return new MatchAllDocsQuery();
}
@@ -304,7 +311,7 @@ public class LuceneIndex implements Full
}
BooleanQuery bq = new BooleanQuery();
for (Query q : qs) {
- bq.add(q, Occur.MUST);
+ bq.add(q, MUST);
}
return bq;
}
@@ -321,7 +328,7 @@ public class LuceneIndex implements Full
BooleanQuery bq = new BooleanQuery();
Collection<String> fields = MultiFields.getIndexedFields(reader);
for (String f : fields) {
- bq.add(new TermQuery(new Term(f, uuid)), Occur.SHOULD);
+ bq.add(new TermQuery(new Term(f, uuid)), SHOULD);
}
qs.add(bq);
}
@@ -337,4 +344,94 @@ public class LuceneIndex implements Full
qs.add(bq);
}
+ private static void addFulltextConstraints(List<Query> qs, Filter filter) {
+ if (filter.getFulltextConditions() == null
+ || filter.getFulltextConditions().isEmpty()) {
+ return;
+ }
+ List<String> tokens = tokenize(filter.getFulltextConditions()
+ .iterator().next().toLowerCase());
+ if (tokens.size() == 1) {
+ String token = tokens.get(0);
+ Query q = null;
+ if (token.contains(" ")) {
+ // q = new WildcardQuery(newFulltextTerm(token));
+ // PhraseQuery pq = new PhraseQuery();
+ // pq.add(newFulltextTerm(token));
+ // q = pq;
+ } else {
+ q = new WildcardQuery(newFulltextTerm(token
+ + WildcardQuery.WILDCARD_STRING));
+ }
+ if (q != null) {
+ qs.add(q);
+ }
+ return;
+ }
+
+ BooleanQuery q = new BooleanQuery();
+ for (String token : tokens) {
+ q.add(new TermQuery(newFulltextTerm(token)), MUST);
+ // if (token.contains(" ")) {
+ // // q = new WildcardQuery(newFulltextTerm(token));
+ // // PhraseQuery pq = new PhraseQuery();
+ // // pq.add(newFulltextTerm(token));
+ // // q = pq;
+ // } else {
+ // q = new WildcardQuery(newFulltextTerm(token
+ // + WildcardQuery.WILDCARD_STRING));
+ // }
+ }
+ qs.add(q);
+ }
+
+ /**
+ *
+ * inspired from lucene's WildcardQuery#toAutomaton
+ */
+ private static List<String> tokenize(String in) {
+ List<String> out = new ArrayList<String>();
+ StringBuilder token = new StringBuilder();
+ boolean quote = false;
+ for (int i = 0; i < in.length();) {
+ final int c = in.codePointAt(i);
+ int length = Character.charCount(c);
+ switch (c) {
+ case ' ':
+ if (quote) {
+ token.append(' ');
+ } else if (token.length() > 0) {
+ out.add(token.toString());
+ token = new StringBuilder();
+ }
+ break;
+ case '"':
+ if (quote) {
+ quote = false;
+ if (token.length() > 0) {
+ out.add(token.toString());
+ token = new StringBuilder();
+ }
+ } else {
+ quote = true;
+ }
+ break;
+ case '\\':
+ if (i + length < in.length()) {
+ final int nextChar = in.codePointAt(i + length);
+ length += Character.charCount(nextChar);
+ token.append(new String(Character.toChars(nextChar)));
+ break;
+ }
+ default:
+ token.append(new String(Character.toChars(c)));
+ }
+ i += length;
+ }
+ if (token.length() > 0) {
+ out.add(token.toString());
+ }
+ return out;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java Tue May 14 20:30:51 2013
@@ -26,7 +26,7 @@ public interface LuceneIndexConstants {
String INDEX_DATA_CHILD_NAME = ":data";
- Version VERSION = Version.LUCENE_41;
+ Version VERSION = Version.LUCENE_42;
Analyzer ANALYZER = new StandardAnalyzer(VERSION);
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexUpdate.java Tue May 14 20:30:51 2013
@@ -20,6 +20,11 @@ import static com.google.common.base.Pre
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getString;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPathField;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPropertyField;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newFulltextField;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.ANALYZER;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_TYPES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_DATA_CHILD_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm;
import java.io.Closeable;
@@ -49,7 +54,7 @@ import org.apache.tika.sax.WriteOutConte
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class LuceneIndexUpdate implements Closeable, LuceneIndexConstants {
+class LuceneIndexUpdate implements Closeable {
private static final Logger log = LoggerFactory
.getLogger(LuceneIndexUpdate.class);
@@ -187,14 +192,15 @@ class LuceneIndexUpdate implements Close
Document document = new Document();
document.add(newPathField(path));
for (PropertyState property : state.getProperties()) {
- if (propertyTypes.isEmpty()
+ String pname = property.getName();
+ if (isVisible(pname) && propertyTypes.isEmpty()
|| propertyTypes.contains(property.getType().tag())) {
if (Type.BINARY.tag() == property.getType().tag()) {
addBinaryValue(document, property, state);
} else {
- String pname = property.getName();
for (String v : property.getValue(Type.STRINGS)) {
document.add(newPropertyField(pname, v));
+ document.add(newFulltextField(v));
}
}
}
@@ -202,6 +208,10 @@ class LuceneIndexUpdate implements Close
return document;
}
+ private static boolean isVisible(String name) {
+ return name.charAt(0) != ':';
+ }
+
private void addBinaryValue(Document doc, PropertyState property,
NodeState state) {
String type = getString(state, JcrConstants.JCR_MIMETYPE);
@@ -216,9 +226,8 @@ class LuceneIndexUpdate implements Close
metadata.set(Metadata.CONTENT_ENCODING, encoding);
}
- String name = property.getName();
for (Blob v : property.getValue(Type.BINARIES)) {
- doc.add(newPropertyField(name, parseStringValue(v, metadata)));
+ doc.add(newFulltextField(parseStringValue(v, metadata)));
}
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/TermFactory.java Tue May 14 20:30:51 2013
@@ -45,4 +45,8 @@ public final class TermFactory {
return new Term(FieldNames.PATH, path);
}
+ public static Term newFulltextTerm(String ft) {
+ return new Term(FieldNames.FULLTEXT, ft);
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java Tue May 14 20:30:51 2013
@@ -31,6 +31,10 @@ public class LuceneInitializerHelper imp
private final Set<String> propertyTypes;
+ public LuceneInitializerHelper(String name) {
+ this(name, LuceneIndexHelper.JR_PROPERTY_INCLUDES);
+ }
+
public LuceneInitializerHelper(String name, Set<String> propertyTypes) {
this.name = name;
this.propertyTypes = propertyTypes;
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java?rev=1482567&r1=1482566&r2=1482567&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java Tue May 14 20:30:51 2013
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertFal
import static org.junit.Assert.assertTrue;
import java.util.Iterator;
-import java.util.List;
import org.apache.jackrabbit.oak.Oak;
import org.apache.jackrabbit.oak.api.ContentRepository;
@@ -32,6 +31,8 @@ import org.apache.jackrabbit.oak.query.J
import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
import org.junit.Test;
+import com.google.common.collect.ImmutableList;
+
/**
* Tests the query engine using the default index implementation: the
* {@link LuceneIndexProvider}
@@ -113,19 +114,29 @@ public class LuceneIndexQueryTest extend
assertEquals("/, /parents", result.next());
assertFalse(result.hasNext());
}
-
+
@Test
public void contains() throws Exception {
+ String h = "Hello" + System.currentTimeMillis();
+ String w = "World" + System.currentTimeMillis();
+
+ JsopUtil.apply(root, "/ + \"test\": { \"a\": { \"name\": [\"" + h
+ + "\", \"" + w + "\" ] }, \"b\": { \"name\" : \"" + h + "\" }}");
+ root.commit();
+
+ // query 'hello'
StringBuffer stmt = new StringBuffer();
- stmt.append("/jcr:root").append("/test").append("/*");
- stmt.append("[jcr:contains(., '").append("token");
+ stmt.append("/jcr:root//*[jcr:contains(., '").append(h);
+ stmt.append("')]");
+ assertQuery(stmt.toString(), "xpath",
+ ImmutableList.of("/test/a", "/test/b"));
+
+ // query 'world'
+ stmt = new StringBuffer();
+ stmt.append("/jcr:root//*[jcr:contains(., '").append(w);
stmt.append("')]");
- System.out.println(stmt.toString());
+ assertQuery(stmt.toString(), "xpath", ImmutableList.of("/test/a"));
- List<String> result = executeQuery(stmt.toString(), "xpath");
- System.out.println(result);
- for (String h : result) {
- System.out.println(h);
- }
}
+
}