1 /***************************************************************************************
2 * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3 * http://aspectwerkz.codehaus.org *
4 * ---------------------------------------------------------------------------------- *
5 * The software in this package is published under the terms of the LGPL license *
6 * a copy of which has been included with this distribution in the license.txt file. *
7 **************************************************************************************/
8 package org.codehaus.aspectwerkz.expression;
9
10 import org.codehaus.aspectwerkz.annotation.AnnotationInfo;
11 import org.codehaus.aspectwerkz.expression.ast.ASTAnd;
12 import org.codehaus.aspectwerkz.expression.ast.ASTAttribute;
13 import org.codehaus.aspectwerkz.expression.ast.ASTCall;
14 import org.codehaus.aspectwerkz.expression.ast.ASTCflow;
15 import org.codehaus.aspectwerkz.expression.ast.ASTCflowBelow;
16 import org.codehaus.aspectwerkz.expression.ast.ASTClassPattern;
17 import org.codehaus.aspectwerkz.expression.ast.ASTConstructorPattern;
18 import org.codehaus.aspectwerkz.expression.ast.ASTExecution;
19 import org.codehaus.aspectwerkz.expression.ast.ASTExpression;
20 import org.codehaus.aspectwerkz.expression.ast.ASTFieldPattern;
21 import org.codehaus.aspectwerkz.expression.ast.ASTGet;
22 import org.codehaus.aspectwerkz.expression.ast.ASTHandler;
23 import org.codehaus.aspectwerkz.expression.ast.ASTMethodPattern;
24 import org.codehaus.aspectwerkz.expression.ast.ASTModifier;
25 import org.codehaus.aspectwerkz.expression.ast.ASTNot;
26 import org.codehaus.aspectwerkz.expression.ast.ASTOr;
27 import org.codehaus.aspectwerkz.expression.ast.ASTParameter;
28 import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference;
29 import org.codehaus.aspectwerkz.expression.ast.ASTRoot;
30 import org.codehaus.aspectwerkz.expression.ast.ASTSet;
31 import org.codehaus.aspectwerkz.expression.ast.ASTStaticInitialization;
32 import org.codehaus.aspectwerkz.expression.ast.ASTWithin;
33 import org.codehaus.aspectwerkz.expression.ast.ASTWithinCode;
34 import org.codehaus.aspectwerkz.expression.ast.ExpressionParserVisitor;
35 import org.codehaus.aspectwerkz.expression.ast.Node;
36 import org.codehaus.aspectwerkz.expression.ast.SimpleNode;
37 import org.codehaus.aspectwerkz.expression.ast.ASTArgs;
38 import org.codehaus.aspectwerkz.expression.ast.ASTArgParameter;
39 import org.codehaus.aspectwerkz.expression.regexp.TypePattern;
40 import org.codehaus.aspectwerkz.reflect.ClassInfo;
41 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper;
42 import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
43 import org.codehaus.aspectwerkz.reflect.FieldInfo;
44 import org.codehaus.aspectwerkz.reflect.MemberInfo;
45 import org.codehaus.aspectwerkz.reflect.MethodInfo;
46 import org.codehaus.aspectwerkz.reflect.ReflectionInfo;
47
48 import java.lang.reflect.Modifier;
49 import java.util.ArrayList;
50 import java.util.Iterator;
51 import java.util.List;
52 import org.codehaus.aspectwerkz.expression.ast.ASTHasField;
53 import org.codehaus.aspectwerkz.expression.ast.ASTHasMethod;
54
55 /***
56 * The expression visitor.
57 *
58 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
59 * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
60 * @author Michael Nascimento
61 */
62 public class ExpressionVisitor implements ExpressionParserVisitor {
63
64 protected ASTRoot m_root;
65 protected String m_expression;
66 protected String m_namespace;
67
68 /***
69 * The expressionInfo this visitor is built on for expression with signature Caution: Can be null for visitor that
70 * don't need this information.
71 */
72 protected ExpressionInfo m_expressionInfo;
73
74 /***
75 * Creates a new expression.
76 *
77 * @param expressionInfo the expressionInfo this visitor is built on for expression with signature
78 * @param expression the expression as a string
79 * @param namespace the namespace
80 * @param root the AST root
81 */
82 public ExpressionVisitor(final ExpressionInfo expressionInfo,
83 final String expression,
84 final String namespace,
85 final ASTRoot root) {
86 m_expressionInfo = expressionInfo;
87 m_expression = expression;
88 m_namespace = namespace;
89 m_root = root;
90 }
91
92 /***
93 * Matches the expression context.
94 *
95 * @param context
96 * @return
97 */
98 public boolean match(final ExpressionContext context) {
99 return ((Boolean) visit(m_root, context)).booleanValue();
100 }
101
102
103 public Object visit(SimpleNode node, Object data) {
104 return node.jjtGetChild(0).jjtAccept(this, data);
105 }
106
107 public Object visit(ASTRoot node, Object data) {
108 return node.jjtGetChild(0).jjtAccept(this, data);
109 }
110
111 public Object visit(ASTExpression node, Object data) {
112 return node.jjtGetChild(0).jjtAccept(this, data);
113 }
114
115
116 public Object visit(ASTOr node, Object data) {
117 int nrOfChildren = node.jjtGetNumChildren();
118 for (int i = 0; i < nrOfChildren; i++) {
119 Boolean match = (Boolean) node.jjtGetChild(i).jjtAccept(this, data);
120 if (match.equals(Boolean.TRUE)) {
121 return Boolean.TRUE;
122 }
123 }
124 return Boolean.FALSE;
125 }
126
127 public Object visit(ASTAnd node, Object data) {
128 int nrOfChildren = node.jjtGetNumChildren();
129 for (int i = 0; i < nrOfChildren; i++) {
130 Boolean match = (Boolean) node.jjtGetChild(i).jjtAccept(this, data);
131 if (match.equals(Boolean.FALSE)) {
132 return Boolean.FALSE;
133 }
134 }
135 return Boolean.TRUE;
136 }
137
138 public Object visit(ASTNot node, Object data) {
139 Node child = node.jjtGetChild(0);
140 Boolean match = (Boolean) child.jjtAccept(this, data);
141 if (child instanceof ASTCflow || child instanceof ASTCflowBelow) {
142 return match;
143 } else {
144 if (match.equals(Boolean.TRUE)) {
145 return Boolean.FALSE;
146 } else {
147 return Boolean.TRUE;
148 }
149 }
150 }
151
152
153 public Object visit(ASTPointcutReference node, Object data) {
154 ExpressionContext context = (ExpressionContext) data;
155 ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace);
156 ExpressionVisitor expression = namespace.getExpression(node.getName());
157 return new Boolean(expression.match(context));
158 }
159
160 public Object visit(ASTExecution node, Object data) {
161 ExpressionContext context = (ExpressionContext) data;
162 if (context.hasExecutionPointcut() && (context.hasMethodInfo() || context.hasConstructorInfo())) {
163 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo());
164 } else {
165 return Boolean.FALSE;
166 }
167 }
168
169 public Object visit(ASTCall node, Object data) {
170 ExpressionContext context = (ExpressionContext) data;
171 if (context.hasCallPointcut() && (context.hasMethodInfo() || context.hasConstructorInfo())) {
172 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo());
173 } else {
174 return Boolean.FALSE;
175 }
176 }
177
178 public Object visit(ASTSet node, Object data) {
179 ExpressionContext context = (ExpressionContext) data;
180 if (context.hasSetPointcut() && context.hasFieldInfo()) {
181 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo());
182 } else {
183 return Boolean.FALSE;
184 }
185 }
186
187 public Object visit(ASTGet node, Object data) {
188 ExpressionContext context = (ExpressionContext) data;
189 if (context.hasGetPointcut() && context.hasFieldInfo()) {
190 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo());
191 } else {
192 return Boolean.FALSE;
193 }
194 }
195
196 public Object visit(ASTHandler node, Object data) {
197 ExpressionContext context = (ExpressionContext) data;
198 if (context.hasHandlerPointcut() && context.hasClassInfo()) {
199 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo());
200 } else {
201 return Boolean.FALSE;
202 }
203 }
204
205 public Object visit(ASTStaticInitialization node, Object data) {
206 ExpressionContext context = (ExpressionContext) data;
207 if (context.hasStaticInitializationPointcut() && context.hasClassInfo()) {
208 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo());
209 } else {
210 return Boolean.FALSE;
211 }
212 }
213
214 public Object visit(ASTWithin node, Object data) {
215 ExpressionContext context = (ExpressionContext) data;
216 if (context.hasWithinReflectionInfo()) {
217 ReflectionInfo withinInfo = context.getWithinReflectionInfo();
218 if (withinInfo instanceof MemberInfo) {
219 return node.jjtGetChild(0).jjtAccept(this, ((MemberInfo) withinInfo).getDeclaringType());
220 } else if (withinInfo instanceof ClassInfo) {
221 return node.jjtGetChild(0).jjtAccept(this, withinInfo);
222 }
223 }
224 return Boolean.FALSE;
225 }
226
227 public Object visit(ASTWithinCode node, Object data) {
228 ExpressionContext context = (ExpressionContext) data;
229 if (context.hasWithinReflectionInfo()) {
230 return node.jjtGetChild(0).jjtAccept(this, context.getWithinReflectionInfo());
231 } else {
232 return Boolean.FALSE;
233 }
234 }
235
236
237 public Object visit(ASTHasMethod node, Object data) {
238 ExpressionContext context = (ExpressionContext) data;
239
240
241
242 ReflectionInfo info = context.getWithinReflectionInfo();
243 ClassInfo classInfo = (info instanceof MemberInfo) ?
244 ((MemberInfo)info).getDeclaringType() : (ClassInfo)info;
245
246 Node childNode = node.jjtGetChild(0);
247 MethodInfo[] methodInfos = classInfo.getMethods();
248 for (int i = 0; i < methodInfos.length; i++) {
249 if (Boolean.TRUE.equals(childNode.jjtAccept(this, methodInfos[i]))) {
250 return Boolean.TRUE;
251 }
252 }
253
254 ConstructorInfo[] constructorInfos = classInfo.getConstructors();
255 for (int i = 0; i < constructorInfos.length; i++) {
256 if (Boolean.TRUE.equals(childNode.jjtAccept(this, constructorInfos[i]))) {
257 return Boolean.TRUE;
258 }
259 }
260
261 return Boolean.FALSE;
262 }
263
264 public Object visit(ASTHasField node, Object data) {
265 ExpressionContext context = (ExpressionContext) data;
266
267
268
269 ReflectionInfo info = context.getWithinReflectionInfo();
270 ClassInfo classInfo = (info instanceof MemberInfo) ?
271 ((MemberInfo)info).getDeclaringType() : (ClassInfo)info;
272
273 Node childNode = node.jjtGetChild(0);
274 FieldInfo[] fieldInfos = classInfo.getFields();
275 for (int i = 0; i < fieldInfos.length; i++) {
276 if (Boolean.TRUE.equals(childNode.jjtAccept(this, fieldInfos[i]))) {
277 return Boolean.TRUE;
278 }
279 }
280
281 return Boolean.FALSE;
282 }
283
284 public Object visit(ASTCflow node, Object data) {
285 return Boolean.TRUE;
286 }
287
288 public Object visit(ASTCflowBelow node, Object data) {
289 return Boolean.TRUE;
290 }
291
292
293 public Object visit(ASTClassPattern node, Object data) {
294 ClassInfo classInfo = (ClassInfo) data;
295 TypePattern typePattern = node.getTypePattern();
296 if (ClassInfoHelper.matchType(typePattern, classInfo)
297 && visitAttributes(node, classInfo)
298 && visitModifiers(node, classInfo)) {
299 return Boolean.TRUE;
300 } else {
301 return Boolean.FALSE;
302 }
303 }
304
305 public Object visit(ASTMethodPattern node, Object data) {
306 if (data instanceof MethodInfo) {
307 MethodInfo methodInfo = (MethodInfo) data;
308 if (node.getMethodNamePattern().matches(methodInfo.getName())
309 && ClassInfoHelper.matchType(node.getDeclaringTypePattern(), methodInfo.getDeclaringType())
310 && ClassInfoHelper.matchType(node.getReturnTypePattern(), methodInfo.getReturnType())
311 && visitAttributes(node, methodInfo)
312 && visitModifiers(node, methodInfo)
313 && visitParameters(node, methodInfo.getParameterTypes())) {
314 return Boolean.TRUE;
315 }
316 }
317
318 return Boolean.FALSE;
319 }
320
321 public Object visit(ASTConstructorPattern node, Object data) {
322 if (data instanceof ConstructorInfo) {
323 ConstructorInfo constructorMetaData = (ConstructorInfo) data;
324 if (ClassInfoHelper.matchType(node.getDeclaringTypePattern(), constructorMetaData.getDeclaringType())
325 && visitAttributes(node, constructorMetaData)
326 && visitModifiers(node, constructorMetaData)
327 && visitParameters(node, constructorMetaData.getParameterTypes())) {
328 return Boolean.TRUE;
329 }
330 }
331 return Boolean.FALSE;
332 }
333
334 public Object visit(ASTFieldPattern node, Object data) {
335 if (data instanceof FieldInfo) {
336 FieldInfo fieldInfo = (FieldInfo) data;
337 if (node.getFieldNamePattern().matches(fieldInfo.getName())
338 && ClassInfoHelper.matchType(node.getDeclaringTypePattern(), fieldInfo.getDeclaringType())
339 && ClassInfoHelper.matchType(node.getFieldTypePattern(), fieldInfo.getType())
340 && visitAttributes(node, fieldInfo)
341 && visitModifiers(node, fieldInfo)) {
342 return Boolean.TRUE;
343 }
344 }
345 return Boolean.FALSE;
346 }
347
348 public Object visit(ASTParameter node, Object data) {
349 ClassInfo parameterType = (ClassInfo) data;
350 if (ClassInfoHelper.matchType(node.getDeclaringClassPattern(), parameterType)) {
351 return Boolean.TRUE;
352 } else {
353 return Boolean.FALSE;
354 }
355 }
356
357 public Object visit(ASTArgs node, Object data) {
358 ExpressionContext ctx = (ExpressionContext) data;
359 if (node.jjtGetNumChildren() <= 0) {
360
361 return (getParametersCount(ctx) == 0) ? Boolean.TRUE : Boolean.FALSE;
362 } else {
363
364 int expressionParameterCount = node.jjtGetNumChildren();
365 boolean isFirstArgEager = ((ASTArgParameter) node.jjtGetChild(0)).getTypePattern().isEagerWildCard();
366 boolean isLastArgEager = ((ASTArgParameter) node.jjtGetChild(node.jjtGetNumChildren() - 1))
367 .getTypePattern().isEagerWildCard();
368
369 if (isFirstArgEager && expressionParameterCount == 1) {
370 return Boolean.TRUE;
371 }
372 int contextParametersCount = getParametersCount(ctx);
373 if (isFirstArgEager && isLastArgEager) {
374 expressionParameterCount -= 2;
375 if (expressionParameterCount == 0) {
376
377 return Boolean.TRUE;
378 }
379
380
381
382
383 int matchCount = 0;
384 int ictx = 0;
385 for (int iexp = 0; iexp < expressionParameterCount; iexp++) {
386 if (ictx >= contextParametersCount) {
387
388 matchCount = -1;
389 break;
390 }
391 ctx.setCurrentTargetArgsIndex(ictx);
392
393 boolean isEager = ((ASTArgParameter) node.jjtGetChild(iexp+1)).getTypePattern().isEagerWildCard();
394 if (isEager) {
395
396 }
397 if (Boolean.TRUE.equals((Boolean) node.jjtGetChild(iexp+1).jjtAccept(this, ctx))) {
398 matchCount += 1;
399 ictx++;
400 } else {
401
402 matchCount = 0;
403 ictx++;
404 iexp = -1;
405 }
406 }
407 if (matchCount == expressionParameterCount) {
408 return Boolean.TRUE;
409 } else {
410 return Boolean.FALSE;
411 }
412 } else if (isFirstArgEager) {
413 expressionParameterCount--;
414 if (contextParametersCount >= expressionParameterCount) {
415
416 for (int i = 0; (i < contextParametersCount) && (expressionParameterCount - i >= 0); i++) {
417 ctx.setCurrentTargetArgsIndex(contextParametersCount - 1 - i);
418 if (Boolean.TRUE.equals((Boolean) node.jjtGetChild(expressionParameterCount - i).jjtAccept(
419 this,
420 ctx))) {
421 ;
422 } else {
423 return Boolean.FALSE;
424 }
425 }
426 return Boolean.TRUE;
427 } else {
428
429 return Boolean.FALSE;
430 }
431 } else if (isLastArgEager) {
432 expressionParameterCount--;
433 if (contextParametersCount >= expressionParameterCount) {
434
435 for (int i = 0; (i < contextParametersCount) && (i < expressionParameterCount); i++) {
436 ctx.setCurrentTargetArgsIndex(i);
437 if (Boolean.TRUE.equals((Boolean) node.jjtGetChild(i).jjtAccept(this, ctx))) {
438 ;
439 } else {
440 return Boolean.FALSE;
441 }
442 }
443 return Boolean.TRUE;
444 } else {
445 return Boolean.FALSE;
446 }
447 } else {
448
449
450 if (expressionParameterCount == contextParametersCount) {
451 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
452 ctx.setCurrentTargetArgsIndex(i);
453 if (Boolean.TRUE.equals((Boolean) node.jjtGetChild(i).jjtAccept(this, ctx))) {
454 ;
455 } else {
456 return Boolean.FALSE;
457 }
458 }
459 return Boolean.TRUE;
460 } else {
461 return Boolean.FALSE;
462 }
463 }
464 }
465 }
466
467 public Object visit(ASTArgParameter node, Object data) {
468 TypePattern typePattern = node.getTypePattern();
469 TypePattern realPattern = typePattern;
470
471
472
473
474
475
476
477 int pointcutArgIndex = -1;
478 if (typePattern.getPattern().indexOf(".") < 0) {
479 String boundedType = m_expressionInfo.getArgumentType(typePattern.getPattern());
480 if (boundedType != null) {
481 pointcutArgIndex = m_expressionInfo.getArgumentIndex(typePattern.getPattern());
482 realPattern = TypePattern.compileTypePattern(boundedType, SubtypePatternType.NOT_HIERARCHICAL);
483 }
484 }
485
486 ExpressionContext ctx = (ExpressionContext) data;
487 ClassInfo argInfo = null;
488 try {
489 if (ctx.getReflectionInfo() instanceof MethodInfo) {
490 argInfo = ((MethodInfo) ctx.getReflectionInfo()).getParameterTypes()[ctx.getCurrentTargetArgsIndex()];
491 } else if (ctx.getReflectionInfo() instanceof ConstructorInfo) {
492 argInfo = ((ConstructorInfo) ctx.getReflectionInfo()).getParameterTypes()[ctx
493 .getCurrentTargetArgsIndex()];
494 } else if (ctx.getReflectionInfo() instanceof FieldInfo) {
495 argInfo = ((FieldInfo) ctx.getReflectionInfo()).getType();
496 }
497 } catch (ArrayIndexOutOfBoundsException e) {
498
499 return Boolean.FALSE;
500 }
501 if (ClassInfoHelper.matchType(realPattern, argInfo)) {
502 return Boolean.TRUE;
503 } else {
504 return Boolean.FALSE;
505 }
506 }
507
508 public Object visit(ASTAttribute node, Object data) {
509 List annotations = (List) data;
510 for (Iterator it = annotations.iterator(); it.hasNext();) {
511 AnnotationInfo annotation = (AnnotationInfo) it.next();
512 if (annotation.getName().equals(node.getName())) {
513 return Boolean.TRUE;
514 }
515 }
516 return Boolean.FALSE;
517 }
518
519 public Object visit(ASTModifier node, Object data) {
520 ReflectionInfo refInfo = (ReflectionInfo) data;
521 int modifiersToMatch = refInfo.getModifiers();
522 int modifierPattern = node.getModifier();
523 if (node.isNot()) {
524 if ((modifierPattern & Modifier.PUBLIC) != 0) {
525 if (((modifiersToMatch & Modifier.PUBLIC) == 0)) {
526 return Boolean.TRUE;
527 } else {
528 return Boolean.FALSE;
529 }
530 } else if ((modifierPattern & Modifier.PROTECTED) != 0) {
531 if ((modifiersToMatch & Modifier.PROTECTED) == 0) {
532 return Boolean.TRUE;
533 } else {
534 return Boolean.FALSE;
535 }
536 } else if ((modifierPattern & Modifier.PRIVATE) != 0) {
537 if ((modifiersToMatch & Modifier.PRIVATE) == 0) {
538 return Boolean.TRUE;
539 } else {
540 return Boolean.FALSE;
541 }
542 } else if ((modifierPattern & Modifier.STATIC) != 0) {
543 if ((modifiersToMatch & Modifier.STATIC) == 0) {
544 return Boolean.TRUE;
545 } else {
546 return Boolean.FALSE;
547 }
548 } else if ((modifierPattern & Modifier.SYNCHRONIZED) != 0) {
549 if ((modifiersToMatch & Modifier.SYNCHRONIZED) == 0) {
550 return Boolean.TRUE;
551 } else {
552 return Boolean.FALSE;
553 }
554 } else if ((modifierPattern & Modifier.FINAL) != 0) {
555 if ((modifiersToMatch & Modifier.FINAL) == 0) {
556 return Boolean.TRUE;
557 } else {
558 return Boolean.FALSE;
559 }
560 } else if ((modifierPattern & Modifier.TRANSIENT) != 0) {
561 if ((modifiersToMatch & Modifier.TRANSIENT) == 0) {
562 return Boolean.TRUE;
563 } else {
564 return Boolean.FALSE;
565 }
566 } else if ((modifierPattern & Modifier.VOLATILE) != 0) {
567 if ((modifiersToMatch & Modifier.VOLATILE) == 0) {
568 return Boolean.TRUE;
569 } else {
570 return Boolean.FALSE;
571 }
572 } else if ((modifierPattern & Modifier.STRICT) != 0) {
573 if ((modifiersToMatch & Modifier.STRICT) == 0) {
574 return Boolean.TRUE;
575 } else {
576 return Boolean.FALSE;
577 }
578 } else {
579 return Boolean.FALSE;
580 }
581 } else {
582 if ((modifierPattern & Modifier.PUBLIC) != 0) {
583 if (((modifiersToMatch & Modifier.PUBLIC) == 0)) {
584 return Boolean.FALSE;
585 } else {
586 return Boolean.TRUE;
587 }
588 } else if ((modifierPattern & Modifier.PROTECTED) != 0) {
589 if ((modifiersToMatch & Modifier.PROTECTED) == 0) {
590 return Boolean.FALSE;
591 } else {
592 return Boolean.TRUE;
593 }
594 } else if ((modifierPattern & Modifier.PRIVATE) != 0) {
595 if ((modifiersToMatch & Modifier.PRIVATE) == 0) {
596 return Boolean.FALSE;
597 } else {
598 return Boolean.TRUE;
599 }
600 } else if ((modifierPattern & Modifier.STATIC) != 0) {
601 if ((modifiersToMatch & Modifier.STATIC) == 0) {
602 return Boolean.FALSE;
603 } else {
604 return Boolean.TRUE;
605 }
606 } else if ((modifierPattern & Modifier.SYNCHRONIZED) != 0) {
607 if ((modifiersToMatch & Modifier.SYNCHRONIZED) == 0) {
608 return Boolean.FALSE;
609 } else {
610 return Boolean.TRUE;
611 }
612 } else if ((modifierPattern & Modifier.FINAL) != 0) {
613 if ((modifiersToMatch & Modifier.FINAL) == 0) {
614 return Boolean.FALSE;
615 } else {
616 return Boolean.TRUE;
617 }
618 } else if ((modifierPattern & Modifier.TRANSIENT) != 0) {
619 if ((modifiersToMatch & Modifier.TRANSIENT) == 0) {
620 return Boolean.FALSE;
621 } else {
622 return Boolean.TRUE;
623 }
624 } else if ((modifierPattern & Modifier.VOLATILE) != 0) {
625 if ((modifiersToMatch & Modifier.VOLATILE) == 0) {
626 return Boolean.FALSE;
627 } else {
628 return Boolean.TRUE;
629 }
630 } else if ((modifierPattern & Modifier.STRICT) != 0) {
631 if ((modifiersToMatch & Modifier.STRICT) == 0) {
632 return Boolean.FALSE;
633 } else {
634 return Boolean.TRUE;
635 }
636 } else {
637 return Boolean.TRUE;
638 }
639 }
640 }
641
642 protected boolean visitAttributes(SimpleNode node, ReflectionInfo refInfo) {
643 int nrChildren = node.jjtGetNumChildren();
644 if (nrChildren != 0) {
645 for (int i = 0; i < nrChildren; i++) {
646 Node child = node.jjtGetChild(i);
647 if (child instanceof ASTAttribute) {
648 List annotations = refInfo.getAnnotations();
649 if (Boolean.TRUE.equals(child.jjtAccept(this, annotations))) {
650 continue;
651 } else {
652 return false;
653 }
654 }
655 }
656 }
657 return true;
658 }
659
660 protected boolean visitModifiers(SimpleNode node, ReflectionInfo refInfo) {
661 int nrChildren = node.jjtGetNumChildren();
662 if (nrChildren != 0) {
663 for (int i = 0; i < nrChildren; i++) {
664 Node child = node.jjtGetChild(i);
665 if (child instanceof ASTModifier) {
666 if (Boolean.TRUE.equals(child.jjtAccept(this, refInfo))) {
667 continue;
668 } else {
669 return false;
670 }
671 }
672 }
673 }
674 return true;
675 }
676
677 protected boolean visitParameters(SimpleNode node, ClassInfo[] parameterTypes) {
678 int nrChildren = node.jjtGetNumChildren();
679 if (nrChildren <= 0) {
680 return (parameterTypes.length==0);
681 }
682
683
684 List parameterNodes = new ArrayList();
685 for (int i = 0; i < nrChildren; i++) {
686 Node child = node.jjtGetChild(i);
687 if (child instanceof ASTParameter) {
688 parameterNodes.add(child);
689 }
690 }
691
692 if (parameterNodes.size() <= 0) {
693 return (parameterTypes.length==0);
694 }
695
696
697
698
699
700 int expressionParameterCount = parameterNodes.size();
701 boolean isFirstArgEager = ((ASTParameter) parameterNodes.get(0)).getDeclaringClassPattern().isEagerWildCard();
702 boolean isLastArgEager = ((ASTParameter) parameterNodes.get(expressionParameterCount-1)).getDeclaringClassPattern().isEagerWildCard();
703
704 if (isFirstArgEager && expressionParameterCount == 1) {
705 return true;
706 }
707 int contextParametersCount = parameterTypes.length;
708 if (isFirstArgEager && isLastArgEager) {
709 expressionParameterCount -= 2;
710 if (expressionParameterCount == 0) {
711
712 return true;
713 }
714
715
716
717
718 int matchCount = 0;
719 int ictx = 0;
720 for (int iexp = 0; iexp < expressionParameterCount; iexp++) {
721 if (ictx >= contextParametersCount) {
722
723 matchCount = -1;
724 break;
725 }
726
727 ASTParameter parameterNode = (ASTParameter) parameterNodes.get(iexp+1);
728 boolean isEager = parameterNode.getDeclaringClassPattern().isEagerWildCard();
729 if (isEager) {
730
731 }
732 if (Boolean.TRUE.equals((Boolean) parameterNode.jjtAccept(this, parameterTypes[ictx]))) {
733 matchCount += 1;
734 ictx++;
735 } else {
736
737 matchCount = 0;
738 ictx++;
739 iexp = -1;
740 }
741 }
742 if (matchCount == expressionParameterCount) {
743 return true;
744 } else {
745 return false;
746 }
747 } else if (isFirstArgEager) {
748 expressionParameterCount--;
749 if (contextParametersCount >= expressionParameterCount) {
750
751 for (int i = 0; (i < contextParametersCount) && (expressionParameterCount - i >= 0); i++) {
752 ASTParameter parameterNode = (ASTParameter) parameterNodes.get(expressionParameterCount - i);
753 if (Boolean.TRUE.equals((Boolean) parameterNode.jjtAccept(
754 this,
755 parameterTypes[contextParametersCount -1 -i]))) {
756 ;
757 } else {
758 return false;
759 }
760 }
761 return true;
762 } else {
763
764 return false;
765 }
766 } else if (isLastArgEager) {
767 expressionParameterCount--;
768 if (contextParametersCount >= expressionParameterCount) {
769
770 for (int i = 0; (i < contextParametersCount) && (i < expressionParameterCount); i++) {
771 ASTParameter parameterNode = (ASTParameter) parameterNodes.get(i);
772 if (Boolean.TRUE.equals((Boolean) parameterNode.jjtAccept(this, parameterTypes[i]))) {
773 ;
774 } else {
775 return false;
776 }
777 }
778 return true;
779 } else {
780 return false;
781 }
782 } else {
783
784
785 if (expressionParameterCount == contextParametersCount) {
786 for (int i = 0; i < parameterNodes.size(); i++) {
787 ASTParameter parameterNode = (ASTParameter) parameterNodes.get(i);
788 if (Boolean.TRUE.equals((Boolean) parameterNode.jjtAccept(this, parameterTypes[i]))) {
789 ;
790 } else {
791 return false;
792 }
793 }
794 return true;
795 } else {
796 return false;
797 }
798 }
799 }
800
801 /***
802 * Returns the string representation of the expression.
803 *
804 * @return
805 */
806 public String toString() {
807 return m_expression;
808 }
809
810 /***
811 * Returns the number of parameters to the target method/constructor else -1.
812 *
813 * @param ctx
814 * @return
815 */
816 private int getParametersCount(final ExpressionContext ctx) {
817 ReflectionInfo reflectionInfo = ctx.getReflectionInfo();
818 if (reflectionInfo instanceof MethodInfo) {
819 return ((MethodInfo) reflectionInfo).getParameterTypes().length;
820 } else if (reflectionInfo instanceof ConstructorInfo) {
821 return ((ConstructorInfo) reflectionInfo).getParameterTypes().length;
822 } else if (reflectionInfo instanceof FieldInfo) {
823 return 1;
824 } else {
825 return -1;
826 }
827 }
828 }