You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fg...@apache.org on 2010/01/19 18:22:44 UTC
svn commit: r900853 - in /incubator/chemistry/trunk/chemistry:
chemistry-commons/src/main/antlr3/org/apache/chemistry/cmissql/
chemistry-commons/src/main/antlr3/org/apache/chemistry/impl/simple/
chemistry-commons/src/main/java/org/apache/chemistry/impl...
Author: fguillaume
Date: Tue Jan 19 17:22:43 2010
New Revision: 900853
URL: http://svn.apache.org/viewvc?rev=900853&view=rev
Log:
fixed CMISQL parser for functions and boolean expressions; implemented CONTAINS, IN_TREE, IN_FOLDER for Simple
Added:
incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java (with props)
incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java (with props)
Modified:
incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/cmissql/CmisSqlParser.g
incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/impl/simple/CmisSqlSimpleWalker.g
incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java
incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/gunit/org/apache/chemistry/cmissql/CmisSql.testsuite
incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java
Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/cmissql/CmisSqlParser.g
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/cmissql/CmisSqlParser.g?rev=900853&r1=900852&r2=900853&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/cmissql/CmisSqlParser.g (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/cmissql/CmisSqlParser.g Tue Jan 19 17:22:43 2010
@@ -130,19 +130,17 @@
where_clause: WHERE^ search_condition;
search_condition:
- // not a BIN_OP
- boolean_term ( OR^ boolean_term )*;
+ boolean_term ( OR boolean_term )*;
boolean_term:
- // not a BIN_OP
- boolean_factor ( AND^ boolean_factor )*;
+ boolean_factor ( AND boolean_factor )*;
boolean_factor:
- NOT^? boolean_test;
+ NOT? boolean_test;
boolean_test:
predicate
- | LPAR! search_condition RPAR!
+ | LPAR search_condition RPAR
;
predicate:
@@ -212,7 +210,9 @@
;
text_search_predicate:
- CONTAINS^ LPAR! (qualifier COMMA!)? text_search_expression RPAR!;
+ CONTAINS LPAR (qualifier COMMA)? text_search_expression RPAR
+ -> ^(FUNC CONTAINS qualifier? text_search_expression)
+ ;
folder_predicate:
( f=IN_FOLDER | f=IN_TREE ) LPAR (qualifier COMMA)? folder_id RPAR
Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/impl/simple/CmisSqlSimpleWalker.g
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/impl/simple/CmisSqlSimpleWalker.g?rev=900853&r1=900852&r2=900853&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/impl/simple/CmisSqlSimpleWalker.g (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/antlr3/org/apache/chemistry/impl/simple/CmisSqlSimpleWalker.g Tue Jan 19 17:22:43 2010
@@ -53,11 +53,23 @@
@members {
public SimpleData data;
+ public SimpleConnection connection;
+
+ public String errorMessage;
+
+ @Override
+ public void displayRecognitionError(String[] tokenNames,
+ RecognitionException e) {
+ if (errorMessage == null) {
+ errorMessage = getErrorMessage(e, tokenNames);
+ }
+ }
}
-query [SimpleData d] returns [String tableName, boolean matches]
+query [SimpleData d, SimpleConnection conn] returns [String tableName, boolean matches]
@init {
data = $d;
+ connection = $conn;
}:
^(SELECT select_list from_clause where_clause order_by_clause?)
{
@@ -90,7 +102,7 @@
{
String col = $column_name.start.getText();
// TODO should use query name
- $value = data.get(col); // TODO error if unknown prop
+ $value = data.getIgnoreCase(col); // TODO error if unknown prop
}
;
@@ -144,67 +156,31 @@
;
search_condition returns [boolean matches]:
- boolean_term
- {
- $matches = $boolean_term.matches;
- }
- | ^(OR (list+=boolean_term)+)
- {
- $matches = false;
- for (boolean_term_return t : (List<boolean_term_return>) $list) {
- if (t.matches) {
- $matches = true;
- break;
- }
- }
- }
+ b1=boolean_term { $matches = $b1.matches; }
+ (OR b2=boolean_term { $matches |= $b2.matches; })*
;
boolean_term returns [boolean matches]:
- boolean_factor
- {
- $matches = $boolean_factor.matches;
- }
- | ^(AND (list+=boolean_factor)+)
- {
- $matches = true;
- for (boolean_factor_return t : (List<boolean_factor_return>) $list) {
- if (t.matches) {
- $matches = false;
- break;
- }
- }
- }
+ b1=boolean_factor { $matches = $b1.matches; }
+ (AND b2=boolean_factor { $matches &= $b2.matches; })*
;
boolean_factor returns [boolean matches]:
- boolean_test
- {
- $matches = $boolean_test.matches;
- }
- | ^(NOT boolean_test)
- {
- $matches = ! $boolean_test.matches;
- }
+ b=boolean_test { $matches = $b.matches; }
+ | NOT b=boolean_test { $matches = ! $b.matches; }
;
boolean_test returns [boolean matches]:
- predicate
- {
- $matches = $predicate.matches;
- }
-// | search_condition
+ predicate { $matches = $predicate.matches; }
+ | LPAR search_condition RPAR { $matches = $search_condition.matches; }
;
-predicate returns [boolean matches]:
- ^(UN_OP IS_NULL un_arg)
- {
- $matches = $un_arg.value == null;
- }
- | ^(UN_OP IS_NOT_NULL un_arg)
- {
- $matches = $un_arg.value != null;
- }
+predicate returns [boolean matches]
+@init {
+ List<Object> literals = new ArrayList<Object>();
+}:
+ ^(UN_OP IS_NULL un_arg) { $matches = $un_arg.value == null; }
+ | ^(UN_OP IS_NOT_NULL un_arg) { $matches = $un_arg.value != null; }
| ^(BIN_OP bin_op arg1=bin_arg arg2=bin_arg)
{
int token = $bin_op.start.getType();
@@ -221,8 +197,24 @@
throw new UnwantedTokenException(token, input);
}
}
-// | text_search_predicate
-// | folder_predicate
+ | ^(FUNC func_name (literal { literals.add($literal.value); })*)
+ {
+ int func = $func_name.start.getType();
+ switch (func) {
+ case IN_FOLDER:
+ $matches = connection.isInFolder(data, literals.get(0));
+ break;
+ case IN_TREE:
+ $matches = connection.isInTree(data, literals.get(0));
+ break;
+ case CONTAINS:
+ $matches = connection.fulltextContains(data, literals);
+ break;
+ case ID:
+ default:
+ throw new UnwantedTokenException(Token.INVALID_TOKEN_TYPE, input);
+ }
+ }
;
un_arg returns [Object value]:
@@ -235,7 +227,10 @@
bin_op:
EQ | NEQ | LT | GT | LTEQ | GTEQ | LIKE | NOT_LIKE;
-bin_arg returns [Object value]:
+bin_arg returns [Object value]
+@init {
+ List<Object> literals = new ArrayList<Object>();
+}:
value_expression
{
$value = $value_expression.value;
@@ -244,16 +239,15 @@
{
$value = $literal.value;
}
- | ^(LIST (list+=literal)+)
+ | ^(LIST (literal { literals.add($literal.value); })+)
{
- List<Object> ret = new ArrayList<Object>($list.size());
- for (literal_return l : (List<literal_return>) $list) {
- ret.add(l.value);
- }
- $value = ret;
+ $value = literals;
}
;
+func_name:
+ IN_FOLDER | IN_TREE | CONTAINS | ID;
+
literal returns [Object value]:
NUM_LIT
{
Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java?rev=900853&r1=900852&r2=900853&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java Tue Jan 19 17:22:43 2010
@@ -23,8 +23,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import javax.xml.namespace.QName;
@@ -41,6 +43,7 @@
import org.apache.chemistry.ACLPropagation;
import org.apache.chemistry.BaseType;
import org.apache.chemistry.CMISObject;
+import org.apache.chemistry.CMISRuntimeException;
import org.apache.chemistry.Connection;
import org.apache.chemistry.ConstraintViolationException;
import org.apache.chemistry.ContentStream;
@@ -66,6 +69,7 @@
import org.apache.chemistry.VersioningState;
import org.apache.chemistry.cmissql.CmisSqlLexer;
import org.apache.chemistry.cmissql.CmisSqlParser;
+import org.apache.chemistry.impl.simple.CmisSqlSimpleWalker.query_return;
import org.apache.chemistry.util.GregorianCalendar;
public class SimpleConnection implements Connection, SPI {
@@ -781,12 +785,69 @@
CommonTree tree = (CommonTree) new CmisSqlParser(tokens).query().getTree();
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
nodes.setTokenStream(tokens);
- return new CmisSqlSimpleWalker(nodes).query(data);
+ CmisSqlSimpleWalker walker = new CmisSqlSimpleWalker(nodes);
+ query_return res = walker.query(data, this);
+ if (walker.errorMessage != null) {
+ throw new CMISRuntimeException("Cannot parse query: "
+ + statement + " (" + walker.errorMessage + ")");
+ }
+ return res;
} catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
+ throw new CMISRuntimeException(e.getMessage(), e);
} catch (RecognitionException e) {
- throw new RuntimeException("Cannot parse query: " + statement, e);
+ throw new CMISRuntimeException("Cannot parse query: " + statement,
+ e);
+ }
+ }
+
+ // IN_FOLDER
+ protected boolean isInFolder(SimpleData data, Object folderId) {
+ if (!(folderId instanceof String)) {
+ throw new IllegalArgumentException(folderId.toString());
+ }
+ Set<String> children = repository.children.get(folderId);
+ if (children == null) {
+ return false; // no such id
+ }
+ return children.contains(data.get(Property.ID));
+ }
+
+ // IN_TREE
+ protected boolean isInTree(SimpleData data, Object folderId) {
+ if (!(folderId instanceof String)) {
+ throw new IllegalArgumentException(folderId.toString());
+ }
+ String id = (String) data.get(Property.ID);
+ if (id == null) {
+ return false; // no such id
+ }
+ Queue<String> todo = new LinkedList<String>(Collections.singleton(id));
+ while (!todo.isEmpty()) {
+ String cur = todo.remove();
+ Set<String> parents = repository.parents.get(cur);
+ for (String pid : parents) {
+ if (pid.equals(folderId)) {
+ return true;
+ }
+ }
+ todo.addAll(parents);
+ }
+ return false;
+ }
+
+ // CONTAINS
+ protected boolean fulltextContains(SimpleData data, List<Object> args) {
+ // String qual;
+ String query;
+ if (args.size() == 2) {
+ // qual = (String) args.get(0);
+ query = (String) args.get(1);
+ } else {
+ // qual = null;
+ query = (String) args.get(0);
}
+ Set<String> words = SimpleFulltext.parseFulltext(data);
+ return SimpleFulltext.matchesFullText(words, query);
}
public Collection<CMISObject> query(String statement,
Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java?rev=900853&r1=900852&r2=900853&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java Tue Jan 19 17:22:43 2010
@@ -41,4 +41,27 @@
}
}
+ /**
+ * Returns the value to which the specified key is mapped, or {@code null}
+ * if this map contains no mapping for the key.
+ * <p>
+ * Key comparison is done case insensitively.
+ *
+ * @throws NullPointerException if the specified key is {@code null}
+ * @see ConcurrentHashMap#get(Object)
+ */
+ public Serializable getIgnoreCase(String key) {
+ // shortcut for exact case match
+ if (contains(key)) {
+ return get(key);
+ }
+ // try all keys
+ for (String k : keySet()) {
+ if (key.equalsIgnoreCase(k)) {
+ return get(k);
+ }
+ }
+ return null;
+ }
+
}
Added: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java?rev=900853&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java Tue Jan 19 17:22:43 2010
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Florent Guillaume, Nuxeo
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+
+/**
+ * Simple utility class that does basic and naive fulltext match.
+ */
+public class SimpleFulltext {
+
+ private SimpleFulltext() {
+ }
+
+ /**
+ * Extracts the words from a SimpleData for fulltext indexing.
+ */
+ protected static Set<String> parseFulltext(Map<String, Serializable> data) {
+ Set<String> set = new HashSet<String>();
+ for (Entry<String, Serializable> es : data.entrySet()) {
+ Object value = es.getValue();
+ if (value instanceof String) {
+ parseFullText((String) value, set);
+ } else if (value instanceof String[]) {
+ for (String v : (String[]) value) {
+ parseFullText(v, set);
+ }
+ }
+ }
+ return set;
+ }
+
+ protected static void parseFullText(String string, Set<String> set) {
+ if (string == null) {
+ return;
+ }
+ for (String word : wordPattern.split(string)) {
+ String w = parseWord(word);
+ if (w != null) {
+ set.add(w);
+ }
+ }
+ }
+
+ /**
+ * Checks if the passed query expression matches the fulltext.
+ */
+ // TODO XXX implement actual CMIS 1.0 language
+ protected static boolean matchesFullText(Set<String> fulltextWords,
+ String query) {
+ if (fulltextWords == null || query == null) {
+ return false;
+ }
+ Set<String> queryWords = split(query, ' ');
+ if (queryWords.isEmpty()) {
+ return false;
+ }
+ for (String word : queryWords) {
+ if (!fulltextWords.contains(word)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // ----- simple parsing, don't try to be exhaustive -----
+
+ private static final Pattern wordPattern = Pattern.compile("[\\s\\p{Punct}]+");
+
+ private static final String UNACCENTED = "aaaaaaaceeeeiiii\u00f0nooooo\u00f7ouuuuy\u00fey";
+
+ private static final String STOPWORDS = "a an are and as at be by for from how "
+ + "i in is it of on or that the this to was what when where who will with "
+ + "car donc est il ils je la le les mais ni nous or ou pour tu un une vous "
+ + "www com net org";
+
+ private static final Set<String> stopWords = new HashSet<String>(split(
+ STOPWORDS, ' '));
+
+ protected static final String parseWord(String string) {
+ int len = string.length();
+ if (len < 3) {
+ return null;
+ }
+ StringBuilder buf = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ char c = Character.toLowerCase(string.charAt(i));
+ if (c == '\u00e6') {
+ buf.append("ae");
+ } else if (c >= '\u00e0' && c <= '\u00ff') {
+ buf.append(UNACCENTED.charAt((c) - 0xe0));
+ } else if (c == '\u0153') {
+ buf.append("oe");
+ } else {
+ buf.append(c);
+ }
+ }
+ // simple heuristic to remove plurals
+ int l = buf.length();
+ if (l > 3 && buf.charAt(l - 1) == 's') {
+ buf.setLength(l - 1);
+ }
+ String word = buf.toString();
+ if (stopWords.contains(word)) {
+ return null;
+ }
+ return word;
+ }
+
+ protected static Set<String> split(String string, char sep) {
+ int len = string.length();
+ if (len == 0) {
+ return Collections.emptySet();
+ }
+ int end = string.indexOf(sep);
+ if (end == -1) {
+ return Collections.singleton(string);
+ }
+ Set<String> set = new HashSet<String>();
+ int start = 0;
+ do {
+ String segment = string.substring(start, end);
+ set.add(segment);
+ start = end + 1;
+ end = string.indexOf(sep, start);
+ } while (end != -1);
+ if (start < len) {
+ set.add(string.substring(start));
+ } else {
+ set.add("");
+ }
+ return set;
+ }
+
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFulltext.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/gunit/org/apache/chemistry/cmissql/CmisSql.testsuite
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/gunit/org/apache/chemistry/cmissql/CmisSql.testsuite?rev=900853&r1=900852&r2=900853&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/gunit/org/apache/chemistry/cmissql/CmisSql.testsuite (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/gunit/org/apache/chemistry/cmissql/CmisSql.testsuite Tue Jan 19 17:22:43 2010
@@ -113,12 +113,12 @@
"IN_TREE('ID123')" -> (FUNC IN_TREE 'ID123')
text_search_predicate:
-"CONTAINS('foo')" -> (CONTAINS 'foo')
-"CONTAINS(bar, 'foo')" -> (CONTAINS bar 'foo')
+"CONTAINS('foo')" -> (FUNC CONTAINS 'foo')
+"CONTAINS(bar, 'foo')" -> (FUNC CONTAINS bar 'foo')
-search_condition:
-"foo = 1" -> (BIN_OP = (COL foo) 1)
-"a = 1 AND b <> 2 OR c >= 3 AND NOT d <= 4" -> (OR (AND (BIN_OP = (COL a) 1) (BIN_OP <> (COL b) 2)) (AND (BIN_OP >= (COL c) 3) (NOT (BIN_OP <= (COL d) 4))))
+where_clause:
+"WHERE foo = 1" -> (WHERE (BIN_OP = (COL foo) 1))
+"WHERE a = 1 AND b <> 2 OR c >= 3 AND NOT d <= 4" -> (WHERE (BIN_OP = (COL a) 1) AND (BIN_OP <> (COL b) 2) OR (BIN_OP >= (COL c) 3) AND NOT (BIN_OP <= (COL d) 4))
query:
"SELECT * FROM Document" -> (SELECT * (FROM (TABLE Document)))
@@ -132,7 +132,7 @@
SELECT TITLE, AUTHORS, DATE
FROM WHITE_PAPER
WHERE ( IN_TREE('ID00093854763') ) AND ( 'SMITH' = ANY AUTHORS )
->> -> (SELECT (LIST (COL TITLE) (COL AUTHORS) (COL DATE)) (FROM (TABLE WHITE_PAPER)) (WHERE (AND (FUNC IN_TREE 'ID00093854763') (BIN_OP_ANY = 'SMITH' (COL AUTHORS)))))
+>> -> (SELECT (LIST (COL TITLE) (COL AUTHORS) (COL DATE)) (FROM (TABLE WHITE_PAPER)) (WHERE ( (FUNC IN_TREE 'ID00093854763') ) AND ( (BIN_OP_ANY = 'SMITH' (COL AUTHORS)) )))
<<
SELECT OBJECT_ID, SCORE() AS X, DESTINATION, DEPARTURE_DATES
Added: incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java?rev=900853&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java Tue Jan 19 17:22:43 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Florent Guillaume, Nuxeo
+ * Amelie Avramo, EntropySoft
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+public class TestSimpleFulltext extends TestCase {
+
+ public static void checkSplit(String string, String... expected) {
+ assertEquals(new HashSet<String>(Arrays.asList(expected)),
+ SimpleFulltext.split(string, ' '));
+ }
+
+ public static void checkSplit(char sep, String string, String... expected) {
+ assertEquals(new HashSet<String>(Arrays.asList(expected)),
+ SimpleFulltext.split(string, sep));
+ }
+
+ public void testSplit() {
+ checkSplit("", new String[0]);
+ checkSplit("A", "A");
+ checkSplit("A B C", "A", "B", "C");
+ checkSplit("A B", "A", "B", "");
+ checkSplit(" A B C", "A", "B", "C", "");
+ checkSplit("A B C ", "A", "B", "C", "");
+ checkSplit(" ", "");
+ checkSplit('-', "A-B-C", "A", "B", "C");
+ }
+
+ public void testParse() {
+ assertNull(SimpleFulltext.parseWord("gr"));
+ assertNull(SimpleFulltext.parseWord("are"));
+ assertNull(SimpleFulltext.parseWord("THE"));
+ assertEquals("foo", SimpleFulltext.parseWord("foo"));
+ assertEquals("foo", SimpleFulltext.parseWord("fOoS"));
+ }
+
+ protected static void checkParseFullText(String expected, String text) {
+ Set<String> set = new HashSet<String>();
+ SimpleFulltext.parseFullText(text, set);
+ assertEquals(new HashSet<String>(Arrays.asList(expected.split(" "))),
+ set);
+ }
+
+ public void testParseFullText() throws Exception {
+ checkParseFullText("brown dog fail fox jump lazy over quick",
+ "The quick brown fox jumps over the lazy dog -- and fails!");
+ checkParseFullText("aime cafe jure pas",
+ "J'aime PAS le caf\u00e9, je te jure.");
+ checkParseFullText("007 bond jame thx1138", "James Bond 007 && THX1138");
+ }
+
+}
Propchange: incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleFulltext.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java?rev=900853&r1=900852&r2=900853&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java Tue Jan 19 17:22:43 2010
@@ -252,11 +252,65 @@
}
public void testQuery() {
- Collection<CMISObject> res = conn.query("SELECT * FROM doc", false);
+ String rootId = spi.getRepository().getInfo().getRootFolderId().getId();
+ String folder1Id = spi.getObjectByPath("/folder 1", null).getId();
+ String folder2Id = spi.getObjectByPath("/folder 1/folder 2", null).getId();
+ Collection<CMISObject> res;
+
+ res = conn.query("SELECT * FROM doc", false);
+ assertNotNull(res);
+ assertEquals(4, res.size());
+ res = conn.query("SELECT * FROM cmis:document", false);
assertNotNull(res);
assertEquals(4, res.size());
+ ObjectEntry doc = spi.getObjectByPath("/folder 1/folder 2/doc 2", null);
+ res = conn.query(String.format(
+ "SELECT * FROM cmis:document WHERE cmis:objectId = '%s'",
+ doc.getId()), false);
+ assertEquals(1, res.size());
+
res = conn.query("SELECT * FROM fold", false);
assertEquals(2, res.size());
+ res = conn.query("SELECT * FROM cmis:folder", false);
+ assertEquals(3, res.size()); // root as well
+ res = conn.query(String.format(
+ "SELECT * FROM cmis:folder WHERE cmis:objectId = '%s'",
+ folder2Id), false);
+ assertEquals(1, res.size());
+ res = conn.query(String.format(
+ "SELECT * FROM cmis:folder WHERE cmis:objectId = '%s'"
+ + " AND cmis:name = 'folder 2'"
+ + " AND title <> 'blarg'", //
+ folder2Id), false);
+ assertEquals(1, res.size());
+
+ // IN_FOLDER
+ String sqlpat = "SELECT * FROM cmis:document WHERE IN_FOLDER('%s')";
+ res = conn.query(String.format(sqlpat, folder2Id), false);
+ assertEquals(3, res.size());
+ sqlpat = "SELECT * FROM cmis:folder WHERE IN_FOLDER('%s')";
+ res = conn.query(String.format(sqlpat, folder1Id), false);
+ assertEquals(1, res.size());
+
+ // IN_TREE
+ sqlpat = "SELECT * FROM cmis:document WHERE IN_TREE('%s')";
+ res = conn.query(String.format(sqlpat, folder2Id), false);
+ assertEquals(3, res.size());
+ sqlpat = "SELECT * FROM cmis:document WHERE IN_TREE('%s')";
+ res = conn.query(String.format(sqlpat, folder1Id), false);
+ assertEquals(4, res.size());
+ sqlpat = "SELECT * FROM cmis:folder WHERE IN_TREE('%s')";
+ res = conn.query(String.format(sqlpat, rootId), false);
+ assertEquals(2, res.size());
+
+ // CONTAINS
+ res = conn.query(
+ "SELECT * FROM cmis:folder WHERE CONTAINS('description')",
+ false);
+ assertEquals(2, res.size());
+ res = conn.query("SELECT * FROM cmis:document WHERE CONTAINS('small')",
+ false);
+ assertEquals(1, res.size());
}
public void testGetObjectByPath() {