This project has retired. For details please refer to its Attic page.
XPathBuilderTest xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.chemistry.opencmis.jcr.query;
21  
22  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
23  import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
24  import org.apache.chemistry.opencmis.jcr.JcrTypeManager;
25  import org.apache.chemistry.opencmis.jcr.PathManager;
26  import org.apache.chemistry.opencmis.jcr.impl.DefaultDocumentTypeHandler;
27  import org.apache.chemistry.opencmis.jcr.impl.DefaultFolderTypeHandler;
28  import org.apache.chemistry.opencmis.jcr.impl.DefaultUnversionedDocumentTypeHandler;
29  import org.apache.chemistry.opencmis.jcr.type.JcrTypeHandlerManager;
30  import org.apache.chemistry.opencmis.jcr.util.ISO8601;
31  import org.apache.chemistry.opencmis.server.support.query.CalendarHelper;
32  import org.apache.chemistry.opencmis.server.support.query.QueryObject;
33  import org.apache.chemistry.opencmis.server.support.query.QueryUtil;
34  import org.junit.Before;
35  import org.junit.Test;
36  
37  import java.util.Arrays;
38  import java.util.GregorianCalendar;
39  import java.util.Iterator;
40  import java.util.List;
41  
42  import static org.junit.Assert.*;
43  
44  public class XPathBuilderTest {
45  
46      private JcrTypeManager typeManager;
47  
48      @Before
49      public void setUp() throws Exception {
50          typeManager = new JcrTypeManager();
51          PathManager pathManager = new PathManager(PathManager.CMIS_ROOT_PATH);
52          JcrTypeHandlerManager typeHandlerManager = new JcrTypeHandlerManager(pathManager, typeManager);
53          typeHandlerManager.addHandler(new DefaultFolderTypeHandler());
54          typeHandlerManager.addHandler(new DefaultDocumentTypeHandler());
55          typeHandlerManager.addHandler(new DefaultUnversionedDocumentTypeHandler());
56      }
57  
58      @Test
59      public void testValidQuery() {
60          check("select * from cmis:document",
61                  null,
62                  list(),
63                  null);
64  
65          check("select * from cmis:document where cmis:isLatestVersion='foo'",
66                  "cmis:isLatestVersion = 'foo'",
67                  list(),
68                  null);
69  
70          check("select * from cmis:document where cmis:isLatestVersion LIKE 'foo'",
71                  "jcr:like(cmis:isLatestVersion, 'foo')",
72                  list(),
73                  null);
74  
75          check("select * from cmis:document where cmis:isLatestVersion NOT LIKE 'foo'",
76                  "not(jcr:like(cmis:isLatestVersion, 'foo'))",
77                  list(),
78                  null);
79  
80          check("select * from cmis:document where cmis:isLatestVersion='foo' AND cmis:name<>'baz'",
81                  "cmis:isLatestVersion = 'foo' and cmis:name != 'baz'",
82                  list(),
83                  null);
84  
85          check("select * from cmis:document where NOT (cmis:isLatestVersion>'foo' OR cmis:name< 1.0)",
86                  "not((cmis:isLatestVersion > 'foo' or cmis:name < 1.0))",
87                  list(),
88                  null);
89  
90          check("select * from cmis:document where cmis:name = 'foo' or cmis:objectId = 'baz' and cmis:createdBy = 'bar'",
91                  "(cmis:name = 'foo' or cmis:objectId = 'baz' and cmis:createdBy = 'bar')",
92                  list(),
93                  null);
94  
95          check("select * from cmis:document where cmis:name = 'foo' and cmis:objectId = 'baz' or cmis:createdBy = 'bar'",
96                  "(cmis:name = 'foo' and cmis:objectId = 'baz' or cmis:createdBy = 'bar')",
97                  list(),
98                  null);
99  
100         check("select * from cmis:document where cmis:name = 'foo' and (cmis:objectId = 'baz' or cmis:createdBy = 'bar')",
101                 "cmis:name = 'foo' and (cmis:objectId = 'baz' or cmis:createdBy = 'bar')",
102                 list(),
103                 null);
104 
105         check("select * from cmis:document where IN_FOLDER('folderId')",
106                 "folderId/",
107                 list("folderId/"),
108                 false);
109 
110         check("select * from cmis:document where not(not(IN_FOLDER('folderId')))",
111                 "true()",
112                 list("folderId/"),
113                 false);
114 
115         check("select * from cmis:document where IN_TREE('folderId')",
116                 "folderId//",
117                 list("folderId//"),
118                 false);
119 
120         check("select * from cmis:document where not(not(IN_TREE('folderId')))",
121                 "true()",
122                 list("folderId//"),
123                 false);
124 
125         check("select * from cmis:document where IN_FOLDER('folderId') AND cmis:name <= 1",
126                 "cmis:name <= 1",
127                 list("folderId/"),
128                 false);
129 
130         check("select * from cmis:document where IN_TREE('folderId') AND cmis:name >= 'name' AND cmis:name = TRUE",
131                 "cmis:name >= 'name' and cmis:name = true",
132                 list("folderId//"),
133                 false);
134 
135         GregorianCalendar date = new GregorianCalendar();
136         check("select * from cmis:document where NOT(NOT IN_FOLDER('folderId') OR cmis:name = TIMESTAMP '" +
137                 CalendarHelper.toString(date) + "')",
138                 "not(cmis:name = xs:dateTime('" + ISO8601.format(date) + "'))",
139                 list("folderId/"),
140                 false);
141 
142         check("select * from cmis:document where cmis:name IS NULL",
143                 "cmis:name",
144                 list(),
145                 null);
146 
147         check("select * from cmis:document where cmis:name IS NOT NULL",
148                 "not(cmis:name)",
149                 list(),
150                 null);
151 
152 // TODO: adjust to full text query parser       
153 //        check("select * from cmis:document where CONTAINS('foo')",
154 //                "jcr:contains(., 'foo')",
155 //                list(),
156 //                null);
157     }
158 
159     @Test
160     public void testTooSpecificQuery() {
161         check("select * from cmis:document where NOT IN_FOLDER('folderId')",
162                 "false()",
163                 list("folderId/"),
164                 true);
165 
166         check("select * from cmis:document where NOT(NOT IN_FOLDER('folderId') AND cmis:name = 'name')",
167                 "true()",
168                 list("folderId/"),
169                 null);
170 
171         check("select * from cmis:document where IN_FOLDER('folderId') OR cmis:name = 'name'",
172                 "true()",
173                 list("folderId/"),
174                 null);
175 
176         check("select * from cmis:document where NOT(IN_FOLDER('folderId') AND cmis:name = 'name')",
177                 "not(cmis:name = 'name')",
178                 list("folderId/"),
179                 true);
180 
181         check("select * from cmis:document where IN_FOLDER('folder1Id') OR IN_TREE('folder2Id')",
182                 "true()",
183                 list("folder1Id/", "folder2Id//"),
184                 false);
185 
186         check("select * from cmis:document where IN_FOLDER('folder1Id') AND NOT IN_TREE('folder2Id')",
187                 "false()",
188                 list("folder1Id/", "folder2Id//"),
189                 false);
190     }
191 
192     @Test
193     public void testNotImplemented() {
194         try {
195             execute("select * from cmis:document where cmis:name in (1,2,3)");
196             fail();
197         }
198         catch (CmisNotSupportedException expected) {}
199 
200         try {
201             execute("select * from cmis:document where 'foo' = ANY cmis:name");
202             fail();
203         }
204         catch (CmisNotSupportedException expected) {}
205     }
206 
207     @Test
208     public void testInvalidQuery() {
209         try {
210             execute("");
211             fail();
212         }
213         catch (CmisInvalidArgumentException expected) {}
214 
215         try {
216             execute("select * from cmis:something");
217             fail();
218         }
219         catch (CmisInvalidArgumentException expected) {}
220 
221         try {
222             execute("select * from cmis:document WHERE");
223             fail();
224         }
225         catch (CmisInvalidArgumentException expected) {}
226 
227         try {
228             execute("select * from cmis:document WHERE cmis:something = 'foo'");
229             fail();
230         }
231         catch (CmisInvalidArgumentException expected) {}
232     }
233 
234     //------------------------------------------< private >---
235 
236     private static List<String> list(String... elements) {
237         return Arrays.asList(elements);
238     }
239 
240     private XPathBuilder execute(String statement) {
241         QueryUtil queryUtil = new QueryUtil();
242         QueryObject queryObject = new QueryObject(typeManager);
243         ParseTreeWalker<XPathBuilder> parseTreeWalker = new ParseTreeWalker<XPathBuilder>(new EvaluatorXPath());
244         queryUtil.traverseStatementAndCatchExc(statement, queryObject, parseTreeWalker);
245         return parseTreeWalker.getResult();
246     }
247 
248     private void check(String query, String result, List<String> folderPredicates, Boolean evaluation) {
249         XPathBuilder queryBuilder = execute(query);
250         if (result == null) {
251             assertEquals(null, queryBuilder);
252         } else {
253             assertEquals(result, queryBuilder.xPath());
254 
255             Iterator<XPathBuilder> folderPredicatesBuilder = queryBuilder.folderPredicates().iterator();
256             for (String folderPredicate : folderPredicates) {
257                 assertTrue(folderPredicatesBuilder.hasNext());
258                 assertEquals(folderPredicate, folderPredicatesBuilder.next().xPath());
259             }
260             assertFalse(folderPredicatesBuilder.hasNext());
261 
262             assertEquals(evaluation, queryBuilder.eval(false));
263         }
264     }
265 
266 }