/*
* (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.storage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.nuxeo.ecm.core.query.QueryParseException;
import org.nuxeo.ecm.core.storage.FulltextQueryAnalyzer.FulltextQuery;
import org.nuxeo.ecm.core.storage.FulltextQueryAnalyzer.Op;
public class TestFulltextQueryAnalyzer {
protected void assertFulltextException(String query) {
try {
FulltextQueryAnalyzer.analyzeFulltextQuery(query);
fail("Query should fail: " + query);
} catch (QueryParseException e) {
// ok
}
}
protected static void dumpFulltextQuery(FulltextQuery ft, StringBuilder buf) {
if (ft.op == Op.AND || ft.op == Op.OR) {
assertNull(ft.word);
buf.append('[');
for (int i = 0; i < ft.terms.size(); i++) {
if (i != 0) {
buf.append(' ');
buf.append(ft.op.name());
buf.append(' ');
}
dumpFulltextQuery(ft.terms.get(i), buf);
}
buf.append(']');
return;
} else {
assertNull(ft.terms);
if (ft.op == Op.NOTWORD) {
buf.append('~');
}
boolean isPhrase = ft.word.contains(" ");
if (isPhrase) {
buf.append('{');
}
buf.append(ft.word);
if (isPhrase) {
buf.append('}');
}
}
}
protected void assertFulltextQuery(String expected, String query) {
FulltextQuery ft = FulltextQueryAnalyzer.analyzeFulltextQuery(query);
if (ft == null) {
assertNull(expected);
} else {
StringBuilder buf = new StringBuilder();
dumpFulltextQuery(ft, buf);
assertEquals(expected, buf.toString());
}
}
@Test
public void testAnalyzeFulltextQuery() throws Exception {
// invalid queries
assertFulltextException("OR foo");
assertFulltextException("OR foo bar");
assertFulltextException("foo OR");
assertFulltextException("foo bar OR");
assertFulltextException("foo OR OR bar");
assertFulltextException("foo bar OR OR baz");
assertFulltextException("foo + bar");
assertFulltextException("foo - bar");
// ok queries
assertFulltextQuery(null, "");
assertFulltextQuery(null, " ");
assertFulltextQuery("foo", "foo");
assertFulltextQuery("foo", " foo ");
assertFulltextQuery("[foo AND bar]", "foo bar");
assertFulltextQuery("[foo AND bar AND baz]", "foo bar baz");
assertFulltextQuery("[foo AND ~bar]", "foo -bar");
assertFulltextQuery("[foo AND baz AND ~bar]", "foo -bar baz");
assertFulltextQuery("[foo AND ~bar AND ~baz]", "foo -bar -baz");
assertFulltextQuery("[bar AND ~foo]", "-foo bar");
assertFulltextQuery("[bar AND baz AND ~foo]", "-foo bar baz");
// queries with OR
assertFulltextQuery("[foo OR bar]", "foo OR bar");
assertFulltextQuery("[foo OR [bar AND baz]]", "foo OR bar baz");
assertFulltextQuery("[[foo AND bar] OR baz]", "foo bar OR baz");
assertFulltextQuery("[foo OR bar OR baz]", "foo OR bar OR baz");
assertFulltextQuery("[foo OR [bar AND baz] OR gee]", "foo OR bar baz OR gee");
assertFulltextQuery("[[bar AND ~foo] OR baz]", "-foo bar OR baz");
assertFulltextQuery("[foo OR [bar AND ~baz]]", "foo OR bar -baz");
// queries containing suppressed terms
assertFulltextQuery(null, "-foo");
assertFulltextQuery(null, "-foo -bar");
assertFulltextQuery("bar", "-foo OR bar");
assertFulltextQuery("foo", "foo OR -bar");
assertFulltextQuery(null, "-foo OR -bar");
assertFulltextQuery("foo", "foo OR -bar -baz");
assertFulltextQuery("baz", "-foo -bar OR baz");
// query with phrases
assertFulltextException("\"foo");
assertFulltextException("\"foo bar");
assertFulltextException("\"fo\"o\"");
assertFulltextQuery(null, "\"\"");
assertFulltextQuery(null, " \" \" ");
assertFulltextQuery("foo", "\"foo\"");
assertFulltextQuery("foo", "+\"foo\"");
assertFulltextQuery(null, "-\"foo\"");
assertFulltextQuery("foo", "\" foo\"");
assertFulltextQuery("foo", "\"foo \"");
assertFulltextQuery("foo", "\" foo \"");
assertFulltextQuery("OR", "\"OR\"");
assertFulltextQuery("{foo bar}", "\"foo bar\"");
assertFulltextQuery("{foo bar}", "\" foo bar\"");
assertFulltextQuery("{foo bar}", "\"foo bar \"");
assertFulltextQuery("{foo bar}", "\" foo bar \"");
assertFulltextQuery("{foo bar}", "+\"foo bar\"");
assertFulltextQuery("{foo or bar}", "\"foo or bar\"");
assertFulltextQuery(null, "-\"foo bar\"");
assertFulltextQuery("[foo AND {bar baz}]", "foo \"bar baz\"");
assertFulltextQuery("[foo AND {bar baz}]", "foo +\"bar baz\"");
assertFulltextQuery("[foo AND ~{bar baz}]", "foo -\"bar baz\"");
assertFulltextQuery("[{foo bar} AND baz]", "\"foo bar\" baz");
assertFulltextQuery("[{foo bar} AND baz]", "+\"foo bar\" baz");
assertFulltextQuery("[baz AND ~{foo bar}]", "-\"foo bar\" baz");
assertFulltextQuery("[{foo bar} AND ~{baz gee}]", "\"foo bar\" -\"baz gee\"");
}
}