1
1
/*
2
- * Copyright 2013-2014 the original author or authors.
2
+ * Copyright 2013-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
22
22
import java .util .List ;
23
23
24
24
import org .springframework .core .GenericTypeResolver ;
25
+ import org .springframework .data .mongodb .core .spel .ConstructorReferenceNode ;
25
26
import org .springframework .data .mongodb .core .spel .ExpressionNode ;
26
27
import org .springframework .data .mongodb .core .spel .ExpressionTransformationContextSupport ;
27
28
import org .springframework .data .mongodb .core .spel .LiteralNode ;
28
29
import org .springframework .data .mongodb .core .spel .MethodReferenceNode ;
30
+ import org .springframework .data .mongodb .core .spel .NotOperatorNode ;
29
31
import org .springframework .data .mongodb .core .spel .OperatorNode ;
30
32
import org .springframework .expression .spel .ExpressionState ;
31
33
import org .springframework .expression .spel .SpelNode ;
32
34
import org .springframework .expression .spel .SpelParserConfiguration ;
33
35
import org .springframework .expression .spel .ast .CompoundExpression ;
34
36
import org .springframework .expression .spel .ast .Indexer ;
35
37
import org .springframework .expression .spel .ast .InlineList ;
38
+ import org .springframework .expression .spel .ast .OperatorNot ;
36
39
import org .springframework .expression .spel .ast .PropertyOrFieldReference ;
37
40
import org .springframework .expression .spel .standard .SpelExpression ;
38
41
import org .springframework .expression .spel .standard .SpelExpressionParser ;
39
42
import org .springframework .expression .spel .support .StandardEvaluationContext ;
40
43
import org .springframework .util .Assert ;
44
+ import org .springframework .util .ClassUtils ;
41
45
import org .springframework .util .NumberUtils ;
42
46
43
47
import com .mongodb .BasicDBList ;
48
52
* Renders the AST of a SpEL expression as a MongoDB Aggregation Framework projection expression.
49
53
*
50
54
* @author Thomas Darimont
55
+ * @author Christoph Strobl
51
56
*/
52
57
class SpelExpressionTransformer implements AggregationExpressionTransformer {
53
58
@@ -69,6 +74,8 @@ public SpelExpressionTransformer() {
69
74
conversions .add (new PropertyOrFieldReferenceNodeConversion (this ));
70
75
conversions .add (new CompoundExpressionNodeConversion (this ));
71
76
conversions .add (new MethodReferenceNodeConversion (this ));
77
+ conversions .add (new NotOperatorrNodeConversion (this ));
78
+ conversions .add (new ConstructorReferenceNodeConversion (this ));
72
79
73
80
this .conversions = Collections .unmodifiableList (conversions );
74
81
}
@@ -131,8 +138,8 @@ private ExpressionNodeConversion<ExpressionNode> lookupConversionFor(ExpressionN
131
138
* @author Thomas Darimont
132
139
* @author Oliver Gierke
133
140
*/
134
- private static abstract class ExpressionNodeConversion <T extends ExpressionNode > implements
135
- AggregationExpressionTransformer {
141
+ private static abstract class ExpressionNodeConversion <T extends ExpressionNode >
142
+ implements AggregationExpressionTransformer {
136
143
137
144
private final AggregationExpressionTransformer transformer ;
138
145
private final Class <? extends ExpressionNode > nodeType ;
@@ -235,8 +242,17 @@ public OperatorNodeConversion(AggregationExpressionTransformer transformer) {
235
242
protected Object convert (AggregationExpressionTransformationContext <OperatorNode > context ) {
236
243
237
244
OperatorNode currentNode = context .getCurrentNode ();
238
-
239
245
DBObject operationObject = createOperationObjectAndAddToPreviousArgumentsIfNecessary (context , currentNode );
246
+
247
+ if (currentNode .isConjunctionOperator ()) {
248
+
249
+ for (ExpressionNode expressionNode : currentNode ) {
250
+ transform (expressionNode , currentNode , operationObject , context );
251
+ }
252
+
253
+ return operationObject ;
254
+ }
255
+
240
256
Object leftResult = transform (currentNode .getLeft (), currentNode , operationObject , context );
241
257
242
258
if (currentNode .isUnaryMinus ()) {
@@ -271,7 +287,8 @@ private DBObject createOperationObjectAndAddToPreviousArgumentsIfNecessary(
271
287
return nextDbObject ;
272
288
}
273
289
274
- private Object convertUnaryMinusOp (ExpressionTransformationContextSupport <OperatorNode > context , Object leftResult ) {
290
+ private Object convertUnaryMinusOp (ExpressionTransformationContextSupport <OperatorNode > context ,
291
+ Object leftResult ) {
275
292
276
293
Object result = leftResult instanceof Number ? leftResult
277
294
: new BasicDBObject ("$multiply" , dbList (-1 , leftResult ));
@@ -289,7 +306,7 @@ private Object convertUnaryMinusOp(ExpressionTransformationContextSupport<Operat
289
306
*/
290
307
@ Override
291
308
protected boolean supports (ExpressionNode node ) {
292
- return node .isMathematicalOperation ();
309
+ return node .isMathematicalOperation () || node . isConjunctionOperator () ;
293
310
}
294
311
}
295
312
@@ -510,4 +527,80 @@ protected boolean supports(ExpressionNode node) {
510
527
return node .isOfType (CompoundExpression .class );
511
528
}
512
529
}
530
+
531
+ /**
532
+ * @author Christoph Strobl
533
+ * @since 1.10
534
+ */
535
+ static class NotOperatorrNodeConversion extends ExpressionNodeConversion <NotOperatorNode > {
536
+
537
+ /**
538
+ * Creates a new {@link ExpressionNodeConversion}.
539
+ *
540
+ * @param transformer must not be {@literal null}.
541
+ */
542
+ public NotOperatorrNodeConversion (AggregationExpressionTransformer transformer ) {
543
+ super (transformer );
544
+ }
545
+
546
+ /*
547
+ * (non-Javadoc)
548
+ * @see org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.SpelNodeWrapper#convertSpelNodeToMongoObjectExpression(org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.ExpressionConversionContext)
549
+ */
550
+ @ Override
551
+ protected Object convert (AggregationExpressionTransformationContext <NotOperatorNode > context ) {
552
+
553
+ NotOperatorNode node = context .getCurrentNode ();
554
+ List <Object > args = new ArrayList <Object >();
555
+
556
+ for (ExpressionNode childNode : node ) {
557
+ args .add (transform (childNode , context ));
558
+ }
559
+
560
+ return context .addToPreviousOrReturn (new BasicDBObject (node .getMongoOperator (), dbList (args .toArray ())));
561
+ }
562
+
563
+ /*
564
+ * (non-Javadoc)
565
+ * @see org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.NodeConversion#supports(org.springframework.data.mongodb.core.spel.ExpressionNode)
566
+ */
567
+ @ Override
568
+ protected boolean supports (ExpressionNode node ) {
569
+ return node .isOfType (OperatorNot .class );
570
+ }
571
+ }
572
+
573
+ /**
574
+ * @author Christoph Strobl
575
+ * @since 1.10
576
+ */
577
+ static class ConstructorReferenceNodeConversion extends ExpressionNodeConversion <ConstructorReferenceNode > {
578
+
579
+ /**
580
+ * Creates a new {@link ExpressionNodeConversion}.
581
+ *
582
+ * @param transformer must not be {@literal null}.
583
+ */
584
+ public ConstructorReferenceNodeConversion (AggregationExpressionTransformer transformer ) {
585
+ super (transformer );
586
+ }
587
+
588
+ /*
589
+ * (non-Javadoc)
590
+ * @see org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.SpelNodeWrapper#convertSpelNodeToMongoObjectExpression(org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.ExpressionConversionContext)
591
+ */
592
+ @ Override
593
+ protected Object convert (AggregationExpressionTransformationContext <ConstructorReferenceNode > context ) {
594
+ return context .getCurrentNode ().getValue ();
595
+ }
596
+
597
+ /*
598
+ * (non-Javadoc)
599
+ * @see org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.NodeConversion#supports(org.springframework.data.mongodb.core.spel.ExpressionNode)
600
+ */
601
+ @ Override
602
+ protected boolean supports (ExpressionNode node ) {
603
+ return ClassUtils .isAssignable (ConstructorReferenceNode .class , node .getClass ());
604
+ }
605
+ }
513
606
}
0 commit comments