[exo-jcr-commits] exo-jcr SVN: r348 - in jcr/trunk/component/core: src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell and 1 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Thu Oct 22 05:45:53 EDT 2009
Author: sergiykarpenko
Date: 2009-10-22 05:45:53 -0400 (Thu, 22 Oct 2009)
New Revision: 348
Modified:
jcr/trunk/component/core/known-issues.txt
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java
jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java
Log:
EXOJCR-192: SpellChecker accuracy increased to 0.55f. Fails fixed
Modified: jcr/trunk/component/core/known-issues.txt
===================================================================
--- jcr/trunk/component/core/known-issues.txt 2009-10-21 16:18:15 UTC (rev 347)
+++ jcr/trunk/component/core/known-issues.txt 2009-10-22 09:45:53 UTC (rev 348)
@@ -1,6 +1,3 @@
// https://jira.jboss.org/jira/browse/EXOJCR-193
org.exoplatform.services.jcr.impl.core.query.TestSimilarity.java
-
-//https://jira.jboss.org/jira/browse/EXOJCR-192
-org.exoplatform.services.jcr.api.core.query.lucene.spell.SpellCheckerTest.java
\ No newline at end of file
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java 2009-10-21 16:18:15 UTC (rev 347)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/spell/LuceneSpellChecker.java 2009-10-22 09:45:53 UTC (rev 348)
@@ -47,390 +47,442 @@
* <code>LuceneSpellChecker</code> implements a spell checker based on the terms
* present in a lucene index.
*/
-public class LuceneSpellChecker implements
- org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker {
+public class LuceneSpellChecker implements org.exoplatform.services.jcr.impl.core.query.lucene.SpellChecker
+{
- /**
- * Logger instance for this class.
- */
- private static final Log log = ExoLogger
- .getLogger(LuceneSpellChecker.class);
+ /**
+ * Logger instance for this class.
+ */
+ private static final Log log = ExoLogger.getLogger(LuceneSpellChecker.class);
- public static final class FiveSecondsRefreshInterval extends
- LuceneSpellChecker {
- public FiveSecondsRefreshInterval() {
- super(5 * 1000);
- }
- }
+ public static final class FiveSecondsRefreshInterval extends LuceneSpellChecker
+ {
+ public FiveSecondsRefreshInterval()
+ {
+ super(5 * 1000);
+ }
+ }
- public static final class OneMinuteRefreshInterval extends
- LuceneSpellChecker {
- public OneMinuteRefreshInterval() {
- super(60 * 1000);
- }
- }
+ public static final class OneMinuteRefreshInterval extends LuceneSpellChecker
+ {
+ public OneMinuteRefreshInterval()
+ {
+ super(60 * 1000);
+ }
+ }
- public static final class FiveMinutesRefreshInterval extends
- LuceneSpellChecker {
- public FiveMinutesRefreshInterval() {
- super(5 * 60 * 1000);
- }
- }
+ public static final class FiveMinutesRefreshInterval extends LuceneSpellChecker
+ {
+ public FiveMinutesRefreshInterval()
+ {
+ super(5 * 60 * 1000);
+ }
+ }
- public static final class ThirtyMinutesRefreshInterval extends
- LuceneSpellChecker {
- public ThirtyMinutesRefreshInterval() {
- super(30 * 60 * 1000);
- }
- }
+ public static final class ThirtyMinutesRefreshInterval extends LuceneSpellChecker
+ {
+ public ThirtyMinutesRefreshInterval()
+ {
+ super(30 * 60 * 1000);
+ }
+ }
- public static final class OneHourRefreshInterval extends LuceneSpellChecker {
- public OneHourRefreshInterval() {
- super(60 * 60 * 1000);
- }
- }
+ public static final class OneHourRefreshInterval extends LuceneSpellChecker
+ {
+ public OneHourRefreshInterval()
+ {
+ super(60 * 60 * 1000);
+ }
+ }
- public static final class SixHoursRefreshInterval extends
- LuceneSpellChecker {
- public SixHoursRefreshInterval() {
- super(6 * 60 * 60 * 1000);
- }
- }
+ public static final class SixHoursRefreshInterval extends LuceneSpellChecker
+ {
+ public SixHoursRefreshInterval()
+ {
+ super(6 * 60 * 60 * 1000);
+ }
+ }
- public static final class TwelveHoursRefreshInterval extends
- LuceneSpellChecker {
- public TwelveHoursRefreshInterval() {
- super(12 * 60 * 60 * 1000);
- }
- }
+ public static final class TwelveHoursRefreshInterval extends LuceneSpellChecker
+ {
+ public TwelveHoursRefreshInterval()
+ {
+ super(12 * 60 * 60 * 1000);
+ }
+ }
- public static final class OneDayRefreshInterval extends LuceneSpellChecker {
- public OneDayRefreshInterval() {
- super(24 * 60 * 60 * 1000);
- }
- }
+ public static final class OneDayRefreshInterval extends LuceneSpellChecker
+ {
+ public OneDayRefreshInterval()
+ {
+ super(24 * 60 * 60 * 1000);
+ }
+ }
- /**
- * The internal spell checker.
- */
- private InternalSpellChecker spellChecker;
+ /**
+ * The internal spell checker.
+ */
+ private InternalSpellChecker spellChecker;
- /**
- * The refresh interval.
- */
- private final long refreshInterval;
+ /**
+ * The refresh interval.
+ */
+ private final long refreshInterval;
- /**
- * Spell checker with a default refresh interval of one hour.
- */
- public LuceneSpellChecker() {
- this(60 * 60 * 1000); // default refresh interval: one hour
- }
+ /**
+ * Spell checker with a default refresh interval of one hour.
+ */
+ public LuceneSpellChecker()
+ {
+ this(60 * 60 * 1000); // default refresh interval: one hour
+ }
- protected LuceneSpellChecker(long refreshInterval) {
- this.refreshInterval = refreshInterval;
- }
+ protected LuceneSpellChecker(long refreshInterval)
+ {
+ this.refreshInterval = refreshInterval;
+ }
- /**
- * Initializes this spell checker.
- *
- * @param handler
- * the query handler that created this spell checker.
- * @throws IOException
- * if <code>handler</code> is not of type {@link SearchIndex}.
- */
- public void init(QueryHandler handler) throws IOException {
- if (handler instanceof SearchIndex) {
- this.spellChecker = new InternalSpellChecker((SearchIndex) handler);
- } else {
- throw new IOException("LuceneSpellChecker only works with "
- + SearchIndex.class.getName());
- }
- }
+ /**
+ * Initializes this spell checker.
+ *
+ * @param handler
+ * the query handler that created this spell checker.
+ * @throws IOException
+ * if <code>handler</code> is not of type {@link SearchIndex}.
+ */
+ public void init(QueryHandler handler) throws IOException
+ {
+ if (handler instanceof SearchIndex)
+ {
+ this.spellChecker = new InternalSpellChecker((SearchIndex)handler);
+ }
+ else
+ {
+ throw new IOException("LuceneSpellChecker only works with " + SearchIndex.class.getName());
+ }
+ }
- /**
- * {@inheritDoc}
- *
- * @throws RepositoryException
- */
- public String check(QueryRootNode aqt) throws IOException,
- RepositoryException {
- String stmt = getFulltextStatement(aqt);
- if (stmt == null) {
- // no spellcheck operation in query
- return null;
- }
- return spellChecker.suggest(stmt);
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @throws RepositoryException
+ */
+ public String check(QueryRootNode aqt) throws IOException, RepositoryException
+ {
+ String stmt = getFulltextStatement(aqt);
+ if (stmt == null)
+ {
+ // no spellcheck operation in query
+ return null;
+ }
+ return spellChecker.suggest(stmt);
+ }
- public void close() {
- spellChecker.close();
- }
+ public void close()
+ {
+ spellChecker.close();
+ }
- // ------------------------------< internal
- // >--------------------------------
+ // ------------------------------< internal
+ // >--------------------------------
- /**
- * Returns the fulltext statement of a spellcheck relation query node or
- * <code>null</code> if none exists in the abstract query tree.
- *
- * @param aqt
- * the abstract query tree.
- * @return the fulltext statement or <code>null</code>.
- * @throws RepositoryException
- */
- private String getFulltextStatement(QueryRootNode aqt)
- throws RepositoryException {
- final String[] stmt = new String[1];
- aqt.accept(new TraversingQueryNodeVisitor() {
- public Object visit(RelationQueryNode node, Object o)
- throws RepositoryException {
- if (stmt[0] == null
- && node.getOperation() == RelationQueryNode.OPERATION_SPELLCHECK) {
- stmt[0] = node.getStringValue();
- }
- return super.visit(node, o);
- }
- }, null);
- return stmt[0];
- }
+ /**
+ * Returns the fulltext statement of a spellcheck relation query node or
+ * <code>null</code> if none exists in the abstract query tree.
+ *
+ * @param aqt
+ * the abstract query tree.
+ * @return the fulltext statement or <code>null</code>.
+ * @throws RepositoryException
+ */
+ private String getFulltextStatement(QueryRootNode aqt) throws RepositoryException
+ {
+ final String[] stmt = new String[1];
+ aqt.accept(new TraversingQueryNodeVisitor()
+ {
+ public Object visit(RelationQueryNode node, Object o) throws RepositoryException
+ {
+ if (stmt[0] == null && node.getOperation() == RelationQueryNode.OPERATION_SPELLCHECK)
+ {
+ stmt[0] = node.getStringValue();
+ }
+ return super.visit(node, o);
+ }
+ }, null);
+ return stmt[0];
+ }
- private final class InternalSpellChecker {
+ private final class InternalSpellChecker
+ {
- /**
- * Timestamp when the last refresh was done.
- */
- private long lastRefresh;
+ /**
+ * Timestamp when the last refresh was done.
+ */
+ private long lastRefresh;
- /**
- * Set to true while a refresh is done in a separate thread.
- */
- private boolean refreshing = false;
+ /**
+ * Set to true while a refresh is done in a separate thread.
+ */
+ private boolean refreshing = false;
- /**
- * The query handler associated with this spell checker.
- */
- private final SearchIndex handler;
+ /**
+ * The query handler associated with this spell checker.
+ */
+ private final SearchIndex handler;
- /**
- * The directory where the spell index is stored.
- */
- private final Directory spellIndexDirectory;
+ /**
+ * The directory where the spell index is stored.
+ */
+ private final Directory spellIndexDirectory;
- /**
- * The underlying spell checker.
- */
- private SpellChecker spellChecker;
+ /**
+ * The underlying spell checker.
+ */
+ private SpellChecker spellChecker;
- /**
- * Creates a new internal spell checker.
- *
- * @param handler
- * the associated query handler.
- */
- InternalSpellChecker(SearchIndex handler) throws IOException {
- this.handler = handler;
- String path = handler.getContext().getIndexDirectory()
- + File.separatorChar + "spellchecker";
- this.spellIndexDirectory = FSDirectory.getDirectory(path,
- new NativeFSLockFactory(path));
- if (IndexReader.indexExists(spellIndexDirectory)) {
- this.lastRefresh = System.currentTimeMillis();
- }
- this.spellChecker = new SpellChecker(spellIndexDirectory);
- refreshSpellChecker();
- }
+ /**
+ * Creates a new internal spell checker.
+ *
+ * @param handler
+ * the associated query handler.
+ */
+ InternalSpellChecker(SearchIndex handler) throws IOException
+ {
+ this.handler = handler;
+ String path = handler.getContext().getIndexDirectory() + File.separatorChar + "spellchecker";
+ this.spellIndexDirectory = FSDirectory.getDirectory(path, new NativeFSLockFactory(path));
+ if (IndexReader.indexExists(spellIndexDirectory))
+ {
+ this.lastRefresh = System.currentTimeMillis();
+ }
+ this.spellChecker = new SpellChecker(spellIndexDirectory);
+ this.spellChecker.setAccuracy(0.55f);
+ refreshSpellChecker();
+ }
- /**
- * Checks a fulltext query statement and suggests a spell checked
- * version of the statement. If the spell checker thinks the spelling is
- * correct <code>null</code> is returned.
- *
- * @param statement
- * the fulltext query statement.
- * @return a suggestion or <code>null</code>.
- */
- String suggest(String statement) throws IOException {
- // tokenize the statement (field name doesn't matter actually...)
- List<String> words = new ArrayList<String>();
- List<Token> tokens = new ArrayList<Token>();
- tokenize(statement, words, tokens);
+ /**
+ * Checks a fulltext query statement and suggests a spell checked
+ * version of the statement. If the spell checker thinks the spelling is
+ * correct <code>null</code> is returned.
+ *
+ * @param statement
+ * the fulltext query statement.
+ * @return a suggestion or <code>null</code>.
+ */
+ String suggest(String statement) throws IOException
+ {
+ // tokenize the statement (field name doesn't matter actually...)
+ List<String> words = new ArrayList<String>();
+ List<Token> tokens = new ArrayList<Token>();
+ tokenize(statement, words, tokens);
- String[] suggestions = check(words
- .toArray(new String[words.size()]));
- if (suggestions != null) {
- // replace words in statement in reverse order because length
- // of statement will change
- StringBuffer sb = new StringBuffer(statement);
- for (int i = suggestions.length - 1; i >= 0; i--) {
- Token t = tokens.get(i);
- // only replace if word acutally changed
- if (!t.termText().equalsIgnoreCase(suggestions[i])) {
- sb.replace(t.startOffset(), t.endOffset(),
- suggestions[i]);
- }
- }
- return sb.toString();
- } else {
- return null;
- }
- }
+ String[] suggestions = check(words.toArray(new String[words.size()]));
+ if (suggestions != null)
+ {
+ // replace words in statement in reverse order because length
+ // of statement will change
+ StringBuffer sb = new StringBuffer(statement);
+ for (int i = suggestions.length - 1; i >= 0; i--)
+ {
+ Token t = tokens.get(i);
+ // only replace if word acutally changed
+ if (!t.termText().equalsIgnoreCase(suggestions[i]))
+ {
+ sb.replace(t.startOffset(), t.endOffset(), suggestions[i]);
+ }
+ }
+ return sb.toString();
+ }
+ else
+ {
+ return null;
+ }
+ }
- void close() {
- try {
- spellIndexDirectory.close();
- } catch (IOException e) {
- // ignore
- }
- // urgh, the lucene spell checker cannot be closed explicitly.
- // finalize will close the reader...
- spellChecker = null;
- }
+ void close()
+ {
+ try
+ {
+ spellIndexDirectory.close();
+ }
+ catch (IOException e)
+ {
+ // ignore
+ }
+ // urgh, the lucene spell checker cannot be closed explicitly.
+ // finalize will close the reader...
+ spellChecker = null;
+ }
- /**
- * Tokenizes the statement into words and tokens.
- *
- * @param statement
- * the fulltext query statement.
- * @param words
- * this list will be filled with the original words extracted
- * from the statement.
- * @param tokens
- * this list will be filled with the tokens parsed from the
- * statement.
- * @throws IOException
- * if an error occurs while parsing the statement.
- */
- private void tokenize(String statement, List<String> words,
- List<Token> tokens) throws IOException {
- TokenStream ts = handler.getTextAnalyzer().tokenStream(
- FieldNames.FULLTEXT, new StringReader(statement));
- try {
- Token t;
- while ((t = ts.next()) != null) {
- String origWord = statement.substring(t.startOffset(), t
- .endOffset());
- if (t.getPositionIncrement() > 0) {
- words.add(t.termText());
- tokens.add(t);
- } else {
- // very simple implementation: use termText with length
- // closer to original word
- Token current = tokens.get(tokens.size() - 1);
- if (Math.abs(origWord.length()
- - current.termText().length()) > Math
- .abs(origWord.length() - t.termText().length())) {
- // replace current token and word
- words.set(words.size() - 1, t.termText());
- tokens.set(tokens.size() - 1, t);
- }
- }
- }
- } finally {
- ts.close();
- }
- }
+ /**
+ * Tokenizes the statement into words and tokens.
+ *
+ * @param statement
+ * the fulltext query statement.
+ * @param words
+ * this list will be filled with the original words extracted
+ * from the statement.
+ * @param tokens
+ * this list will be filled with the tokens parsed from the
+ * statement.
+ * @throws IOException
+ * if an error occurs while parsing the statement.
+ */
+ private void tokenize(String statement, List<String> words, List<Token> tokens) throws IOException
+ {
+ TokenStream ts = handler.getTextAnalyzer().tokenStream(FieldNames.FULLTEXT, new StringReader(statement));
+ try
+ {
+ Token t;
+ while ((t = ts.next()) != null)
+ {
+ String origWord = statement.substring(t.startOffset(), t.endOffset());
+ if (t.getPositionIncrement() > 0)
+ {
+ words.add(t.termText());
+ tokens.add(t);
+ }
+ else
+ {
+ // very simple implementation: use termText with length
+ // closer to original word
+ Token current = tokens.get(tokens.size() - 1);
+ if (Math.abs(origWord.length() - current.termText().length()) > Math.abs(origWord.length()
+ - t.termText().length()))
+ {
+ // replace current token and word
+ words.set(words.size() - 1, t.termText());
+ tokens.set(tokens.size() - 1, t);
+ }
+ }
+ }
+ }
+ finally
+ {
+ ts.close();
+ }
+ }
- /**
- * Checks the spelling of the passed <code>words</code> and returns a
- * suggestion.
- *
- * @param words
- * the words to check.
- * @return a suggestion of correctly spelled <code>words</code> or
- * <code>null</code> if this spell checker thinks
- * <code>words</code> are spelled correctly.
- * @throws IOException
- * if an error occurs while spell checking.
- */
- private String[] check(String words[]) throws IOException {
- refreshSpellChecker();
- boolean hasSuggestion = false;
- IndexReader reader = handler.getIndexReader();
- try {
- for (int retries = 0; retries < 100; retries++) {
- try {
- String[] suggestion = new String[words.length];
- for (int i = 0; i < words.length; i++) {
- String[] similar = spellChecker.suggestSimilar(
- words[i], 5, reader, FieldNames.FULLTEXT,
- true);
- if (similar.length > 0) {
- suggestion[i] = similar[0];
- hasSuggestion = true;
- } else {
- suggestion[i] = words[i];
- }
- }
- if (hasSuggestion) {
- log.debug("Successful after "
- + new Integer(retries) + " retries");
- return suggestion;
- } else {
- return null;
- }
- } catch (AlreadyClosedException e) {
- // it may happen that the index reader inside the
- // spell checker is closed while searching for
- // suggestions. this is actually a design flaw in the
- // lucene spell checker, but for now we simply retry
- }
- }
- // unsuccessful after retries
- return null;
- } finally {
- reader.close();
- }
- }
+ /**
+ * Checks the spelling of the passed <code>words</code> and returns a
+ * suggestion.
+ *
+ * @param words
+ * the words to check.
+ * @return a suggestion of correctly spelled <code>words</code> or
+ * <code>null</code> if this spell checker thinks
+ * <code>words</code> are spelled correctly.
+ * @throws IOException
+ * if an error occurs while spell checking.
+ */
+ private String[] check(String words[]) throws IOException
+ {
+ refreshSpellChecker();
+ boolean hasSuggestion = false;
+ IndexReader reader = handler.getIndexReader();
+ try
+ {
+ for (int retries = 0; retries < 100; retries++)
+ {
+ try
+ {
+ String[] suggestion = new String[words.length];
+ for (int i = 0; i < words.length; i++)
+ {
+ String[] similar = spellChecker.suggestSimilar(words[i], 5, reader, FieldNames.FULLTEXT, true);
+ if (similar.length > 0)
+ {
+ suggestion[i] = similar[0];
+ hasSuggestion = true;
+ }
+ else
+ {
+ suggestion[i] = words[i];
+ }
+ }
+ if (hasSuggestion)
+ {
+ log.debug("Successful after " + new Integer(retries) + " retries");
+ return suggestion;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch (AlreadyClosedException e)
+ {
+ // it may happen that the index reader inside the
+ // spell checker is closed while searching for
+ // suggestions. this is actually a design flaw in the
+ // lucene spell checker, but for now we simply retry
+ }
+ }
+ // unsuccessful after retries
+ return null;
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
- /**
- * Refreshes the underlying spell checker in a background thread.
- * Synchronization is done on this <code>LuceneSpellChecker</code>
- * instance. While the refresh takes place {@link #refreshing} is set to
- * <code>true</code>.
- */
- private void refreshSpellChecker() {
- if (lastRefresh + refreshInterval < System.currentTimeMillis()) {
- synchronized (this) {
- if (refreshing) {
- return;
- } else {
- refreshing = true;
- Runnable refresh = new Runnable() {
- public void run() {
- try {
- IndexReader reader = handler
- .getIndexReader();
- try {
- long time = System.currentTimeMillis();
- Dictionary dict = new LuceneDictionary(
- reader, FieldNames.FULLTEXT);
- log
- .debug("Starting spell checker index refresh");
- spellChecker.indexDictionary(dict);
- time = System.currentTimeMillis()
- - time;
- time = time / 1000;
- log
- .info("Spell checker index refreshed in: "
- + new Long(time)
- + " s.");
- } finally {
- reader.close();
- synchronized (InternalSpellChecker.this) {
- refreshing = false;
- }
- }
- } catch (IOException e) {
- // ignore
- }
- }
- };
- new Thread(refresh, "SpellChecker Refresh").start();
- lastRefresh = System.currentTimeMillis();
- }
- }
- }
- }
- }
+ /**
+ * Refreshes the underlying spell checker in a background thread.
+ * Synchronization is done on this <code>LuceneSpellChecker</code>
+ * instance. While the refresh takes place {@link #refreshing} is set to
+ * <code>true</code>.
+ */
+ private void refreshSpellChecker()
+ {
+ if (lastRefresh + refreshInterval < System.currentTimeMillis())
+ {
+ synchronized (this)
+ {
+ if (refreshing)
+ {
+ return;
+ }
+ else
+ {
+ refreshing = true;
+ Runnable refresh = new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ IndexReader reader = handler.getIndexReader();
+ try
+ {
+ long time = System.currentTimeMillis();
+ Dictionary dict = new LuceneDictionary(reader, FieldNames.FULLTEXT);
+ log.debug("Starting spell checker index refresh");
+ spellChecker.indexDictionary(dict);
+ time = System.currentTimeMillis() - time;
+ time = time / 1000;
+ log.info("Spell checker index refreshed in: " + new Long(time) + " s.");
+ }
+ finally
+ {
+ reader.close();
+ synchronized (InternalSpellChecker.this)
+ {
+ refreshing = false;
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ // ignore
+ }
+ }
+ };
+ new Thread(refresh, "SpellChecker Refresh").start();
+ lastRefresh = System.currentTimeMillis();
+ }
+ }
+ }
+ }
+ }
}
Modified: jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java
===================================================================
--- jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java 2009-10-21 16:18:15 UTC (rev 347)
+++ jcr/trunk/component/core/src/test/java/org/exoplatform/services/jcr/api/core/query/lucene/spell/SpellCheckerTest.java 2009-10-22 09:45:53 UTC (rev 348)
@@ -59,7 +59,8 @@
public void testSpellCheckerComplexQuery() throws RepositoryException
{
String text = "the quick brown fox jumps over the lazy dog";
- testRootNode.setProperty("prop", text);
+ Node n = testRootNode.addNode("testNode");
+ n.setProperty("prop", text);
superuser.save();
// wait a couple of seconds, refresh interval in test config is 5 seconds
try
@@ -80,7 +81,7 @@
public void testSpellCheckerComplexQuery2() throws RepositoryException
{
- String text = "the quick brown fox jumps over the lazy dog";
+ String text = "the quick brown fox jumps over the lazy dog and something else";
Node doc = testRootNode.addNode("file", "nt:file");//.setProperty("prop", text);
NodeImpl cont = (NodeImpl)doc.addNode("jcr:content", "nt:resource");
More information about the exo-jcr-commits
mailing list