This project has retired. For details please refer to its
Attic page.
EvaluatorXPath xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.chemistry.opencmis.jcr.query;
21
22 import org.apache.chemistry.opencmis.jcr.util.ISO8601;
23 import org.apache.chemistry.opencmis.jcr.util.Iterables;
24
25 import java.util.GregorianCalendar;
26 import java.util.List;
27
28
29
30
31
32
33 public class EvaluatorXPath extends EvaluatorBase<XPathBuilder> {
34
35 @Override
36 public Evaluator<XPathBuilder> op() {
37
38
39 return new EvaluatorXPath() {
40 @Override
41 protected String jcrPathFromId(String id) {
42 return EvaluatorXPath.this.jcrPathFromId(id);
43 }
44
45 @Override
46 protected String jcrPathFromCol(String name) {
47 return EvaluatorXPath.this.jcrPathFromCol(name);
48 }
49 };
50 }
51
52 @Override
53 public XPathBuilder not(final XPathBuilder op) {
54 return new XPathBuilder() {
55 public String xPath() {
56 if (eval(true) != null) {
57 return eval(true) ? "true()" : "false()";
58 }
59 else {
60 return "not(" + op.xPath() + ")";
61 }
62 }
63 public Boolean eval(Boolean folderPredicateValuation) {
64 return not(op.eval(folderPredicateValuation));
65 }
66
67 public Iterable<XPathBuilder> folderPredicates() {
68 return op.folderPredicates();
69 }
70 };
71 }
72
73 @Override
74 public XPathBuilder and(final XPathBuilder op1, final XPathBuilder op2) {
75 return new XPathBuilder() {
76 public String xPath() {
77 if (eval(true) != null) {
78 return eval(true) ? "true()" : "false()";
79 }
80 else if (op1.eval(true) != null) {
81 return op2.xPath();
82 }
83 else if (op2.eval(true) != null) {
84 return op1.xPath();
85 }
86 else {
87 return op1.xPath() + " and " + op2.xPath();
88 }
89 }
90 public Boolean eval(Boolean folderPredicateValuation) {
91 return and(op1.eval(folderPredicateValuation), op2.eval(folderPredicateValuation));
92 }
93
94 public Iterable<XPathBuilder> folderPredicates() {
95 return Iterables.concat(op1.folderPredicates(), op2.folderPredicates());
96 }
97 };
98 }
99
100 @Override
101 public XPathBuilder or(final XPathBuilder op1, final XPathBuilder op2) {
102 return new XPathBuilder() {
103 public String xPath() {
104 if (eval(true) != null) {
105 return eval(true) ? "true()" : "false()";
106 }
107 else if (op1.eval(true) != null) {
108 return op2.xPath();
109 }
110 else if (op2.eval(true) != null) {
111 return op1.xPath();
112 }
113 else {
114 return "(" + op1.xPath() + " or " + op2.xPath() + ")";
115 }
116 }
117 public Boolean eval(Boolean folderPredicateValuation) {
118 return or(op1.eval(folderPredicateValuation), op2.eval(folderPredicateValuation));
119 }
120
121 public Iterable<XPathBuilder> folderPredicates() {
122 return Iterables.concat(op1.folderPredicates(), op2.folderPredicates());
123 }
124 };
125 }
126
127 @Override
128 public XPathBuilder eq(XPathBuilder op1, XPathBuilder op2) {
129 return new RelOpBuilder(op1, " = ", op2);
130 }
131
132 @Override
133 public XPathBuilder neq(XPathBuilder op1, XPathBuilder op2) {
134 return new RelOpBuilder(op1, " != ", op2);
135 }
136
137 @Override
138 public XPathBuilder gt(XPathBuilder op1, XPathBuilder op2) {
139 return new RelOpBuilder(op1, " > ", op2);
140 }
141
142 @Override
143 public XPathBuilder gteq(XPathBuilder op1, XPathBuilder op2) {
144 return new RelOpBuilder(op1, " >= ", op2);
145 }
146
147 @Override
148 public XPathBuilder lt(XPathBuilder op1, XPathBuilder op2) {
149 return new RelOpBuilder(op1, " < ", op2);
150 }
151
152 @Override
153 public XPathBuilder lteq(XPathBuilder op1, XPathBuilder op2) {
154 return new RelOpBuilder(op1, " <= ", op2);
155 }
156
157 @Override
158 public XPathBuilder in(XPathBuilder op1, XPathBuilder op2) {
159 return super.in(op1, op2);
160 }
161
162 @Override
163 public XPathBuilder notIn(XPathBuilder op1, XPathBuilder op2) {
164 return super.notIn(op1, op2);
165 }
166
167 @Override
168 public XPathBuilder inAny(XPathBuilder op1, XPathBuilder op2) {
169 return super.inAny(op1, op2);
170 }
171
172 @Override
173 public XPathBuilder notInAny(XPathBuilder op1, XPathBuilder op2) {
174 return super.notInAny(op1, op2);
175 }
176
177 @Override
178 public XPathBuilder eqAny(XPathBuilder op1, XPathBuilder op2) {
179 return super.eqAny(op1, op2);
180 }
181
182 @Override
183 public XPathBuilder isNull(XPathBuilder op) {
184 return new FunctionBuilder(op);
185 }
186
187 @Override
188 public XPathBuilder notIsNull(XPathBuilder op) {
189 return new FunctionBuilder("not", op);
190 }
191
192 @Override
193 public XPathBuilder like(XPathBuilder op1, XPathBuilder op2) {
194 return new FunctionBuilder("jcr:like", op1, op2);
195 }
196
197 @Override
198 public XPathBuilder notLike(XPathBuilder op1, XPathBuilder op2) {
199 return new FunctionBuilder("jcr:like", op1, op2) {
200 @Override
201 public String xPath() {
202 return "not(" + super.xPath() + ")";
203 }
204 };
205 }
206
207 @Override
208 public XPathBuilder contains(XPathBuilder op1, XPathBuilder op2) {
209 return new FunctionBuilder("jcr:contains", ".", op2);
210 }
211
212 @Override
213 public XPathBuilder inFolder(XPathBuilder op1,XPathBuilder op2) {
214 return new FolderPredicateBuilder(op2.xPath(), false);
215 }
216
217 @Override
218 public XPathBuilder inTree(XPathBuilder op1, XPathBuilder op2) {
219 return new FolderPredicateBuilder(op2.xPath(), true);
220 }
221
222 @Override
223 public XPathBuilder list(List<XPathBuilder> ops) {
224 return super.list(ops);
225 }
226
227 @Override
228 public XPathBuilder value(boolean value) {
229 return new LiteralBuilder(value);
230 }
231
232 @Override
233 public XPathBuilder value(double value) {
234 return new LiteralBuilder(value);
235 }
236
237 @Override
238 public XPathBuilder value(long value) {
239 return new LiteralBuilder(value);
240 }
241
242 @Override
243 public XPathBuilder value(String value) {
244 return new LiteralBuilder(value);
245 }
246
247 @Override
248 public XPathBuilder value(GregorianCalendar value) {
249 return new LiteralBuilder(value);
250 }
251
252 @Override
253 public XPathBuilder col(String name) {
254 return new ColRefBuilder(name);
255 }
256
257
258
259
260
261
262
263 protected String jcrPathFromId(String id) {
264 return id;
265 }
266
267
268
269
270
271
272 protected String jcrPathFromCol(String name) {
273 return name;
274 }
275
276
277
278
279
280
281 private static Boolean not(Boolean b) {
282 return b == null ? null : !b;
283 }
284
285
286
287
288
289
290
291 private static Boolean or(Boolean b1, Boolean b2) {
292 return Boolean.TRUE.equals(b1) || Boolean.TRUE.equals(b2)
293 ? Boolean.TRUE
294 : Boolean.FALSE.equals(b1) && Boolean.FALSE.equals(b2)
295 ? Boolean.FALSE
296 : null;
297 }
298
299
300
301
302
303
304
305 private static Boolean and(Boolean b1, Boolean b2) {
306 return Boolean.FALSE.equals(b1) || Boolean.FALSE.equals(b2)
307 ? Boolean.FALSE
308 : Boolean.TRUE.equals(b1) && Boolean.TRUE.equals(b2)
309 ? Boolean.TRUE
310 : null;
311 }
312
313 private static class RelOpBuilder implements XPathBuilder {
314 private final String relOp;
315 private final XPathBuilder op1;
316 private final XPathBuilder op2;
317
318 public RelOpBuilder(XPathBuilder op1, String relOp, XPathBuilder op2) {
319 this.relOp = relOp;
320 this.op1 = op1;
321 this.op2 = op2;
322 }
323
324 public String xPath() {
325 return op1.xPath() + relOp + op2.xPath();
326 }
327
328 public Boolean eval(Boolean folderPredicateValuation) {
329 return null;
330 }
331
332 public Iterable<XPathBuilder> folderPredicates() {
333 return Iterables.concat(op1.folderPredicates(), op2.folderPredicates());
334 }
335 }
336
337 private class FolderPredicateBuilder implements XPathBuilder {
338 private final String folderId;
339 private final boolean includeDescendants;
340
341 public FolderPredicateBuilder(String folderId, boolean includeDescendants) {
342 this.folderId = stripQuotes(folderId);
343 this.includeDescendants = includeDescendants;
344 }
345
346 public String xPath() {
347 return jcrPathFromId(folderId) + (includeDescendants ? "//" : "/");
348 }
349
350 public Boolean eval(Boolean folderPredicateValuation) {
351 return folderPredicateValuation;
352 }
353
354 public Iterable<XPathBuilder> folderPredicates() {
355 return Iterables.singleton((XPathBuilder) this);
356 }
357
358 private String stripQuotes(String string) {
359 return (string.startsWith("'") || string.startsWith("\"")) && string.length() >= 2
360 ? string.substring(1, string.length() - 1)
361 : string;
362 }
363
364 }
365
366 private abstract static class PrimitiveBuilder implements XPathBuilder {
367 public Boolean eval(Boolean folderPredicateValuation) {
368 return null;
369 }
370
371 public Iterable<XPathBuilder> folderPredicates() {
372 return Iterables.empty();
373 }
374 }
375
376 private static class LiteralBuilder extends PrimitiveBuilder {
377 private final String xPath;
378
379 public LiteralBuilder(String value) {
380 xPath = "'" + value + "'";
381 }
382
383 public LiteralBuilder(boolean value) {
384 xPath = Boolean.toString(value);
385 }
386
387 public LiteralBuilder(long value) {
388 xPath = Long.toString(value);
389 }
390
391 public LiteralBuilder(double value) {
392 xPath = Double.toString(value);
393 }
394
395 public LiteralBuilder(GregorianCalendar value) {
396 xPath = "xs:dateTime('" + ISO8601.format(value) + "')";
397 }
398
399 public String xPath() {
400 return xPath;
401 }
402 }
403
404 private class ColRefBuilder extends PrimitiveBuilder {
405 private final String colRef;
406
407 public ColRefBuilder(String colRef) {
408 this.colRef = colRef;
409 }
410
411 public String xPath() {
412 return jcrPathFromCol(colRef);
413 }
414
415 }
416
417 private static class FunctionBuilder extends PrimitiveBuilder {
418 private final String function;
419 private String op1Str;
420 private final XPathBuilder op1;
421 private final XPathBuilder op2;
422
423 private FunctionBuilder(String function, String op1Str, XPathBuilder op1, XPathBuilder op2) {
424 this.function = function;
425 this.op1Str = op1Str;
426 this.op1 = op1;
427 this.op2 = op2;
428 }
429
430 public FunctionBuilder(String function, XPathBuilder op1, XPathBuilder op2) {
431 this(function, null, op1, op2);
432 }
433
434 public FunctionBuilder(String function, XPathBuilder op1) {
435 this(function, null, op1, null);
436 }
437
438 public FunctionBuilder(String function, String op1, XPathBuilder op2) {
439 this(function, op1, null, op2);
440
441 }
442
443 public FunctionBuilder(XPathBuilder op1) {
444 this(null, op1, null);
445 }
446
447 public String xPath() {
448 if (op1Str == null) {
449 op1Str = op1.xPath();
450 }
451
452 return function == null
453 ? op1Str
454 : function + "(" + op1Str + (op2 == null ? "" : ", " + op2.xPath()) + ")";
455 }
456
457 }
458
459 }