This project has retired. For details please refer to its
Attic page.
AbstractQueryConditionProcessor xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.inmemory.query;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.IOException;
23 import java.io.UnsupportedEncodingException;
24 import java.util.ArrayList;
25 import java.util.GregorianCalendar;
26 import java.util.List;
27
28 import org.antlr.runtime.ANTLRInputStream;
29 import org.antlr.runtime.CharStream;
30 import org.antlr.runtime.CommonTokenStream;
31 import org.antlr.runtime.RecognitionException;
32 import org.antlr.runtime.TokenSource;
33 import org.antlr.runtime.TokenStream;
34 import org.antlr.runtime.tree.CommonTree;
35 import org.antlr.runtime.tree.CommonTreeNodeStream;
36 import org.antlr.runtime.tree.Tree;
37 import org.apache.chemistry.opencmis.server.support.query.CalendarHelper;
38 import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictLexer;
39 import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictParser;
40 import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictParser_CmisBaseGrammar.query_return;
41 import org.apache.chemistry.opencmis.server.support.query.CmisQueryWalker;
42 import org.apache.chemistry.opencmis.server.support.query.StringUtil;
43 import org.apache.chemistry.opencmis.server.support.query.TextSearchLexer;
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46
47 public abstract class AbstractQueryConditionProcessor implements QueryConditionProcessor {
48
49 private static final Log LOG = LogFactory.getLog(ProcessQueryTest.class);
50
51 public abstract void onStartProcessing(Tree whereNode);
52 public abstract void onStopProcessing();
53
54
55 public abstract void onEquals(Tree eqNode, Tree leftNode, Tree rightNode);
56 public abstract void onNotEquals(Tree neNode, Tree leftNode, Tree rightNode);
57 public abstract void onGreaterThan(Tree gtNode, Tree leftNode, Tree rightNode);
58 public abstract void onGreaterOrEquals(Tree geNode, Tree leftNode, Tree rightNode);
59 public abstract void onLessThan(Tree ltNode, Tree leftNode, Tree rightNode);
60 public abstract void onLessOrEquals(Tree leqNode, Tree leftNode, Tree rightNode);
61
62
63 public void onPreNot(Tree opNode, Tree leftNode) {
64 }
65 public abstract void onNot(Tree opNode, Tree leftNode);
66 public void onPostNot(Tree opNode, Tree leftNode) {
67 }
68 public void onPreAnd(Tree opNode, Tree leftNode, Tree rightNode) {
69 }
70 public abstract void onAnd(Tree opNode, Tree leftNode, Tree rightNode);
71 public void onPostAnd(Tree opNode, Tree leftNode, Tree rightNode) {
72 }
73 public void onPreOr(Tree opNode, Tree leftNode, Tree rightNode) {
74 }
75 public abstract void onOr(Tree opNode, Tree leftNode, Tree rightNode);
76 public void onPostOr(Tree opNode, Tree leftNode, Tree rightNode) {
77 }
78
79
80 public abstract void onIn(Tree node, Tree colNode, Tree listNode);
81 public abstract void onNotIn(Tree node, Tree colNode, Tree listNode);
82 public abstract void onInAny(Tree node, Tree colNode, Tree listNode);
83 public abstract void onNotInAny(Tree node, Tree colNode, Tree listNode);
84 public abstract void onEqAny(Tree node, Tree literalNode, Tree colNode);
85
86
87 public abstract void onIsNull(Tree nullNode, Tree colNode);
88 public abstract void onIsNotNull(Tree notNullNode, Tree colNode);
89
90
91 public abstract void onIsLike(Tree node, Tree colNode, Tree stringNode);
92 public abstract void onIsNotLike(Tree node, Tree colNode, Tree stringNode);
93
94
95 public abstract void onInFolder(Tree node, Tree colNode, Tree paramNode);
96 public abstract void onInTree(Tree node, Tree colNode, Tree paramNode);
97 public abstract void onScore(Tree node);
98
99 public void onPreTextAnd(Tree node, List<Tree> conjunctionNodes) {
100 }
101 public abstract void onTextAnd(Tree node, List<Tree> conjunctionNodes);
102 public void onPostTextAnd(Tree node, List<Tree> conjunctionNodes) {
103 }
104 public void onPreTextOr(Tree node, List<Tree> termNodes) {
105 }
106 public abstract void onTextOr(Tree node, List<Tree> termNodes);
107 public void onPostTextOr(Tree node, List<Tree> termNodes) {
108 }
109 public abstract void onTextMinus(Tree node, Tree notNode);
110 public abstract void onTextWord(String word);
111 public abstract void onTextPhrase(String phrase);
112
113
114 public static CmisQueryWalker getWalker(String statement) throws UnsupportedEncodingException, IOException, RecognitionException {
115 CharStream input = new ANTLRInputStream(new ByteArrayInputStream(statement.getBytes("UTF-8")));
116 TokenSource lexer = new CmisQlStrictLexer(input);
117 TokenStream tokens = new CommonTokenStream(lexer);
118 CmisQlStrictParser parser = new CmisQlStrictParser(tokens);
119 CommonTree parserTree;
120
121 query_return parsedStatement = parser.query();
122
123
124
125 parserTree = (CommonTree) parsedStatement.getTree();
126
127 CommonTreeNodeStream nodes = new CommonTreeNodeStream(parserTree);
128 nodes.setTokenStream(tokens);
129 CmisQueryWalker walker = new CmisQueryWalker(nodes);
130 return walker;
131 }
132
133
134
135 public Boolean walkPredicate(Tree whereNode) {
136 if (null != whereNode) {
137 onStartProcessing(whereNode);
138 evalWhereNode(whereNode);
139 onStopProcessing();
140 }
141 return null;
142 }
143
144
145
146
147
148 public void onContains(Tree node, Tree typeNode, Tree searchExprNode) {
149 LOG.debug("evaluating text search node: " + searchExprNode);
150 evalTextSearchNode(searchExprNode);
151 }
152
153 protected void evalWhereNode(Tree node) {
154
155
156 LOG.debug("evaluating node: " + node.toString());
157 switch (node.getType()) {
158 case CmisQlStrictLexer.WHERE:
159 break;
160 case CmisQlStrictLexer.EQ:
161 evalWhereNode(node.getChild(0));
162 onEquals(node, node.getChild(0), node.getChild(1));
163 evalWhereNode(node.getChild(1));
164 break;
165 case CmisQlStrictLexer.NEQ:
166 evalWhereNode(node.getChild(0));
167 onNotEquals(node, node.getChild(0), node.getChild(1));
168 evalWhereNode(node.getChild(1));
169 break;
170 case CmisQlStrictLexer.GT:
171 evalWhereNode(node.getChild(0));
172 onGreaterThan(node, node.getChild(0), node.getChild(1));
173 evalWhereNode(node.getChild(1));
174 break;
175 case CmisQlStrictLexer.GTEQ:
176 evalWhereNode(node.getChild(0));
177 onGreaterOrEquals(node, node.getChild(0), node.getChild(1));
178 evalWhereNode(node.getChild(1));
179 break;
180 case CmisQlStrictLexer.LT:
181 evalWhereNode(node.getChild(0));
182 onLessThan(node, node.getChild(0), node.getChild(1));
183 evalWhereNode(node.getChild(1));
184 break;
185 case CmisQlStrictLexer.LTEQ:
186 evalWhereNode(node.getChild(0));
187 onLessOrEquals(node, node.getChild(0), node.getChild(1));
188 evalWhereNode(node.getChild(1));
189 break;
190
191 case CmisQlStrictLexer.NOT:
192 onPreNot(node, node.getChild(0));
193 onNot(node, node.getChild(0));
194 evalWhereNode(node.getChild(0));
195 onPostNot(node, node.getChild(0));
196 break;
197 case CmisQlStrictLexer.AND:
198 onPreAnd(node, node.getChild(0), node.getChild(1));
199 evalWhereNode(node.getChild(0));
200 onAnd(node, node.getChild(0), node.getChild(1));
201 evalWhereNode(node.getChild(1));
202 onPostAnd(node, node.getChild(0), node.getChild(1));
203 break;
204 case CmisQlStrictLexer.OR:
205 onPreOr(node, node.getChild(0), node.getChild(1));
206 evalWhereNode(node.getChild(0));
207 onOr(node, node.getChild(0), node.getChild(1));
208 evalWhereNode(node.getChild(1));
209 onPostOr(node, node.getChild(0), node.getChild(1));
210 break;
211
212
213 case CmisQlStrictLexer.IN:
214 evalWhereNode(node.getChild(0));
215 onIn(node, node.getChild(0), node.getChild(1));
216 evalWhereNode(node.getChild(1));
217 break;
218 case CmisQlStrictLexer.NOT_IN:
219 evalWhereNode(node.getChild(0));
220 onNotIn(node, node.getChild(0), node.getChild(1));
221 evalWhereNode(node.getChild(1));
222 break;
223 case CmisQlStrictLexer.IN_ANY:
224 evalWhereNode(node.getChild(0));
225 onInAny(node, node.getChild(0), node.getChild(1));
226 evalWhereNode(node.getChild(1));
227 break;
228 case CmisQlStrictLexer.NOT_IN_ANY:
229 evalWhereNode(node.getChild(0));
230 onNotInAny(node, node.getChild(0), node.getChild(1));
231 evalWhereNode(node.getChild(1));
232 break;
233 case CmisQlStrictLexer.EQ_ANY:
234 evalWhereNode(node.getChild(0));
235 onEqAny(node, node.getChild(0), node.getChild(1));
236 evalWhereNode(node.getChild(1));
237 break;
238
239
240 case CmisQlStrictLexer.IS_NULL:
241 onIsNull(node, node.getChild(0));
242 evalWhereNode(node.getChild(0));
243 break;
244 case CmisQlStrictLexer.IS_NOT_NULL:
245 onIsNotNull(node, node.getChild(0));
246 evalWhereNode(node.getChild(0));
247 break;
248
249
250 case CmisQlStrictLexer.LIKE:
251 evalWhereNode(node.getChild(0));
252 onIsLike(node, node.getChild(0), node.getChild(1));
253 evalWhereNode(node.getChild(1));
254 break;
255 case CmisQlStrictLexer.NOT_LIKE:
256 evalWhereNode(node.getChild(0));
257 onIsNotLike(node, node.getChild(0), node.getChild(1));
258 evalWhereNode(node.getChild(1));
259 break;
260
261
262 case CmisQlStrictLexer.CONTAINS:
263 onContains(node, null, node.getChild(0));
264 break;
265 case CmisQlStrictLexer.IN_FOLDER:
266 if (node.getChildCount() == 1) {
267 onInFolder(node, null, node.getChild(0));
268 evalWhereNode(node.getChild(0));
269 } else {
270 evalWhereNode(node.getChild(0));
271 onInFolder(node, node.getChild(0), node.getChild(1));
272 evalWhereNode(node.getChild(1));
273 }
274 break;
275 case CmisQlStrictLexer.IN_TREE:
276 if (node.getChildCount() == 1) {
277 onInTree(node, null, node.getChild(0));
278 evalWhereNode(node.getChild(0));
279 } else {
280 evalWhereNode(node.getChild(0));
281 onInTree(node, node.getChild(0), node.getChild(1));
282 evalWhereNode(node.getChild(1));
283 }
284 break;
285 case CmisQlStrictLexer.SCORE:
286 onScore(node);
287 break;
288
289 default:
290
291 }
292 }
293
294 protected void evalTextSearchNode(Tree node) {
295
296
297 LOG.debug("evaluating node: " + node.toString());
298 switch (node.getType()) {
299 case TextSearchLexer.TEXT_AND:
300 List<Tree> children = getChildrenAsList(node);
301 onPreTextAnd(node, children);
302 for (Tree child : children)
303 evalTextSearchNode(child);
304 onTextAnd(node, children);
305 onPostTextAnd(node, children);
306 break;
307 case TextSearchLexer.TEXT_OR:
308 children = getChildrenAsList(node);
309 onPreTextOr(node, children);
310 for (Tree child : children)
311 evalTextSearchNode(child);
312 onTextOr(node, children);
313 onPostTextOr(node, children);
314 break;
315 case TextSearchLexer.TEXT_MINUS:
316 onTextMinus(node, node.getChild(0));
317 break;
318 case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
319 onTextPhrase(onTextLiteral(node));
320 break;
321 case TextSearchLexer.TEXT_SEARCH_WORD_LIT:
322 onTextWord(onTextLiteral(node));
323 break;
324 }
325 }
326
327
328
329 protected Object onLiteral(Tree node) {
330 int type = node.getType();
331 String text = node.getText();
332 switch (type) {
333 case CmisQlStrictLexer.BOOL_LIT:
334 return Boolean.parseBoolean(node.getText());
335 case CmisQlStrictLexer.NUM_LIT:
336 if (text.contains(".") || text.contains("e") || text.contains("E")) {
337 return Double.parseDouble(text);
338 } else {
339 return Long.parseLong(text);
340 }
341 case CmisQlStrictLexer.STRING_LIT:
342 return text.substring(1, text.length()-1);
343 case CmisQlStrictLexer.TIME_LIT:
344 GregorianCalendar gc = CalendarHelper.fromString(text.substring(text.indexOf('\'')+1, text.lastIndexOf('\'')));
345 return gc;
346 default:
347 throw new RuntimeException("Unknown literal. " + node);
348 }
349 }
350
351 protected String onTextLiteral(Tree node) {
352 int type = node.getType();
353 String text = node.getText();
354 switch (type) {
355 case TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT:
356 return StringUtil.unescape(text.substring(1, text.length()-1), null);
357 case TextSearchLexer.TEXT_SEARCH_WORD_LIT:
358 return StringUtil.unescape(text, null);
359 default:
360 throw new RuntimeException("Unknown text literal. " + node);
361 }
362
363 }
364
365 protected List<Object> onLiteralList(Tree node) {
366 List<Object> res = new ArrayList<Object>(node.getChildCount());
367 for (int i=0; i<node.getChildCount(); i++) {
368 Tree literal = node.getChild(i);
369 res.add(onLiteral(literal));
370 }
371 return res;
372 }
373
374 protected List<Tree> getChildrenAsList(Tree node) {
375 List<Tree> res = new ArrayList<Tree>(node.getChildCount());
376 for (int i=0; i<node.getChildCount(); i++) {
377 Tree childNnode = node.getChild(i);
378 res.add(childNnode);
379 }
380 return res;
381 }
382 }