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