1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jcr.query.qom;
25
26 import java.util.ArrayList;
27 import java.util.List;
28 import javax.jcr.RepositoryException;
29 import javax.jcr.Value;
30 import javax.jcr.query.Query;
31 import javax.jcr.query.qom.And;
32 import javax.jcr.query.qom.BindVariableValue;
33 import javax.jcr.query.qom.ChildNode;
34 import javax.jcr.query.qom.ChildNodeJoinCondition;
35 import javax.jcr.query.qom.Column;
36 import javax.jcr.query.qom.Comparison;
37 import javax.jcr.query.qom.Constraint;
38 import javax.jcr.query.qom.DescendantNode;
39 import javax.jcr.query.qom.DescendantNodeJoinCondition;
40 import javax.jcr.query.qom.DynamicOperand;
41 import javax.jcr.query.qom.EquiJoinCondition;
42 import javax.jcr.query.qom.FullTextSearch;
43 import javax.jcr.query.qom.FullTextSearchScore;
44 import javax.jcr.query.qom.Join;
45 import javax.jcr.query.qom.JoinCondition;
46 import javax.jcr.query.qom.Length;
47 import javax.jcr.query.qom.Literal;
48 import javax.jcr.query.qom.LowerCase;
49 import javax.jcr.query.qom.NodeLocalName;
50 import javax.jcr.query.qom.NodeName;
51 import javax.jcr.query.qom.Not;
52 import javax.jcr.query.qom.Or;
53 import javax.jcr.query.qom.Ordering;
54 import javax.jcr.query.qom.PropertyExistence;
55 import javax.jcr.query.qom.PropertyValue;
56 import javax.jcr.query.qom.QueryObjectModelFactory;
57 import javax.jcr.query.qom.SameNode;
58 import javax.jcr.query.qom.SameNodeJoinCondition;
59 import javax.jcr.query.qom.Source;
60 import javax.jcr.query.qom.StaticOperand;
61 import javax.jcr.query.qom.UpperCase;
62 import org.modeshape.common.util.CheckArg;
63 import org.modeshape.graph.query.model.ArithmeticOperator;
64 import org.modeshape.graph.query.model.JoinType;
65 import org.modeshape.graph.query.model.Operator;
66 import org.modeshape.graph.query.model.Order;
67 import org.modeshape.graph.query.model.SelectorName;
68 import org.modeshape.graph.query.model.SetQuery.Operation;
69 import org.modeshape.graph.query.plan.PlanHints;
70 import org.modeshape.jcr.api.query.qom.ArithmeticOperand;
71 import org.modeshape.jcr.api.query.qom.Between;
72 import org.modeshape.jcr.api.query.qom.Limit;
73 import org.modeshape.jcr.api.query.qom.NodeDepth;
74 import org.modeshape.jcr.api.query.qom.NodePath;
75 import org.modeshape.jcr.api.query.qom.QueryCommand;
76 import org.modeshape.jcr.api.query.qom.QueryObjectModelConstants;
77 import org.modeshape.jcr.api.query.qom.SetCriteria;
78 import org.modeshape.jcr.api.query.qom.SetQuery;
79 import org.modeshape.jcr.query.JcrQueryContext;
80
81
82
83
84
85
86 public class JcrQueryObjectModelFactory
87 implements QueryObjectModelFactory, org.modeshape.jcr.api.query.qom.QueryObjectModelFactory {
88
89 public static final String LANGUAGE = Query.JCR_JQOM;
90 private final JcrQueryContext context;
91
92 public JcrQueryObjectModelFactory( JcrQueryContext context ) {
93 this.context = context;
94 }
95
96 protected SelectorName selectorName( String name ) {
97 return new SelectorName(name);
98 }
99
100
101
102
103
104
105
106 @Override
107 public JcrQueryObjectModel createQuery( Source source,
108 Constraint constraint,
109 Ordering[] orderings,
110 Column[] columns ) {
111
112 JcrSelectQuery query = select(source, constraint, orderings, columns, null, false);
113 String statement = query.toString();
114
115 PlanHints hints = new PlanHints();
116 hints.showPlan = true;
117
118 hints.validateColumnExistance = false;
119 return new JcrQueryObjectModel(context, statement, LANGUAGE, query, hints, null);
120 }
121
122
123
124
125
126
127
128
129 @Override
130 public JcrSelectQuery select( Source source,
131 Constraint constraint,
132 Ordering[] orderings,
133 Column[] columns,
134 Limit limit,
135 boolean distinct ) {
136 JcrSource jcrSource = CheckArg.getInstanceOf(source, JcrSource.class, "source");
137 JcrConstraint jcrConstraint = null;
138 if (constraint != null) {
139 jcrConstraint = CheckArg.getInstanceOf(constraint, JcrConstraint.class, "constraint");
140 }
141 List<JcrColumn> jcrColumns = null;
142 if (columns != null) {
143 jcrColumns = new ArrayList<JcrColumn>();
144 for (int i = 0; i != columns.length; ++i) {
145 jcrColumns.add(CheckArg.getInstanceOf(columns[i], JcrColumn.class, "column[" + i + "]"));
146 }
147 }
148 List<JcrOrdering> jcrOrderings = null;
149 if (orderings != null) {
150 jcrOrderings = new ArrayList<JcrOrdering>();
151 for (int i = 0; i != orderings.length; ++i) {
152 jcrOrderings.add(CheckArg.getInstanceOf(orderings[i], JcrOrdering.class, "orderings[" + i + "]"));
153 }
154 }
155 JcrLimit jcrLimit = limit == null ? JcrLimit.NONE : new JcrLimit(limit.getRowLimit(), limit.getOffset());
156 return new JcrSelectQuery(jcrSource, jcrConstraint, jcrOrderings, jcrColumns, jcrLimit, distinct);
157 }
158
159
160
161
162
163
164 @Override
165 public SetQuery union( QueryCommand left,
166 QueryCommand right,
167 Ordering[] orderings,
168 Limit limit,
169 boolean all ) {
170 return setQuery(left, Operation.UNION, right, orderings, limit, all);
171 }
172
173
174
175
176
177
178
179
180 @Override
181 public SetQuery intersect( QueryCommand left,
182 QueryCommand right,
183 Ordering[] orderings,
184 Limit limit,
185 boolean all ) {
186 return setQuery(left, Operation.INTERSECT, right, orderings, limit, all);
187 }
188
189
190
191
192
193
194
195
196 @Override
197 public SetQuery except( QueryCommand left,
198 QueryCommand right,
199 Ordering[] orderings,
200 Limit limit,
201 boolean all ) {
202 return setQuery(left, Operation.EXCEPT, right, orderings, limit, all);
203 }
204
205 public JcrSetQuery setQuery( QueryCommand left,
206 Operation operation,
207 QueryCommand right,
208 Ordering[] orderings,
209 Limit limit,
210 boolean all ) {
211 JcrQueryCommand jcrLeft = CheckArg.getInstanceOf(left, JcrQueryCommand.class, "left");
212 JcrQueryCommand jcrRight = CheckArg.getInstanceOf(left, JcrQueryCommand.class, "left");
213 List<JcrOrdering> jcrOrderings = new ArrayList<JcrOrdering>();
214 for (int i = 0; i != orderings.length; ++i) {
215 jcrOrderings.add(CheckArg.getInstanceOf(orderings[i], JcrOrdering.class, "orderings[" + i + "]"));
216 }
217 JcrLimit jcrLimit = limit == null ? JcrLimit.NONE : new JcrLimit(limit.getRowLimit(), limit.getOffset());
218 return new JcrSetQuery(jcrLeft, operation, jcrRight, all, jcrOrderings, jcrLimit);
219 }
220
221
222
223
224
225
226 @Override
227 public JcrNamedSelector selector( String nodeTypeName,
228 String selectorName ) {
229 CheckArg.isNotNull(nodeTypeName, "nodeTypeName");
230 CheckArg.isNotNull(selectorName, "selectorName");
231 return new JcrNamedSelector(selectorName(nodeTypeName), selectorName(selectorName));
232 }
233
234
235
236
237
238
239 @Override
240 public JcrColumn column( String selectorName,
241 String propertyName,
242 String columnName ) {
243 CheckArg.isNotNull(selectorName, "selectorName");
244 if (propertyName == null) {
245 return new JcrColumn(selectorName(selectorName));
246 }
247 CheckArg.isNotNull(columnName, "columnName");
248 return new JcrColumn(selectorName(selectorName), selectorName, columnName);
249 }
250
251
252
253
254
255
256 @Override
257 public JcrOrdering ascending( DynamicOperand operand ) {
258 JcrDynamicOperand jcrOperand = CheckArg.getInstanceOf(operand, JcrDynamicOperand.class, "operand");
259 return new JcrOrdering(jcrOperand, Order.ASCENDING);
260 }
261
262
263
264
265
266
267 @Override
268 public JcrOrdering descending( DynamicOperand operand ) {
269 JcrDynamicOperand jcrOperand = CheckArg.getInstanceOf(operand, JcrDynamicOperand.class, "operand");
270 return new JcrOrdering(jcrOperand, Order.DESCENDING);
271 }
272
273
274
275
276
277
278 @Override
279 public And and( Constraint constraint1,
280 Constraint constraint2 ) {
281 JcrConstraint jcrConstraint1 = CheckArg.getInstanceOf(constraint1, JcrConstraint.class, "constraint1");
282 JcrConstraint jcrConstraint2 = CheckArg.getInstanceOf(constraint2, JcrConstraint.class, "constraint2");
283 return new JcrAnd(jcrConstraint1, jcrConstraint2);
284 }
285
286
287
288
289
290
291 @Override
292 public BindVariableValue bindVariable( String bindVariableName ) {
293 CheckArg.isNotNull(bindVariableName, "bindVariableName");
294 return new JcrBindVariableName(bindVariableName);
295 }
296
297
298
299
300
301
302 @Override
303 public ChildNode childNode( String selectorName,
304 String path ) {
305 CheckArg.isNotNull(selectorName, "selectorName");
306 CheckArg.isNotNull(path, "path");
307 return new JcrChildNode(selectorName(selectorName), path);
308 }
309
310
311
312
313
314
315 @Override
316 public ChildNodeJoinCondition childNodeJoinCondition( String childSelectorName,
317 String parentSelectorName ) {
318 CheckArg.isNotNull(childSelectorName, "childSelectorName");
319 CheckArg.isNotNull(parentSelectorName, "parentSelectorName");
320 return new JcrChildNodeJoinCondition(selectorName(parentSelectorName), selectorName(childSelectorName));
321 }
322
323
324
325
326
327
328
329 @Override
330 public Comparison comparison( DynamicOperand operand1,
331 String operator,
332 StaticOperand operand2 ) {
333 JcrDynamicOperand jcrOperand1 = CheckArg.getInstanceOf(operand1, JcrDynamicOperand.class, "operand1");
334 CheckArg.isNotEmpty(operator, "operator");
335 JcrStaticOperand jcrOperand2 = CheckArg.getInstanceOf(operand2, JcrStaticOperand.class, "operand2");
336 operator = operator.trim();
337 Operator op = null;
338 if (QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO.equals(operator)) op = Operator.EQUAL_TO;
339 else if (QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN.equals(operator)) op = Operator.GREATER_THAN;
340 else if (QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO.equals(operator)) op = Operator.GREATER_THAN_OR_EQUAL_TO;
341 else if (QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN.equals(operator)) op = Operator.LESS_THAN;
342 else if (QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO.equals(operator)) op = Operator.LESS_THAN_OR_EQUAL_TO;
343 else if (QueryObjectModelConstants.JCR_OPERATOR_LIKE.equals(operator)) op = Operator.LIKE;
344 else if (QueryObjectModelConstants.JCR_OPERATOR_NOT_EQUAL_TO.equals(operator)) op = Operator.NOT_EQUAL_TO;
345 if (op == null) {
346 throw new IllegalArgumentException("Unknown or unsupported comparison operator: " + operator);
347 }
348 return new JcrComparison(jcrOperand1, op, jcrOperand2);
349 }
350
351
352
353
354
355
356 @Override
357 public DescendantNode descendantNode( String selectorName,
358 String path ) {
359 CheckArg.isNotNull(selectorName, "selectorName");
360 CheckArg.isNotNull(path, "path");
361 return new JcrDescendantNode(selectorName(selectorName), path);
362 }
363
364
365
366
367
368
369 @Override
370 public DescendantNodeJoinCondition descendantNodeJoinCondition( String descendantSelectorName,
371 String ancestorSelectorName ) {
372 CheckArg.isNotNull(descendantSelectorName, "descendantSelectorName");
373 CheckArg.isNotNull(ancestorSelectorName, "ancestorSelectorName");
374 return new JcrDescendantNodeJoinCondition(selectorName(ancestorSelectorName), selectorName(descendantSelectorName));
375 }
376
377
378
379
380
381
382
383 @Override
384 public EquiJoinCondition equiJoinCondition( String selector1Name,
385 String property1Name,
386 String selector2Name,
387 String property2Name ) {
388 CheckArg.isNotNull(selector1Name, "selector1Name");
389 CheckArg.isNotNull(property1Name, "property1Name");
390 CheckArg.isNotNull(selector2Name, "selector2Name");
391 CheckArg.isNotNull(selector2Name, "selector2Name");
392 return new JcrEquiJoinCondition(selectorName(selector1Name), property1Name, selectorName(selector2Name), selector2Name);
393 }
394
395
396
397
398
399
400
401 @Override
402 public FullTextSearch fullTextSearch( String selectorName,
403 String propertyName,
404 StaticOperand fullTextSearchExpression ) throws RepositoryException {
405 CheckArg.isNotNull(selectorName, "selectorName");
406 CheckArg.isNotNull(fullTextSearchExpression, "fullTextSearchExpression");
407 return new JcrFullTextSearch(selectorName(selectorName), propertyName, fullTextSearchExpression);
408 }
409
410
411
412
413
414
415 @Override
416 public FullTextSearchScore fullTextSearchScore( String selectorName ) {
417 CheckArg.isNotNull(selectorName, "selectorName");
418 return new JcrFullTextSearchScore(selectorName(selectorName));
419 }
420
421
422
423
424
425
426
427 @Override
428 public Join join( Source left,
429 Source right,
430 String joinType,
431 JoinCondition joinCondition ) {
432 JcrSource leftSource = CheckArg.getInstanceOf(left, JcrSource.class, "left");
433 JcrSource rightSource = CheckArg.getInstanceOf(right, JcrSource.class, "right");
434 JcrJoinCondition jcrJoinCondition = CheckArg.getInstanceOf(joinCondition, JcrJoinCondition.class, "joinCondition");
435 CheckArg.isNotEmpty(joinType, "joinType");
436 joinType = joinType.trim();
437 JoinType type = null;
438 if (QueryObjectModelConstants.JCR_JOIN_TYPE_CROSS.equals(joinType)) type = JoinType.CROSS;
439 else if (QueryObjectModelConstants.JCR_JOIN_TYPE_INNER.equals(joinType)) type = JoinType.INNER;
440 else if (QueryObjectModelConstants.JCR_JOIN_TYPE_FULL_OUTER.equals(joinType)) type = JoinType.FULL_OUTER;
441 else if (QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER.equals(joinType)) type = JoinType.LEFT_OUTER;
442 else if (QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER.equals(joinType)) type = JoinType.RIGHT_OUTER;
443 if (type == null) {
444 throw new IllegalArgumentException("Unknown or unsupported join type: " + joinType);
445 }
446 return new JcrJoin(leftSource, type, rightSource, jcrJoinCondition);
447 }
448
449
450
451
452
453
454 @Override
455 public Length length( PropertyValue propertyValue ) {
456 JcrPropertyValue jcrPropValue = CheckArg.getInstanceOf(propertyValue, JcrPropertyValue.class, "propertyValue");
457 return new JcrLength(jcrPropValue);
458 }
459
460
461
462
463
464
465 @Override
466 public Literal literal( Value literalValue ) throws RepositoryException {
467 CheckArg.isNotNull(literalValue, "literalValue");
468 return new JcrLiteral(literalValue);
469 }
470
471
472
473
474
475
476 @Override
477 public LowerCase lowerCase( DynamicOperand operand ) {
478 JcrDynamicOperand jcrOperand = CheckArg.getInstanceOf(operand, JcrDynamicOperand.class, "operand");
479 return new JcrLowerCase(jcrOperand);
480 }
481
482
483
484
485
486
487 @Override
488 public NodeLocalName nodeLocalName( String selectorName ) {
489 CheckArg.isNotNull(selectorName, "selectorName");
490 return new JcrNodeLocalName(selectorName(selectorName));
491 }
492
493
494
495
496
497
498 @Override
499 public NodeName nodeName( String selectorName ) {
500 CheckArg.isNotNull(selectorName, "selectorName");
501 return new JcrNodeName(selectorName(selectorName));
502 }
503
504
505
506
507
508
509 @Override
510 public Not not( Constraint constraint ) {
511 JcrConstraint jcrConstraint = CheckArg.getInstanceOf(constraint, JcrConstraint.class, "constraint");
512 return new JcrNot(jcrConstraint);
513 }
514
515
516
517
518
519
520 @Override
521 public Or or( Constraint constraint1,
522 Constraint constraint2 ) {
523 JcrConstraint jcrConstraint1 = CheckArg.getInstanceOf(constraint1, JcrConstraint.class, "constraint1");
524 JcrConstraint jcrConstraint2 = CheckArg.getInstanceOf(constraint2, JcrConstraint.class, "constraint2");
525 return new JcrOr(jcrConstraint1, jcrConstraint2);
526 }
527
528
529
530
531
532
533 @Override
534 public PropertyExistence propertyExistence( String selectorName,
535 String propertyName ) {
536 CheckArg.isNotNull(selectorName, "selectorName");
537 CheckArg.isNotNull(propertyName, "propertyName");
538 return new JcrPropertyExistence(selectorName(selectorName), propertyName);
539 }
540
541
542
543
544
545
546 @Override
547 public PropertyValue propertyValue( String selectorName,
548 String propertyName ) {
549 CheckArg.isNotNull(selectorName, "selectorName");
550 CheckArg.isNotNull(propertyName, "propertyName");
551 return new JcrPropertyValue(selectorName(selectorName), propertyName);
552 }
553
554
555
556
557
558
559 @Override
560 public SameNode sameNode( String selectorName,
561 String path ) {
562 CheckArg.isNotNull(selectorName, "selectorName");
563 CheckArg.isNotNull(path, "path");
564 return new JcrSameNode(selectorName(selectorName), path);
565 }
566
567
568
569
570
571
572
573 @Override
574 public SameNodeJoinCondition sameNodeJoinCondition( String selector1Name,
575 String selector2Name,
576 String selector2Path ) {
577 CheckArg.isNotNull(selector1Name, "selector1Name");
578 CheckArg.isNotNull(selector1Name, "selector1Name");
579 return new JcrSameNodeJoinCondition(selectorName(selector1Name), selectorName(selector1Name), selector2Path);
580 }
581
582
583
584
585
586
587 @Override
588 public UpperCase upperCase( DynamicOperand operand ) {
589 JcrDynamicOperand jcrOperand = CheckArg.getInstanceOf(operand, JcrDynamicOperand.class, "operand");
590 return new JcrUpperCase(jcrOperand);
591 }
592
593
594
595
596
597
598 @Override
599 public NodePath nodePath( String selectorName ) {
600 CheckArg.isNotNull(selectorName, "selectorName");
601 return new JcrNodePath(selectorName(selectorName));
602 }
603
604
605
606
607
608
609 @Override
610 public NodeDepth nodeDepth( String selectorName ) {
611 CheckArg.isNotNull(selectorName, "selectorName");
612 return new JcrNodeDepth(selectorName(selectorName));
613 }
614
615
616
617
618
619
620 @Override
621 public Limit limit( int rowLimit,
622 int offset ) {
623 CheckArg.isPositive(rowLimit, "rowLimit");
624 CheckArg.isNonNegative(offset, "offset");
625 return new JcrLimit(rowLimit, offset);
626 }
627
628
629
630
631
632
633
634 @Override
635 public Between between( DynamicOperand operand,
636 StaticOperand lowerBound,
637 StaticOperand upperBound,
638 boolean includeLowerBound,
639 boolean includeUpperBound ) {
640 JcrDynamicOperand jcrOperand = CheckArg.getInstanceOf(operand, JcrDynamicOperand.class, "operand");
641 JcrStaticOperand lower = CheckArg.getInstanceOf(lowerBound, JcrStaticOperand.class, "lowerBound");
642 JcrStaticOperand upper = CheckArg.getInstanceOf(upperBound, JcrStaticOperand.class, "upperBound");
643 return new JcrBetween(jcrOperand, lower, upper, includeLowerBound, includeUpperBound);
644 }
645
646
647
648
649
650
651
652 @Override
653 public SetCriteria in( DynamicOperand operand,
654 StaticOperand... values ) {
655 JcrDynamicOperand jcrOperand = CheckArg.getInstanceOf(operand, JcrDynamicOperand.class, "operand");
656 List<JcrStaticOperand> jcrValues = new ArrayList<JcrStaticOperand>();
657 for (StaticOperand value : values) {
658 JcrStaticOperand jcrValue = CheckArg.getInstanceOf(value, JcrStaticOperand.class, "values");
659 jcrValues.add(jcrValue);
660 }
661 return new JcrSetCriteria(jcrOperand, jcrValues);
662 }
663
664
665
666
667
668
669
670 @Override
671 public ArithmeticOperand add( DynamicOperand left,
672 DynamicOperand right ) {
673 return arithmeticOperand(left, ArithmeticOperator.ADD, right);
674 }
675
676
677
678
679
680
681
682 @Override
683 public ArithmeticOperand subtract( DynamicOperand left,
684 DynamicOperand right ) {
685 return arithmeticOperand(left, ArithmeticOperator.SUBTRACT, right);
686 }
687
688
689
690
691
692
693
694 @Override
695 public ArithmeticOperand multiply( DynamicOperand left,
696 DynamicOperand right ) {
697 return arithmeticOperand(left, ArithmeticOperator.MULTIPLY, right);
698 }
699
700
701
702
703
704
705
706 @Override
707 public ArithmeticOperand divide( DynamicOperand left,
708 DynamicOperand right ) {
709 return arithmeticOperand(left, ArithmeticOperator.DIVIDE, right);
710 }
711
712 public ArithmeticOperand arithmeticOperand( DynamicOperand left,
713 ArithmeticOperator operator,
714 DynamicOperand right ) {
715 JcrDynamicOperand leftOperand = CheckArg.getInstanceOf(left, JcrDynamicOperand.class, "left");
716 JcrDynamicOperand rightOperand = CheckArg.getInstanceOf(left, JcrDynamicOperand.class, "left");
717 return new JcrArithmeticOperand(leftOperand, operator, rightOperand);
718 }
719
720
721
722
723
724
725 @Override
726 public JcrReferenceValue referenceValue( String selectorName ) {
727 return new JcrReferenceValue(selectorName(selectorName), null);
728 }
729
730
731
732
733
734
735 @Override
736 public JcrReferenceValue referenceValue( String selectorName,
737 String propertyName ) {
738 return new JcrReferenceValue(selectorName(selectorName), propertyName);
739 }
740
741 }