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.graph.query.model;
25
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.LinkedList;
30 import java.util.Map;
31 import java.util.Set;
32 import org.modeshape.common.util.CheckArg;
33 import org.modeshape.graph.ExecutionContext;
34 import org.modeshape.graph.property.Name;
35 import org.modeshape.graph.property.NamespaceRegistry;
36 import org.modeshape.graph.property.Path;
37
38
39
40
41 public class Visitors {
42
43
44
45
46
47
48
49
50
51
52
53
54 public static <StrategyVisitor extends Visitor> StrategyVisitor visitAll( Visitable visitable,
55 StrategyVisitor strategyVisitor ) {
56 if (visitable != null) visitable.accept(new WalkAllVisitor(strategyVisitor));
57 return strategyVisitor;
58 }
59
60
61
62
63
64
65
66
67
68
69 public static <GeneralVisitor extends Visitor> GeneralVisitor visit( Visitable visitable,
70 GeneralVisitor visitor ) {
71 if (visitable != null) visitable.accept(visitor);
72 return visitor;
73 }
74
75
76
77
78
79
80
81 public static String readable( Visitable visitable ) {
82 return visit(visitable, new ReadableVisitor()).getString();
83 }
84
85
86
87
88
89
90
91 public static Map<SelectorName, SelectorName> getSelectorNamesByAlias( Visitable visitable ) {
92
93 final Map<SelectorName, SelectorName> result = new HashMap<SelectorName, SelectorName>();
94 Visitors.visitAll(visitable, new Visitors.AbstractVisitor() {
95 @Override
96 public void visit( AllNodes allNodes ) {
97 if (allNodes.hasAlias()) {
98 result.put(allNodes.alias(), allNodes.name());
99 }
100 }
101
102 @Override
103 public void visit( NamedSelector selector ) {
104 if (selector.hasAlias()) {
105 result.put(selector.alias(), selector.name());
106 }
107 }
108 });
109 return result;
110 }
111
112
113
114
115
116
117
118 public static Map<SelectorName, SelectorName> getSelectorAliasesByName( Visitable visitable ) {
119
120 final Map<SelectorName, SelectorName> result = new HashMap<SelectorName, SelectorName>();
121 Visitors.visitAll(visitable, new Visitors.AbstractVisitor() {
122 @Override
123 public void visit( AllNodes allNodes ) {
124 if (allNodes.hasAlias()) {
125 result.put(allNodes.name(), allNodes.aliasOrName());
126 }
127 }
128
129 @Override
130 public void visit( NamedSelector selector ) {
131 if (selector.hasAlias()) {
132 result.put(selector.name(), selector.aliasOrName());
133 }
134 }
135 });
136 return result;
137 }
138
139
140
141
142
143
144
145 public static Set<SelectorName> getSelectorsReferencedBy( Visitable visitable ) {
146 final Set<SelectorName> symbols = new HashSet<SelectorName>();
147
148 visitAll(visitable, new AbstractVisitor() {
149 @Override
150 public void visit( AllNodes allNodes ) {
151 if (allNodes.hasAlias()) {
152 symbols.add(allNodes.alias());
153 } else {
154 symbols.add(allNodes.name());
155 }
156 }
157
158 @Override
159 public void visit( ChildNode childNode ) {
160 symbols.add(childNode.selectorName());
161 }
162
163 @Override
164 public void visit( ChildNodeJoinCondition joinCondition ) {
165 symbols.add(joinCondition.childSelectorName());
166 symbols.add(joinCondition.parentSelectorName());
167 }
168
169 @Override
170 public void visit( Column column ) {
171 symbols.add(column.selectorName());
172 }
173
174 @Override
175 public void visit( DescendantNode descendant ) {
176 symbols.add(descendant.selectorName());
177 }
178
179 @Override
180 public void visit( DescendantNodeJoinCondition joinCondition ) {
181 symbols.add(joinCondition.ancestorSelectorName());
182 symbols.add(joinCondition.descendantSelectorName());
183 }
184
185 @Override
186 public void visit( EquiJoinCondition joinCondition ) {
187 symbols.add(joinCondition.selector1Name());
188 symbols.add(joinCondition.selector2Name());
189 }
190
191 @Override
192 public void visit( FullTextSearch fullTextSearch ) {
193 symbols.add(fullTextSearch.selectorName());
194 }
195
196 @Override
197 public void visit( FullTextSearchScore fullTextSearchScore ) {
198 symbols.add(fullTextSearchScore.selectorName());
199 }
200
201 @Override
202 public void visit( Length length ) {
203 symbols.add(length.selectorName());
204 }
205
206 @Override
207 public void visit( NodeDepth depth ) {
208 symbols.add(depth.selectorName());
209 }
210
211 @Override
212 public void visit( NodePath path ) {
213 symbols.add(path.selectorName());
214 }
215
216 @Override
217 public void visit( NodeLocalName node ) {
218 symbols.add(node.selectorName());
219 }
220
221 @Override
222 public void visit( NodeName node ) {
223 symbols.add(node.selectorName());
224 }
225
226 @Override
227 public void visit( NamedSelector node ) {
228 if (node.hasAlias()) {
229 symbols.add(node.alias());
230 } else {
231 symbols.add(node.name());
232 }
233 }
234
235 @Override
236 public void visit( PropertyExistence prop ) {
237 symbols.add(prop.selectorName());
238 }
239
240 @Override
241 public void visit( PropertyValue prop ) {
242 symbols.add(prop.selectorName());
243 }
244
245 @Override
246 public void visit( ReferenceValue ref ) {
247 symbols.add(ref.selectorName());
248 }
249
250 @Override
251 public void visit( SameNode node ) {
252 symbols.add(node.selectorName());
253 }
254
255 @Override
256 public void visit( SameNodeJoinCondition joinCondition ) {
257 symbols.add(joinCondition.selector1Name());
258 symbols.add(joinCondition.selector2Name());
259 }
260 });
261 return symbols;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275 public static class AbstractVisitor implements Visitor {
276
277
278
279
280
281
282 public void visit( AllNodes obj ) {
283 }
284
285
286
287
288
289
290 public void visit( And obj ) {
291 }
292
293
294
295
296
297
298 public void visit( ArithmeticOperand obj ) {
299 }
300
301
302
303
304
305
306 public void visit( Between obj ) {
307 }
308
309
310
311
312
313
314 public void visit( BindVariableName obj ) {
315 }
316
317
318
319
320
321
322 public void visit( ChildNode obj ) {
323 }
324
325
326
327
328
329
330 public void visit( ChildNodeJoinCondition obj ) {
331 }
332
333
334
335
336
337
338 public void visit( Column obj ) {
339 }
340
341
342
343
344
345
346 public void visit( Comparison obj ) {
347 }
348
349
350
351
352
353
354 public void visit( DescendantNode obj ) {
355 }
356
357
358
359
360
361
362 public void visit( DescendantNodeJoinCondition obj ) {
363 }
364
365
366
367
368
369
370 public void visit( EquiJoinCondition obj ) {
371 }
372
373
374
375
376
377
378 public void visit( FullTextSearch obj ) {
379 }
380
381
382
383
384
385
386 public void visit( FullTextSearchScore obj ) {
387 }
388
389
390
391
392
393
394 public void visit( Join obj ) {
395 }
396
397
398
399
400
401
402 public void visit( Length obj ) {
403 }
404
405
406
407
408
409
410 public void visit( Limit limit ) {
411 }
412
413
414
415
416
417
418 public void visit( Literal obj ) {
419 }
420
421
422
423
424
425
426 public void visit( LowerCase obj ) {
427 }
428
429
430
431
432
433
434 public void visit( NodeDepth obj ) {
435 }
436
437
438
439
440
441
442 public void visit( NodePath obj ) {
443 }
444
445
446
447
448
449
450 public void visit( NodeName obj ) {
451 }
452
453
454
455
456
457
458 public void visit( NodeLocalName obj ) {
459 }
460
461
462
463
464
465
466 public void visit( NamedSelector obj ) {
467 }
468
469
470
471
472
473
474 public void visit( Not obj ) {
475 }
476
477
478
479
480
481
482 public void visit( Or obj ) {
483 }
484
485
486
487
488
489
490 public void visit( Ordering obj ) {
491 }
492
493
494
495
496
497
498 public void visit( PropertyExistence obj ) {
499 }
500
501
502
503
504
505
506 public void visit( PropertyValue obj ) {
507 }
508
509
510
511
512
513
514 public void visit( Query obj ) {
515 }
516
517
518
519
520
521
522 public void visit( ReferenceValue obj ) {
523 }
524
525
526
527
528
529
530 public void visit( SameNode obj ) {
531 }
532
533
534
535
536
537
538 public void visit( SameNodeJoinCondition obj ) {
539 }
540
541
542
543
544
545
546 public void visit( SetCriteria obj ) {
547 }
548
549
550
551
552
553
554 public void visit( SetQuery obj ) {
555 }
556
557
558
559
560
561
562 public void visit( UpperCase obj ) {
563 }
564 }
565
566
567
568
569
570
571
572
573
574
575
576
577 public static abstract class NavigationVisitor implements Visitor {
578 protected final Visitor strategy;
579 private final LinkedList<? super Visitable> itemQueue = new LinkedList<Visitable>();
580
581
582
583
584
585
586 protected NavigationVisitor( Visitor strategy ) {
587 assert strategy != null;
588 this.strategy = strategy;
589 }
590
591 protected final void enqueue( Visitable objectToBeVisited ) {
592 if (objectToBeVisited != null) {
593 itemQueue.add(objectToBeVisited);
594 }
595 }
596
597 protected final void enqueue( Iterable<? extends Visitable> objectsToBeVisited ) {
598 for (Visitable objectToBeVisited : objectsToBeVisited) {
599 if (objectToBeVisited != null) {
600 itemQueue.add(objectToBeVisited);
601 }
602 }
603 }
604
605 protected final void visitNext() {
606 if (!itemQueue.isEmpty()) {
607 Visitable first = (Visitable)itemQueue.removeFirst();
608 assert first != null;
609 first.accept(this);
610 }
611 }
612 }
613
614
615
616
617
618 public static class WalkAllVisitor extends NavigationVisitor {
619
620
621
622
623
624
625 protected WalkAllVisitor( Visitor strategy ) {
626 super(strategy);
627 }
628
629
630
631
632
633
634 public void visit( AllNodes allNodes ) {
635 strategy.visit(allNodes);
636 visitNext();
637 }
638
639
640
641
642
643
644 public void visit( And and ) {
645 strategy.visit(and);
646 enqueue(and.left());
647 enqueue(and.right());
648 visitNext();
649 }
650
651
652
653
654
655
656 public void visit( ArithmeticOperand arithmeticOperation ) {
657 strategy.visit(arithmeticOperation);
658 enqueue(arithmeticOperation.left());
659 enqueue(arithmeticOperation.right());
660 visitNext();
661 }
662
663
664
665
666
667
668 public void visit( Between between ) {
669 strategy.visit(between);
670 enqueue(between.operand());
671 enqueue(between.lowerBound());
672 enqueue(between.upperBound());
673 visitNext();
674 }
675
676
677
678
679
680
681 public void visit( BindVariableName variableName ) {
682 strategy.visit(variableName);
683 visitNext();
684 }
685
686
687
688
689
690
691 public void visit( ChildNode child ) {
692 strategy.visit(child);
693 visitNext();
694 }
695
696
697
698
699
700
701 public void visit( ChildNodeJoinCondition joinCondition ) {
702 strategy.visit(joinCondition);
703 visitNext();
704 }
705
706
707
708
709
710
711 public void visit( Column column ) {
712 strategy.visit(column);
713 visitNext();
714 }
715
716
717
718
719
720
721 public void visit( Comparison comparison ) {
722 strategy.visit(comparison);
723 enqueue(comparison.operand1());
724 enqueue(comparison.operand2());
725 visitNext();
726 }
727
728
729
730
731
732
733 public void visit( DescendantNode descendant ) {
734 strategy.visit(descendant);
735 visitNext();
736 }
737
738
739
740
741
742
743 public void visit( DescendantNodeJoinCondition condition ) {
744 strategy.visit(condition);
745 visitNext();
746 }
747
748
749
750
751
752
753 public void visit( EquiJoinCondition condition ) {
754 strategy.visit(condition);
755 visitNext();
756 }
757
758
759
760
761
762
763 public void visit( FullTextSearch fullTextSearch ) {
764 strategy.visit(fullTextSearch);
765 visitNext();
766 }
767
768
769
770
771
772
773 public void visit( FullTextSearchScore score ) {
774 strategy.visit(score);
775 visitNext();
776 }
777
778
779
780
781
782
783 public void visit( Join join ) {
784 strategy.visit(join);
785 enqueue(join.left());
786 enqueue(join.joinCondition());
787 enqueue(join.right());
788 visitNext();
789 }
790
791
792
793
794
795
796 public void visit( Length length ) {
797 strategy.visit(length);
798 visitNext();
799 }
800
801
802
803
804
805
806 public void visit( Limit limit ) {
807 strategy.visit(limit);
808 visitNext();
809 }
810
811
812
813
814
815
816 public void visit( Literal literal ) {
817 strategy.visit(literal);
818 visitNext();
819 }
820
821
822
823
824
825
826 public void visit( LowerCase lowerCase ) {
827 strategy.visit(lowerCase);
828 enqueue(lowerCase.operand());
829 visitNext();
830 }
831
832
833
834
835
836
837 public void visit( NodeDepth depth ) {
838 strategy.visit(depth);
839 visitNext();
840 }
841
842
843
844
845
846
847 public void visit( NodePath path ) {
848 strategy.visit(path);
849 visitNext();
850 }
851
852
853
854
855
856
857 public void visit( NodeName nodeName ) {
858 strategy.visit(nodeName);
859 visitNext();
860 }
861
862
863
864
865
866
867 public void visit( NodeLocalName nodeLocalName ) {
868 strategy.visit(nodeLocalName);
869 visitNext();
870 }
871
872
873
874
875
876
877 public void visit( NamedSelector selector ) {
878 strategy.visit(selector);
879 visitNext();
880 }
881
882
883
884
885
886
887 public void visit( Not not ) {
888 strategy.visit(not);
889 enqueue(not.constraint());
890 visitNext();
891 }
892
893
894
895
896
897
898 public void visit( Or or ) {
899 strategy.visit(or);
900 enqueue(or.left());
901 enqueue(or.right());
902 visitNext();
903 }
904
905
906
907
908
909
910 public void visit( Ordering ordering ) {
911 strategy.visit(ordering);
912 enqueue(ordering.operand());
913 visitNext();
914 }
915
916
917
918
919
920
921 public void visit( PropertyExistence existence ) {
922 strategy.visit(existence);
923 visitNext();
924 }
925
926
927
928
929
930
931 public void visit( PropertyValue propertyValue ) {
932 strategy.visit(propertyValue);
933 visitNext();
934 }
935
936
937
938
939
940
941 public void visit( Query query ) {
942 strategy.visit(query);
943 enqueue(query.source());
944 enqueue(query.columns());
945 enqueue(query.constraint());
946 enqueue(query.orderings());
947 visitNext();
948 }
949
950
951
952
953
954
955 public void visit( ReferenceValue referenceValue ) {
956 strategy.visit(referenceValue);
957 visitNext();
958 }
959
960
961
962
963
964
965 public void visit( SameNode sameNode ) {
966 strategy.visit(sameNode);
967 visitNext();
968 }
969
970
971
972
973
974
975 public void visit( SameNodeJoinCondition condition ) {
976 strategy.visit(condition);
977 visitNext();
978 }
979
980
981
982
983
984
985 public void visit( SetCriteria setCriteria ) {
986 strategy.visit(setCriteria);
987 enqueue(setCriteria.leftOperand());
988 for (StaticOperand right : setCriteria.rightOperands()) {
989 enqueue(right);
990 }
991 visitNext();
992 }
993
994
995
996
997
998
999 public void visit( SetQuery setQuery ) {
1000 strategy.visit(setQuery);
1001 enqueue(setQuery.left());
1002 enqueue(setQuery.right());
1003 visitNext();
1004 }
1005
1006
1007
1008
1009
1010
1011 public void visit( UpperCase upperCase ) {
1012 strategy.visit(upperCase);
1013 enqueue(upperCase.operand());
1014 visitNext();
1015 }
1016 }
1017
1018 public static class ReadableVisitor implements Visitor {
1019 private final StringBuilder sb = new StringBuilder();
1020 private final ExecutionContext context;
1021 private final NamespaceRegistry registry;
1022
1023 public ReadableVisitor( ExecutionContext context ) {
1024 CheckArg.isNotNull(context, "context");
1025 this.context = context;
1026 this.registry = context == null ? null : context.getNamespaceRegistry();
1027 }
1028
1029 public ReadableVisitor() {
1030 this.context = null;
1031 this.registry = null;
1032 }
1033
1034 protected final ReadableVisitor append( String string ) {
1035 sb.append(string);
1036 return this;
1037 }
1038
1039 protected final ReadableVisitor append( char character ) {
1040 sb.append(character);
1041 return this;
1042 }
1043
1044 protected final ReadableVisitor append( int value ) {
1045 sb.append(value);
1046 return this;
1047 }
1048
1049 protected final ReadableVisitor append( SelectorName name ) {
1050 sb.append(name.getString());
1051 return this;
1052 }
1053
1054 protected final ReadableVisitor append( Name name ) {
1055 sb.append(name.getString(registry, null, null));
1056 return this;
1057 }
1058
1059 protected final ReadableVisitor append( Path path ) {
1060 sb.append('\'');
1061 sb.append(path.getString(registry));
1062 sb.append('\'');
1063 return this;
1064 }
1065
1066
1067
1068
1069 public final ExecutionContext getContext() {
1070 return context;
1071 }
1072
1073
1074
1075
1076
1077
1078 public final String getString() {
1079 return sb.toString();
1080 }
1081
1082
1083
1084
1085
1086
1087 @Override
1088 public String toString() {
1089 return sb.toString();
1090 }
1091
1092
1093
1094
1095
1096
1097 public void visit( AllNodes allNodes ) {
1098 append(allNodes.name());
1099 if (allNodes.hasAlias()) {
1100 append(" AS ").append(allNodes.alias());
1101 }
1102 }
1103
1104
1105
1106
1107
1108
1109 public void visit( And and ) {
1110 append('(');
1111 and.left().accept(this);
1112 append(" AND ");
1113 and.right().accept(this);
1114 append(')');
1115 }
1116
1117
1118
1119
1120
1121
1122 public void visit( ArithmeticOperand arithmeticOperand ) {
1123 append('(');
1124 arithmeticOperand.left().accept(this);
1125 append(' ');
1126 append(arithmeticOperand.operator().symbol());
1127 append(' ');
1128 arithmeticOperand.right().accept(this);
1129 append(')');
1130 }
1131
1132
1133
1134
1135
1136
1137 public void visit( Between between ) {
1138 between.operand().accept(this);
1139 append(" BETWEEN ");
1140 between.lowerBound().accept(this);
1141 if (!between.isLowerBoundIncluded()) append(" EXCLUSIVE");
1142 append(" AND ");
1143 between.upperBound().accept(this);
1144 if (!between.isUpperBoundIncluded()) append(" EXCLUSIVE");
1145 }
1146
1147
1148
1149
1150
1151
1152 public void visit( BindVariableName variable ) {
1153 append('$').append(variable.variableName());
1154 }
1155
1156
1157
1158
1159
1160
1161 public void visit( ChildNode child ) {
1162 append("ISCHILDNODE(");
1163 append(child.selectorName());
1164 append(',');
1165 append(child.parentPath());
1166 append(')');
1167 }
1168
1169
1170
1171
1172
1173
1174 public void visit( ChildNodeJoinCondition condition ) {
1175 append("ISCHILDNODE(");
1176 append(condition.childSelectorName());
1177 append(',');
1178 append(condition.parentSelectorName());
1179 append(')');
1180 }
1181
1182
1183
1184
1185
1186
1187 public void visit( Column column ) {
1188 append(column.selectorName());
1189 if (column.propertyName() == null) {
1190 append(".*");
1191 } else {
1192 String propertyName = column.propertyName();
1193 append('.').append(propertyName);
1194 if (!propertyName.equals(column.columnName()) && !propertyName.equals(column.columnName())) {
1195 append(" AS ").append(column.columnName());
1196 }
1197 }
1198 }
1199
1200
1201
1202
1203
1204
1205 public void visit( Comparison comparison ) {
1206 comparison.operand1().accept(this);
1207 append(' ').append(comparison.operator().symbol()).append(' ');
1208 comparison.operand2().accept(this);
1209 }
1210
1211
1212
1213
1214
1215
1216 public void visit( DescendantNode descendant ) {
1217 append("ISDESCENDANTNODE(");
1218 append(descendant.selectorName());
1219 append(',');
1220 append(descendant.ancestorPath());
1221 append(')');
1222 }
1223
1224
1225
1226
1227
1228
1229 public void visit( DescendantNodeJoinCondition condition ) {
1230 append("ISDESCENDANTNODE(");
1231 append(condition.descendantSelectorName());
1232 append(',');
1233 append(condition.ancestorSelectorName());
1234 append(')');
1235 }
1236
1237
1238
1239
1240
1241
1242 public void visit( EquiJoinCondition condition ) {
1243 append(condition.selector1Name()).append('.').append(condition.property1Name());
1244 append(" = ");
1245 append(condition.selector2Name()).append('.').append(condition.property2Name());
1246 }
1247
1248
1249
1250
1251
1252
1253 public void visit( FullTextSearch fullText ) {
1254 append("CONTAINS(").append(fullText.selectorName());
1255 if (fullText.propertyName() != null) {
1256 append('.').append(fullText.propertyName());
1257 }
1258 sb.append(",'").append(fullText.fullTextSearchExpression()).append("')");
1259 }
1260
1261
1262
1263
1264
1265
1266 public void visit( FullTextSearchScore score ) {
1267 append("SCORE(").append(score.selectorName()).append(')');
1268 }
1269
1270
1271
1272
1273
1274
1275 public void visit( Join join ) {
1276 join.left().accept(this);
1277
1278 sb.append(' ').append(join.type().symbol());
1279
1280
1281
1282 append(' ');
1283 join.right().accept(this);
1284 append(" ON ");
1285 join.joinCondition().accept(this);
1286 }
1287
1288
1289
1290
1291
1292
1293 public void visit( Length length ) {
1294 append("LENGTH(");
1295 length.propertyValue().accept(this);
1296 append(')');
1297 }
1298
1299
1300
1301
1302
1303
1304 public void visit( Limit limit ) {
1305 append("LIMIT ").append(limit.rowLimit());
1306 if (limit.offset() != 0) {
1307 append(" OFFSET ").append(limit.offset());
1308 }
1309 }
1310
1311
1312
1313
1314
1315
1316 public void visit( Literal literal ) {
1317 Object value = literal.value();
1318 boolean quote = value instanceof String || value instanceof Path || value instanceof Name;
1319 if (quote) append('\'');
1320 if (context == null) {
1321 append(literal.value().toString());
1322 } else {
1323 append(context.getValueFactories().getStringFactory().create(literal.value()));
1324 }
1325 if (quote) append('\'');
1326 }
1327
1328
1329
1330
1331
1332
1333 public void visit( LowerCase lowerCase ) {
1334 append("LOWER(");
1335 lowerCase.operand().accept(this);
1336 append(')');
1337 }
1338
1339
1340
1341
1342
1343
1344 public void visit( NodeDepth depth ) {
1345 append("DEPTH(").append(depth.selectorName()).append(')');
1346 }
1347
1348
1349
1350
1351
1352
1353 public void visit( NodePath path ) {
1354 append("PATH(").append(path.selectorName()).append(')');
1355 }
1356
1357
1358
1359
1360
1361
1362 public void visit( NodeLocalName name ) {
1363 append("LOCALNAME(").append(name.selectorName()).append(')');
1364 }
1365
1366
1367
1368
1369
1370
1371 public void visit( NodeName name ) {
1372 append("NAME(").append(name.selectorName()).append(')');
1373 }
1374
1375
1376
1377
1378
1379
1380 public void visit( NamedSelector selector ) {
1381 append(selector.name());
1382 if (selector.hasAlias()) {
1383 append(" AS ").append(selector.alias());
1384 }
1385 }
1386
1387
1388
1389
1390
1391
1392 public void visit( Not not ) {
1393 append('(');
1394 append("NOT ");
1395 not.constraint().accept(this);
1396 append(')');
1397 }
1398
1399
1400
1401
1402
1403
1404 public void visit( Or or ) {
1405 append('(');
1406 or.left().accept(this);
1407 append(" OR ");
1408 or.right().accept(this);
1409 append(')');
1410 }
1411
1412
1413
1414
1415
1416
1417 public void visit( Ordering ordering ) {
1418 ordering.operand().accept(this);
1419 append(' ').append(ordering.order().symbol());
1420 }
1421
1422
1423
1424
1425
1426
1427 public void visit( PropertyExistence existence ) {
1428 append(existence.selectorName()).append('.').append(existence.propertyName()).append(" IS NOT NULL");
1429 }
1430
1431
1432
1433
1434
1435
1436 public void visit( PropertyValue value ) {
1437 append(value.selectorName()).append('.').append(value.propertyName());
1438 }
1439
1440
1441
1442
1443
1444
1445 public void visit( ReferenceValue value ) {
1446 append(value.selectorName());
1447 if (value.propertyName() != null) {
1448 append('.').append(value.propertyName());
1449 }
1450 }
1451
1452
1453
1454
1455
1456
1457 public void visit( Query query ) {
1458 append("SELECT ");
1459 if (query.isDistinct()) append("DISTINCT ");
1460 if (query.columns().isEmpty()) {
1461 append('*');
1462 } else {
1463 boolean isFirst = true;
1464 for (Column column : query.columns()) {
1465 if (isFirst) isFirst = false;
1466 else append(',');
1467 column.accept(this);
1468 }
1469 }
1470 append(" FROM ");
1471 query.source().accept(this);
1472 if (query.constraint() != null) {
1473 append(" WHERE ");
1474 query.constraint().accept(this);
1475 }
1476 if (!query.orderings().isEmpty()) {
1477 append(" ORDER BY ");
1478 boolean isFirst = true;
1479 for (Ordering ordering : query.orderings()) {
1480 if (isFirst) isFirst = false;
1481 else append(',');
1482 ordering.accept(this);
1483 }
1484 }
1485 if (!query.limits().isUnlimited()) {
1486 append(' ');
1487 query.limits().accept(this);
1488 }
1489 }
1490
1491
1492
1493
1494
1495
1496 public void visit( SameNode sameNode ) {
1497 append("ISSAMENODE(").append(sameNode.selectorName()).append(',').append(sameNode.path()).append(')');
1498 }
1499
1500
1501
1502
1503
1504
1505 public void visit( SameNodeJoinCondition condition ) {
1506 append("ISSAMENODE(").append(condition.selector1Name()).append(',').append(condition.selector2Name());
1507 if (condition.selector2Path() != null) {
1508 append(',').append(condition.selector2Path());
1509 }
1510 append(')');
1511 }
1512
1513
1514
1515
1516
1517
1518 public void visit( SetCriteria criteria ) {
1519 criteria.leftOperand().accept(this);
1520 append(" IN (");
1521 Iterator<? extends StaticOperand> iter = criteria.rightOperands().iterator();
1522 if (iter.hasNext()) {
1523 iter.next().accept(this);
1524 while (iter.hasNext()) {
1525 append(',');
1526 iter.next().accept(this);
1527 }
1528 }
1529 append(')');
1530 }
1531
1532
1533
1534
1535
1536
1537 public void visit( SetQuery query ) {
1538 query.left().accept(this);
1539 append(' ').append(query.operation().getSymbol()).append(' ');
1540 if (query.isAll()) append("ALL ");
1541 query.right().accept(this);
1542 }
1543
1544
1545
1546
1547
1548
1549 public void visit( UpperCase upperCase ) {
1550 append("UPPER(");
1551 upperCase.operand().accept(this);
1552 append(')');
1553 }
1554
1555 }
1556 }