Source Code Cross Referenced for ExpressionVisitor.java in  » Aspect-oriented » aspectwerkz-2.0 » org » codehaus » aspectwerkz » expression » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Aspect oriented » aspectwerkz 2.0 » org.codehaus.aspectwerkz.expression 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**************************************************************************************
0002:         * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
0003:         * http://aspectwerkz.codehaus.org                                                    *
0004:         * ---------------------------------------------------------------------------------- *
0005:         * The software in this package is published under the terms of the LGPL license      *
0006:         * a copy of which has been included with this distribution in the license.txt file.  *
0007:         **************************************************************************************/package org.codehaus.aspectwerkz.expression;
0008:
0009:        import org.codehaus.aspectwerkz.annotation.AnnotationInfo;
0010:        import org.codehaus.aspectwerkz.expression.ast.ASTAnd;
0011:        import org.codehaus.aspectwerkz.expression.ast.ASTAttribute;
0012:        import org.codehaus.aspectwerkz.expression.ast.ASTCall;
0013:        import org.codehaus.aspectwerkz.expression.ast.ASTCflow;
0014:        import org.codehaus.aspectwerkz.expression.ast.ASTCflowBelow;
0015:        import org.codehaus.aspectwerkz.expression.ast.ASTClassPattern;
0016:        import org.codehaus.aspectwerkz.expression.ast.ASTConstructorPattern;
0017:        import org.codehaus.aspectwerkz.expression.ast.ASTExecution;
0018:        import org.codehaus.aspectwerkz.expression.ast.ASTExpression;
0019:        import org.codehaus.aspectwerkz.expression.ast.ASTFieldPattern;
0020:        import org.codehaus.aspectwerkz.expression.ast.ASTGet;
0021:        import org.codehaus.aspectwerkz.expression.ast.ASTHandler;
0022:        import org.codehaus.aspectwerkz.expression.ast.ASTMethodPattern;
0023:        import org.codehaus.aspectwerkz.expression.ast.ASTModifier;
0024:        import org.codehaus.aspectwerkz.expression.ast.ASTNot;
0025:        import org.codehaus.aspectwerkz.expression.ast.ASTOr;
0026:        import org.codehaus.aspectwerkz.expression.ast.ASTParameter;
0027:        import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference;
0028:        import org.codehaus.aspectwerkz.expression.ast.ASTRoot;
0029:        import org.codehaus.aspectwerkz.expression.ast.ASTSet;
0030:        import org.codehaus.aspectwerkz.expression.ast.ASTStaticInitialization;
0031:        import org.codehaus.aspectwerkz.expression.ast.ASTWithin;
0032:        import org.codehaus.aspectwerkz.expression.ast.ASTWithinCode;
0033:        import org.codehaus.aspectwerkz.expression.ast.ExpressionParserVisitor;
0034:        import org.codehaus.aspectwerkz.expression.ast.Node;
0035:        import org.codehaus.aspectwerkz.expression.ast.SimpleNode;
0036:        import org.codehaus.aspectwerkz.expression.ast.ASTArgs;
0037:        import org.codehaus.aspectwerkz.expression.ast.ASTArgParameter;
0038:        import org.codehaus.aspectwerkz.expression.regexp.TypePattern;
0039:        import org.codehaus.aspectwerkz.reflect.ClassInfo;
0040:        import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
0041:        import org.codehaus.aspectwerkz.reflect.FieldInfo;
0042:        import org.codehaus.aspectwerkz.reflect.MemberInfo;
0043:        import org.codehaus.aspectwerkz.reflect.MethodInfo;
0044:        import org.codehaus.aspectwerkz.reflect.ReflectionInfo;
0045:        import org.codehaus.aspectwerkz.reflect.ClassInfoHelper;
0046:        import org.codehaus.aspectwerkz.reflect.StaticInitializationInfo;
0047:
0048:        import java.lang.reflect.Modifier;
0049:        import java.util.ArrayList;
0050:        import java.util.Iterator;
0051:        import java.util.List;
0052:
0053:        import org.codehaus.aspectwerkz.expression.ast.ASTHasField;
0054:        import org.codehaus.aspectwerkz.expression.ast.ASTHasMethod;
0055:        import org.codehaus.aspectwerkz.expression.ast.ASTTarget;
0056:        import org.codehaus.aspectwerkz.expression.ast.ASTThis;
0057:        import org.codehaus.aspectwerkz.util.Util;
0058:
0059:        /**
0060:         * The expression visitor.
0061:         * If a runtime residual is required (target => instance of check sometimes), Undeterministic matching is used.
0062:         *
0063:         * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
0064:         * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
0065:         * @author Michael Nascimento
0066:         * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
0067:         */
0068:        public class ExpressionVisitor implements  ExpressionParserVisitor {
0069:
0070:            protected Node m_root;
0071:            protected String m_expression;
0072:            protected String m_namespace;
0073:
0074:            /**
0075:             * The expressionInfo this visitor is built on
0076:             */
0077:            protected ExpressionInfo m_expressionInfo;
0078:
0079:            /**
0080:             * Creates a new expression.
0081:             *
0082:             * @param expressionInfo the expressionInfo this visitor is built on for expression with signature
0083:             * @param expression     the expression as a string
0084:             * @param namespace      the namespace
0085:             * @param root           the AST root
0086:             */
0087:            public ExpressionVisitor(final ExpressionInfo expressionInfo,
0088:                    final String expression, final String namespace,
0089:                    final Node root) {
0090:                m_expressionInfo = expressionInfo;
0091:                m_expression = expression;
0092:                m_namespace = namespace;
0093:                m_root = root;
0094:            }
0095:
0096:            /**
0097:             * Matches the expression context.
0098:             * If undetermined, assume true.
0099:             * Do not use for poincut reference - see matchUndeterministic
0100:             *
0101:             * @param context
0102:             * @return
0103:             */
0104:            public boolean match(final ExpressionContext context) {
0105:                Boolean match = ((Boolean) visit(m_root, context));
0106:                // undeterministic is assumed to be "true" at this stage
0107:                // since it won't be composed anymore with a NOT (unless
0108:                // thru pointcut reference ie a new visitor)
0109:                return (match != null) ? match.booleanValue() : true;
0110:            }
0111:
0112:            protected Boolean matchUndeterministic(
0113:                    final ExpressionContext context) {
0114:                Boolean match = ((Boolean) visit(m_root, context));
0115:                return match;
0116:            }
0117:
0118:            // ============ Boot strap =============
0119:            public Object visit(Node node, Object data) {
0120:                return node.jjtGetChild(0).jjtAccept(this , data);
0121:            }
0122:
0123:            public Object visit(SimpleNode node, Object data) {
0124:                return node.jjtGetChild(0).jjtAccept(this , data);
0125:            }
0126:
0127:            public Object visit(ASTRoot node, Object data) {
0128:                return node.jjtGetChild(0).jjtAccept(this , data);
0129:            }
0130:
0131:            public Object visit(ASTExpression node, Object data) {
0132:                return node.jjtGetChild(0).jjtAccept(this , data);
0133:            }
0134:
0135:            // ============ Logical operators =============
0136:            public Object visit(ASTOr node, Object data) {
0137:                // the AND and OR can have more than 2 nodes [see jjt grammar]
0138:                Boolean matchL = (Boolean) node.jjtGetChild(0).jjtAccept(this ,
0139:                        data);
0140:                Boolean matchR = (Boolean) node.jjtGetChild(1).jjtAccept(this ,
0141:                        data);
0142:                Boolean intermediate = Undeterministic.or(matchL, matchR);
0143:                for (int i = 2; i < node.jjtGetNumChildren(); i++) {
0144:                    Boolean matchNext = (Boolean) node.jjtGetChild(i)
0145:                            .jjtAccept(this , data);
0146:                    intermediate = Undeterministic.or(intermediate, matchNext);
0147:                }
0148:                return intermediate;
0149:            }
0150:
0151:            public Object visit(ASTAnd node, Object data) {
0152:                // the AND and OR can have more than 2 nodes [see jjt grammar]
0153:                Boolean matchL = (Boolean) node.jjtGetChild(0).jjtAccept(this ,
0154:                        data);
0155:                Boolean matchR = (Boolean) node.jjtGetChild(1).jjtAccept(this ,
0156:                        data);
0157:                Boolean intermediate = Undeterministic.and(matchL, matchR);
0158:                for (int i = 2; i < node.jjtGetNumChildren(); i++) {
0159:                    Boolean matchNext = (Boolean) node.jjtGetChild(i)
0160:                            .jjtAccept(this , data);
0161:                    intermediate = Undeterministic.and(intermediate, matchNext);
0162:                }
0163:                return intermediate;
0164:            }
0165:
0166:            public Object visit(ASTNot node, Object data) {
0167:                Boolean match = (Boolean) node.jjtGetChild(0).jjtAccept(this ,
0168:                        data);
0169:                return Undeterministic.not(match);
0170:            }
0171:
0172:            // ============ Pointcut types =============
0173:            public Object visit(ASTPointcutReference node, Object data) {
0174:                ExpressionContext context = (ExpressionContext) data;
0175:                ExpressionNamespace namespace = ExpressionNamespace
0176:                        .getNamespace(m_namespace);
0177:                ExpressionVisitor expression = namespace.getExpression(node
0178:                        .getName());
0179:                return expression.matchUndeterministic(context);
0180:            }
0181:
0182:            public Object visit(ASTExecution node, Object data) {
0183:                ExpressionContext context = (ExpressionContext) data;
0184:                if (context.hasExecutionPointcut()
0185:                        && (context.hasMethodInfo() || context
0186:                                .hasConstructorInfo())) {
0187:                    return visitAnnotatedNode(node, context.getReflectionInfo());
0188:                } else {
0189:                    return Boolean.FALSE;
0190:                }
0191:            }
0192:
0193:            public Object visit(ASTCall node, Object data) {
0194:                ExpressionContext context = (ExpressionContext) data;
0195:                if (context.hasCallPointcut()
0196:                        && (context.hasMethodInfo() || context
0197:                                .hasConstructorInfo())) {
0198:                    return visitAnnotatedNode(node, context.getReflectionInfo());
0199:                } else {
0200:                    return Boolean.FALSE;
0201:                }
0202:            }
0203:
0204:            public Object visit(ASTSet node, Object data) {
0205:                ExpressionContext context = (ExpressionContext) data;
0206:                if (context.hasSetPointcut() && context.hasFieldInfo()) {
0207:                    return visitAnnotatedNode(node, context.getReflectionInfo());
0208:                } else {
0209:                    return Boolean.FALSE;
0210:                }
0211:            }
0212:
0213:            public Object visit(ASTGet node, Object data) {
0214:                ExpressionContext context = (ExpressionContext) data;
0215:                if (context.hasGetPointcut() && context.hasFieldInfo()) {
0216:                    return visitAnnotatedNode(node, context.getReflectionInfo());
0217:                } else {
0218:                    return Boolean.FALSE;
0219:                }
0220:            }
0221:
0222:            public Object visit(ASTHandler node, Object data) {
0223:                ExpressionContext context = (ExpressionContext) data;
0224:                if (context.hasHandlerPointcut() && context.hasClassInfo()) {
0225:                    return node.jjtGetChild(0).jjtAccept(this ,
0226:                            context.getReflectionInfo());
0227:                } else {
0228:                    return Boolean.FALSE;
0229:                }
0230:            }
0231:
0232:            public Object visit(ASTStaticInitialization node, Object data) {
0233:                ExpressionContext context = (ExpressionContext) data;
0234:
0235:                if (context.hasStaticInitializationPointcut()
0236:                        && context.hasReflectionInfo()) {
0237:                    ReflectionInfo reflectInfo = context.getReflectionInfo();
0238:
0239:                    if (reflectInfo instanceof  StaticInitializationInfo) {
0240:                        ClassInfo declaringClassInfo = ((StaticInitializationInfo) reflectInfo)
0241:                                .getDeclaringType();
0242:
0243:                        // In an annotated subtree, only the last child node may represent the pattern
0244:                        Node patternNode = node.jjtGetChild(node
0245:                                .jjtGetNumChildren() - 1);
0246:                        if (!(patternNode instanceof  ASTAttribute)) {
0247:                            Boolean matchPattern = (Boolean) patternNode
0248:                                    .jjtAccept(this , reflectInfo);
0249:                            if (Boolean.FALSE.equals(matchPattern)) {
0250:                                return Boolean.FALSE;
0251:                            }
0252:                        }
0253:
0254:                        // match on annotation if no pattern node or matched already
0255:                        boolean matchedAnnotations = visitAttributes(node,
0256:                                declaringClassInfo);
0257:                        if (!matchedAnnotations) {
0258:                            return Boolean.FALSE;
0259:                        } else {
0260:                            return Boolean.TRUE;
0261:                        }
0262:                    } else {
0263:                        return Boolean.FALSE;
0264:                    }
0265:                } else {
0266:                    return Boolean.FALSE;
0267:                }
0268:            }
0269:
0270:            public Object visit(ASTWithin node, Object data) {
0271:                ExpressionContext context = (ExpressionContext) data;
0272:                if (context.hasWithinReflectionInfo()) {
0273:                    ReflectionInfo reflectInfo = context
0274:                            .getWithinReflectionInfo();
0275:                    ReflectionInfo withinInfo = null;
0276:
0277:                    if (reflectInfo instanceof  MemberInfo) {
0278:                        withinInfo = ((MemberInfo) reflectInfo)
0279:                                .getDeclaringType();
0280:                    } else if (reflectInfo instanceof  ClassInfo) {
0281:                        withinInfo = reflectInfo;
0282:                    } else {
0283:                        return Boolean.FALSE;
0284:                    }
0285:                    return visitAnnotatedNode(node, withinInfo);
0286:                } else {
0287:                    return null;
0288:                }
0289:            }
0290:
0291:            public Object visit(ASTWithinCode node, Object data) {
0292:                ExpressionContext context = (ExpressionContext) data;
0293:
0294:                if (!context.hasWithinReflectionInfo()) {
0295:                    return null;
0296:                }
0297:
0298:                ReflectionInfo reflectInfo = context.getWithinReflectionInfo();
0299:
0300:                if (node.isStaticInitializer()) {
0301:                    if (reflectInfo instanceof  StaticInitializationInfo) {
0302:                        // Ignore the ASTStaticInitialization node in this context
0303:                        SimpleNode staticClinitNode = (SimpleNode) node
0304:                                .jjtGetChild(0);
0305:                        ClassInfo declaringClassInfo = ((StaticInitializationInfo) reflectInfo)
0306:                                .getDeclaringType();
0307:
0308:                        boolean matchedAnnotations = visitAttributes(
0309:                                staticClinitNode, declaringClassInfo);
0310:                        if (!matchedAnnotations) {
0311:                            return Boolean.FALSE;
0312:                        }
0313:
0314:                        // In an annotated subtree, the last child node represents the pattern
0315:                        Node lastNode = staticClinitNode
0316:                                .jjtGetChild(staticClinitNode
0317:                                        .jjtGetNumChildren() - 1);
0318:                        if (lastNode instanceof  ASTAttribute) {
0319:                            return Boolean.TRUE;
0320:                        } else {
0321:                            return lastNode.jjtAccept(this , reflectInfo);
0322:                        }
0323:                    } else {
0324:                        return Boolean.FALSE;
0325:                    }
0326:                } else {
0327:                    return visitAnnotatedNode(node, reflectInfo);
0328:                }
0329:            }
0330:
0331:            public Object visit(ASTHasMethod node, Object data) {
0332:                ExpressionContext context = (ExpressionContext) data;
0333:
0334:                // we are matching on the CALLER info
0335:                // for execution() pointcut, this is equals to CALLEE info
0336:                ReflectionInfo info = context.getWithinReflectionInfo();
0337:                ClassInfo classInfo = info instanceof  MemberInfo ? ((MemberInfo) info)
0338:                        .getDeclaringType()
0339:                        : (ClassInfo) info;
0340:
0341:                Node patternNode = node
0342:                        .jjtGetChild(node.jjtGetNumChildren() - 1);
0343:                boolean hasPatternNode = !(patternNode instanceof  ASTAttribute);
0344:
0345:                MethodInfo[] methodInfos = classInfo.getMethods();
0346:                for (int i = 0; i < methodInfos.length; i++) {
0347:                    if (hasPatternNode) {
0348:                        if (Boolean.FALSE.equals(patternNode.jjtAccept(this ,
0349:                                methodInfos[i]))) {
0350:                            continue;
0351:                        }
0352:                    }
0353:
0354:                    boolean matchAnnotations = visitAttributes(node,
0355:                            methodInfos[i]);
0356:                    if (matchAnnotations) {
0357:                        return Boolean.TRUE;
0358:                    }
0359:                }
0360:
0361:                ConstructorInfo[] constructorInfos = classInfo
0362:                        .getConstructors();
0363:                for (int i = 0; i < constructorInfos.length; i++) {
0364:                    if (hasPatternNode) {
0365:                        if (Boolean.FALSE.equals(patternNode.jjtAccept(this ,
0366:                                constructorInfos[i]))) {
0367:                            continue;
0368:                        }
0369:                    }
0370:
0371:                    boolean matchAnnotations = visitAttributes(node,
0372:                            constructorInfos[i]);
0373:                    if (matchAnnotations) {
0374:                        return Boolean.TRUE;
0375:                    }
0376:                }
0377:
0378:                return Boolean.FALSE;
0379:            }
0380:
0381:            public Object visit(ASTHasField node, Object data) {
0382:                ExpressionContext context = (ExpressionContext) data;
0383:
0384:                // we are matching on the CALLER info
0385:                // for execution() pointcut, this is equals to CALLEE info
0386:                ReflectionInfo info = context.getWithinReflectionInfo();
0387:                ClassInfo classInfo = (info instanceof  MemberInfo) ? ((MemberInfo) info)
0388:                        .getDeclaringType()
0389:                        : (ClassInfo) info;
0390:
0391:                Node patternNode = node
0392:                        .jjtGetChild(node.jjtGetNumChildren() - 1);
0393:                boolean hasPatternNode = !(patternNode instanceof  ASTAttribute);
0394:
0395:                FieldInfo[] fieldInfos = classInfo.getFields();
0396:                for (int i = 0; i < fieldInfos.length; i++) {
0397:                    if (hasPatternNode) {
0398:                        if (Boolean.FALSE.equals(patternNode.jjtAccept(this ,
0399:                                fieldInfos[i]))) {
0400:                            continue;
0401:                        }
0402:                    }
0403:
0404:                    boolean matchAnnotations = visitAttributes(node,
0405:                            fieldInfos[i]);
0406:                    if (matchAnnotations) {
0407:                        return Boolean.TRUE;
0408:                    }
0409:                }
0410:
0411:                return Boolean.FALSE;
0412:            }
0413:
0414:            public Object visit(ASTTarget node, Object data) {
0415:                ExpressionContext context = (ExpressionContext) data;
0416:                ReflectionInfo info = context.getReflectionInfo();
0417:
0418:                //        //TODO - seems to be the case for AJ - not intuitive
0419:                //        if (info instanceof ConstructorInfo) {
0420:                //            // target(..) does not match for constructors
0421:                //            return Boolean.FALSE;
0422:                //        }
0423:                ClassInfo declaringType = null;
0424:                if (info instanceof  MemberInfo) {
0425:                    // if method/field is static, target(..) is evaluated to false
0426:                    if (Modifier.isStatic(((MemberInfo) info).getModifiers())) {
0427:                        return Boolean.FALSE;
0428:                    }
0429:
0430:                    declaringType = ((MemberInfo) info).getDeclaringType();
0431:                } else if (info instanceof  ClassInfo) {
0432:                    declaringType = (ClassInfo) info;
0433:                } else {
0434:                    return Boolean.FALSE;
0435:                }
0436:
0437:                String boundedTypeName = node.getBoundedType(m_expressionInfo);
0438:                // check if the context we match is an interface call, while the bounded type of target(..) is not an
0439:                // interface. In such a case we will need a runtime check
0440:                if (declaringType.isInterface()) {
0441:                    // if we are a instanceof (subinterface) of the bounded type, then we don't need a runtime check
0442:                    if (ClassInfoHelper.instanceOf(declaringType,
0443:                            boundedTypeName)) {
0444:                        return Boolean.TRUE;
0445:                    } else {
0446:                        //System.out.println("*** RT check for "  + boundedTypeName + " when I am " + declaringType.getName());
0447:                        // a runtime check with instance of will be required
0448:                        return null;
0449:                    }
0450:                } else {
0451:                    return Util.booleanValueOf(ClassInfoHelper.instanceOf(
0452:                            declaringType, boundedTypeName));
0453:                }
0454:            }
0455:
0456:            public Object visit(ASTThis node, Object data) {
0457:                ExpressionContext context = (ExpressionContext) data;
0458:                // for execution pointcut, this(..) is used to match the callee info
0459:                // and we are assuming here that withinInfo is properly set to reflectionInfo
0460:                if (context.hasWithinReflectionInfo()) {
0461:                    ReflectionInfo withinInfo = context
0462:                            .getWithinReflectionInfo();
0463:                    if (withinInfo instanceof  MemberInfo) {
0464:                        // if method is static (callee for execution or caller for call/get/set), this(..) is evaluated to false
0465:                        if (Modifier.isStatic(((MemberInfo) withinInfo)
0466:                                .getModifiers())) {
0467:                            return Boolean.FALSE;
0468:                        }
0469:                        return Util.booleanValueOf(ClassInfoHelper.instanceOf(
0470:                                ((MemberInfo) withinInfo).getDeclaringType(),
0471:                                node.getBoundedType(m_expressionInfo)));
0472:                    } else if (withinInfo instanceof  ClassInfo) {
0473:                        return Util.booleanValueOf(ClassInfoHelper.instanceOf(
0474:                                (ClassInfo) withinInfo, node
0475:                                        .getBoundedType(m_expressionInfo)));
0476:                    }
0477:                }
0478:                return Boolean.FALSE;
0479:            }
0480:
0481:            public Object visit(ASTCflow node, Object data) {
0482:                return null;
0483:            }
0484:
0485:            public Object visit(ASTCflowBelow node, Object data) {
0486:                return null;
0487:            }
0488:
0489:            // ============ Patterns =============
0490:            public Object visit(ASTClassPattern node, Object data) {
0491:                if (data instanceof  ClassInfo) {
0492:                    ClassInfo classInfo = (ClassInfo) data;
0493:                    TypePattern typePattern = node.getTypePattern();
0494:
0495:                    if (typePattern.matchType(classInfo)
0496:                            && visitModifiers(node, classInfo)) {
0497:                        return Boolean.TRUE;
0498:                    } else {
0499:                        return Boolean.FALSE;
0500:                    }
0501:                } else if (data instanceof  StaticInitializationInfo) {
0502:                    ClassInfo classInfo = ((StaticInitializationInfo) data)
0503:                            .getDeclaringType();
0504:
0505:                    if (node.getTypePattern().matchType(classInfo)) {
0506:                        return Boolean.TRUE;
0507:                    } else {
0508:                        return Boolean.FALSE;
0509:                    }
0510:
0511:                    //        	return new Boolean(node.getTypePattern().matchType(classInfo));
0512:                }
0513:
0514:                return Boolean.FALSE;
0515:            }
0516:
0517:            public Object visit(ASTMethodPattern node, Object data) {
0518:                if (data instanceof  MethodInfo) {
0519:                    MethodInfo methodInfo = (MethodInfo) data;
0520:                    if (node.getMethodNamePattern().matches(
0521:                            methodInfo.getName())
0522:                            && node.getDeclaringTypePattern().matchType(
0523:                                    methodInfo.getDeclaringType())
0524:                            && node.getReturnTypePattern().matchType(
0525:                                    methodInfo.getReturnType())
0526:                            && visitModifiers(node, methodInfo)
0527:                            && visitParameters(node, methodInfo
0528:                                    .getParameterTypes())) {
0529:                        return Boolean.TRUE;
0530:                    }
0531:                }
0532:
0533:                return Boolean.FALSE;
0534:            }
0535:
0536:            public Object visit(ASTConstructorPattern node, Object data) {
0537:                if (data instanceof  ConstructorInfo) {
0538:                    ConstructorInfo constructorMetaData = (ConstructorInfo) data;
0539:                    if (node.getDeclaringTypePattern().matchType(
0540:                            constructorMetaData.getDeclaringType())
0541:                            && visitModifiers(node, constructorMetaData)
0542:                            && visitParameters(node, constructorMetaData
0543:                                    .getParameterTypes())) {
0544:                        return Boolean.TRUE;
0545:                    }
0546:                }
0547:                return Boolean.FALSE;
0548:            }
0549:
0550:            public Object visit(ASTFieldPattern node, Object data) {
0551:                if (data instanceof  FieldInfo) {
0552:                    FieldInfo fieldInfo = (FieldInfo) data;
0553:                    if (node.getFieldNamePattern().matches(fieldInfo.getName())
0554:                            && node.getDeclaringTypePattern().matchType(
0555:                                    fieldInfo.getDeclaringType())
0556:                            && node.getFieldTypePattern().matchType(
0557:                                    fieldInfo.getType())
0558:                            && visitModifiers(node, fieldInfo)) {
0559:                        return Boolean.TRUE;
0560:                    }
0561:                }
0562:                return Boolean.FALSE;
0563:            }
0564:
0565:            public Object visit(ASTParameter node, Object data) {
0566:                ClassInfo parameterType = (ClassInfo) data;
0567:                if (node.getDeclaringClassPattern().matchType(parameterType)) {
0568:                    return Boolean.TRUE;
0569:                } else {
0570:                    return Boolean.FALSE;
0571:                }
0572:            }
0573:
0574:            public Object visit(ASTArgs node, Object data) {
0575:                ExpressionContext ctx = (ExpressionContext) data;
0576:                if (node.jjtGetNumChildren() <= 0) {
0577:                    // args(EMPTY)
0578:                    return (getParametersCount(ctx) == 0) ? Boolean.TRUE
0579:                            : Boolean.FALSE;
0580:                } else {
0581:                    // check for ".." as first node
0582:                    int expressionParameterCount = node.jjtGetNumChildren();// the number of node minus eager one.
0583:                    boolean isFirstArgEager = ((ASTArgParameter) node
0584:                            .jjtGetChild(0)).getTypePattern().isEagerWildCard();
0585:                    boolean isLastArgEager = ((ASTArgParameter) node
0586:                            .jjtGetChild(node.jjtGetNumChildren() - 1))
0587:                            .getTypePattern().isEagerWildCard();
0588:                    // args(..)
0589:                    if (isFirstArgEager && expressionParameterCount == 1) {
0590:                        return Boolean.TRUE;
0591:                    }
0592:                    int contextParametersCount = getParametersCount(ctx);
0593:                    if (isFirstArgEager && isLastArgEager) {
0594:                        expressionParameterCount -= 2;
0595:                        if (expressionParameterCount == 0) {
0596:                            // expression is "args(.., ..)"
0597:                            return Boolean.TRUE;
0598:                        }
0599:                        // we need to find a starting position - args(..,int, bar, ..)
0600:                        // foo(int) //int is ok
0601:                        // foo(bar,int,bar) //int is ok
0602:                        // foo(bar,int,foo,int,bar) // int is ok, but then we fail, so move on to next..
0603:                        int matchCount = 0;
0604:                        int ictx = 0;
0605:                        for (int iexp = 0; iexp < expressionParameterCount; iexp++) {
0606:                            if (ictx >= contextParametersCount) {
0607:                                // too many args in args()
0608:                                matchCount = -1;
0609:                                break;
0610:                            }
0611:                            ctx.setCurrentTargetArgsIndex(ictx);
0612:                            // do we have an eager wildcard in the middle ?
0613:                            boolean isEager = ((ASTArgParameter) node
0614:                                    .jjtGetChild(iexp + 1)).getTypePattern()
0615:                                    .isEagerWildCard();
0616:                            if (isEager) {
0617:                                // TODO - ignore for now, but not really supported - eager in the middle will match one
0618:                            }
0619:                            if (Boolean.TRUE.equals((Boolean) node.jjtGetChild(
0620:                                    iexp + 1).jjtAccept(this , ctx))) {
0621:                                matchCount += 1;
0622:                                ictx++;
0623:                            } else {
0624:                                // assume matched by starting ".." and rewind expression index
0625:                                matchCount = 0;
0626:                                ictx++;
0627:                                iexp = -1;
0628:                            }
0629:                        }
0630:                        if (matchCount == expressionParameterCount) {
0631:                            return Boolean.TRUE;
0632:                        } else {
0633:                            return Boolean.FALSE;
0634:                        }
0635:                    } else if (isFirstArgEager) {
0636:                        expressionParameterCount--;
0637:                        if (contextParametersCount >= expressionParameterCount) {
0638:                            // do a match from last to first, break when args() nodes are exhausted
0639:                            for (int i = 0; (i < contextParametersCount)
0640:                                    && (expressionParameterCount - i >= 0); i++) {
0641:                                ctx
0642:                                        .setCurrentTargetArgsIndex(contextParametersCount
0643:                                                - 1 - i);
0644:                                if (Boolean.TRUE.equals((Boolean) node
0645:                                        .jjtGetChild(
0646:                                                expressionParameterCount - i)
0647:                                        .jjtAccept(this , ctx))) {
0648:                                    ;//go on with "next" arg
0649:                                } else {
0650:                                    return Boolean.FALSE;
0651:                                }
0652:                            }
0653:                            return Boolean.TRUE;
0654:                        } else {
0655:                            //args() as more args than context we try to match
0656:                            return Boolean.FALSE;
0657:                        }
0658:                    } else if (isLastArgEager) {
0659:                        expressionParameterCount--;
0660:                        if (contextParametersCount >= expressionParameterCount) {
0661:                            // do a match from first to last, break when args() nodes are exhausted
0662:                            for (int i = 0; (i < contextParametersCount)
0663:                                    && (i < expressionParameterCount); i++) {
0664:                                ctx.setCurrentTargetArgsIndex(i);
0665:                                if (Boolean.TRUE.equals((Boolean) node
0666:                                        .jjtGetChild(i).jjtAccept(this , ctx))) {
0667:                                    ;//go on with next arg
0668:                                } else {
0669:                                    return Boolean.FALSE;
0670:                                }
0671:                            }
0672:                            return Boolean.TRUE;
0673:                        } else {
0674:                            return Boolean.FALSE;
0675:                        }
0676:                    } else {
0677:                        // no eager wildcard in args()
0678:                        // check that args length are equals
0679:                        if (expressionParameterCount == contextParametersCount) {
0680:                            for (int i = 0; i < node.jjtGetNumChildren(); i++) {
0681:                                ctx.setCurrentTargetArgsIndex(i);
0682:                                if (Boolean.TRUE.equals((Boolean) node
0683:                                        .jjtGetChild(i).jjtAccept(this , ctx))) {
0684:                                    ;//go on with next arg
0685:                                } else {
0686:                                    return Boolean.FALSE;
0687:                                }
0688:                            }
0689:                            return Boolean.TRUE;
0690:                        } else {
0691:                            return Boolean.FALSE;
0692:                        }
0693:                    }
0694:                }
0695:            }
0696:
0697:            public Object visit(ASTArgParameter node, Object data) {
0698:                //TODO we are not doing any hierarchical test when the arg is bound
0699:                // => args(e) and before(Exception e) will not mathch on catch(SubException e) ..
0700:                // is that required ? how AJ syntax behaves ?
0701:
0702:                TypePattern typePattern = node.getTypePattern();
0703:                TypePattern realPattern = typePattern;
0704:
0705:                // check if the arg is in the pointcut signature. In such a case, use the declared type
0706:                //TODO can we improve that with a lazy attach of the realTypePattern to the node
0707:                // and a method that always return the real pattern
0708:                // It must be lazy since args are not added at info ctor time [can be refactored..]
0709:                // do some filtering first to avoid unnecessary map lookup
0710:
0711:                int pointcutArgIndex = -1;
0712:                if (typePattern.getPattern().indexOf(".") < 0) {
0713:                    String boundedType = m_expressionInfo
0714:                            .getArgumentType(typePattern.getPattern());
0715:                    if (boundedType != null) {
0716:                        pointcutArgIndex = m_expressionInfo
0717:                                .getArgumentIndex(typePattern.getPattern());
0718:                        realPattern = TypePattern.compileTypePattern(
0719:                                boundedType,
0720:                                SubtypePatternType.NOT_HIERARCHICAL);
0721:                    }
0722:                }
0723:                // grab parameter from context
0724:                ExpressionContext ctx = (ExpressionContext) data;
0725:                ClassInfo argInfo = null;
0726:                try {
0727:                    if (ctx.getReflectionInfo() instanceof  MethodInfo) {
0728:                        argInfo = ((MethodInfo) ctx.getReflectionInfo())
0729:                                .getParameterTypes()[ctx
0730:                                .getCurrentTargetArgsIndex()];
0731:                    } else if (ctx.getReflectionInfo() instanceof  ConstructorInfo) {
0732:                        argInfo = ((ConstructorInfo) ctx.getReflectionInfo())
0733:                                .getParameterTypes()[ctx
0734:                                .getCurrentTargetArgsIndex()];
0735:                    } else if (ctx.getReflectionInfo() instanceof  FieldInfo) {
0736:                        argInfo = ((FieldInfo) ctx.getReflectionInfo())
0737:                                .getType();
0738:                    } else if (ctx.getPointcutType().equals(
0739:                            PointcutType.HANDLER)
0740:                            && ctx.getReflectionInfo() instanceof  ClassInfo) {
0741:                        argInfo = (ClassInfo) ctx.getReflectionInfo();
0742:                    }
0743:                } catch (ArrayIndexOutOfBoundsException e) {
0744:                    // ExpressionContext args are exhausted
0745:                    return Boolean.FALSE;
0746:                }
0747:                if (realPattern.matchType(argInfo)) {
0748:                    return Boolean.TRUE;
0749:                } else {
0750:                    return Boolean.FALSE;
0751:                }
0752:            }
0753:
0754:            public Object visit(ASTAttribute node, Object data) {
0755:                boolean matchAnnotation = false;
0756:                List annotations = (List) data;
0757:                for (Iterator it = annotations.iterator(); it.hasNext();) {
0758:                    AnnotationInfo annotation = (AnnotationInfo) it.next();
0759:                    if (annotation.getName().equals(node.getName())) {
0760:                        matchAnnotation = true;
0761:                    }
0762:                }
0763:                if (node.isNot()) {
0764:                    return Util.booleanValueOf(!matchAnnotation);
0765:                } else {
0766:                    return Util.booleanValueOf(matchAnnotation);
0767:                }
0768:            }
0769:
0770:            public Object visit(ASTModifier node, Object data) {
0771:                ReflectionInfo refInfo = (ReflectionInfo) data;
0772:                int modifiersToMatch = refInfo.getModifiers();
0773:                int modifierPattern = node.getModifier();
0774:                if (node.isNot()) {
0775:                    if ((modifierPattern & Modifier.PUBLIC) != 0) {
0776:                        if (((modifiersToMatch & Modifier.PUBLIC) == 0)) {
0777:                            return Boolean.TRUE;
0778:                        } else {
0779:                            return Boolean.FALSE;
0780:                        }
0781:                    } else if ((modifierPattern & Modifier.PROTECTED) != 0) {
0782:                        if ((modifiersToMatch & Modifier.PROTECTED) == 0) {
0783:                            return Boolean.TRUE;
0784:                        } else {
0785:                            return Boolean.FALSE;
0786:                        }
0787:                    } else if ((modifierPattern & Modifier.PRIVATE) != 0) {
0788:                        if ((modifiersToMatch & Modifier.PRIVATE) == 0) {
0789:                            return Boolean.TRUE;
0790:                        } else {
0791:                            return Boolean.FALSE;
0792:                        }
0793:                    } else if ((modifierPattern & Modifier.STATIC) != 0) {
0794:                        if ((modifiersToMatch & Modifier.STATIC) == 0) {
0795:                            return Boolean.TRUE;
0796:                        } else {
0797:                            return Boolean.FALSE;
0798:                        }
0799:                    } else if ((modifierPattern & Modifier.SYNCHRONIZED) != 0) {
0800:                        if ((modifiersToMatch & Modifier.SYNCHRONIZED) == 0) {
0801:                            return Boolean.TRUE;
0802:                        } else {
0803:                            return Boolean.FALSE;
0804:                        }
0805:                    } else if ((modifierPattern & Modifier.FINAL) != 0) {
0806:                        if ((modifiersToMatch & Modifier.FINAL) == 0) {
0807:                            return Boolean.TRUE;
0808:                        } else {
0809:                            return Boolean.FALSE;
0810:                        }
0811:                    } else if ((modifierPattern & Modifier.TRANSIENT) != 0) {
0812:                        if ((modifiersToMatch & Modifier.TRANSIENT) == 0) {
0813:                            return Boolean.TRUE;
0814:                        } else {
0815:                            return Boolean.FALSE;
0816:                        }
0817:                    } else if ((modifierPattern & Modifier.VOLATILE) != 0) {
0818:                        if ((modifiersToMatch & Modifier.VOLATILE) == 0) {
0819:                            return Boolean.TRUE;
0820:                        } else {
0821:                            return Boolean.FALSE;
0822:                        }
0823:                    } else if ((modifierPattern & Modifier.STRICT) != 0) {
0824:                        if ((modifiersToMatch & Modifier.STRICT) == 0) {
0825:                            return Boolean.TRUE;
0826:                        } else {
0827:                            return Boolean.FALSE;
0828:                        }
0829:                    } else {
0830:                        return Boolean.FALSE;
0831:                    }
0832:                } else {
0833:                    if ((modifierPattern & Modifier.PUBLIC) != 0) {
0834:                        if (((modifiersToMatch & Modifier.PUBLIC) == 0)) {
0835:                            return Boolean.FALSE;
0836:                        } else {
0837:                            return Boolean.TRUE;
0838:                        }
0839:                    } else if ((modifierPattern & Modifier.PROTECTED) != 0) {
0840:                        if ((modifiersToMatch & Modifier.PROTECTED) == 0) {
0841:                            return Boolean.FALSE;
0842:                        } else {
0843:                            return Boolean.TRUE;
0844:                        }
0845:                    } else if ((modifierPattern & Modifier.PRIVATE) != 0) {
0846:                        if ((modifiersToMatch & Modifier.PRIVATE) == 0) {
0847:                            return Boolean.FALSE;
0848:                        } else {
0849:                            return Boolean.TRUE;
0850:                        }
0851:                    } else if ((modifierPattern & Modifier.STATIC) != 0) {
0852:                        if ((modifiersToMatch & Modifier.STATIC) == 0) {
0853:                            return Boolean.FALSE;
0854:                        } else {
0855:                            return Boolean.TRUE;
0856:                        }
0857:                    } else if ((modifierPattern & Modifier.SYNCHRONIZED) != 0) {
0858:                        if ((modifiersToMatch & Modifier.SYNCHRONIZED) == 0) {
0859:                            return Boolean.FALSE;
0860:                        } else {
0861:                            return Boolean.TRUE;
0862:                        }
0863:                    } else if ((modifierPattern & Modifier.FINAL) != 0) {
0864:                        if ((modifiersToMatch & Modifier.FINAL) == 0) {
0865:                            return Boolean.FALSE;
0866:                        } else {
0867:                            return Boolean.TRUE;
0868:                        }
0869:                    } else if ((modifierPattern & Modifier.TRANSIENT) != 0) {
0870:                        if ((modifiersToMatch & Modifier.TRANSIENT) == 0) {
0871:                            return Boolean.FALSE;
0872:                        } else {
0873:                            return Boolean.TRUE;
0874:                        }
0875:                    } else if ((modifierPattern & Modifier.VOLATILE) != 0) {
0876:                        if ((modifiersToMatch & Modifier.VOLATILE) == 0) {
0877:                            return Boolean.FALSE;
0878:                        } else {
0879:                            return Boolean.TRUE;
0880:                        }
0881:                    } else if ((modifierPattern & Modifier.STRICT) != 0) {
0882:                        if ((modifiersToMatch & Modifier.STRICT) == 0) {
0883:                            return Boolean.FALSE;
0884:                        } else {
0885:                            return Boolean.TRUE;
0886:                        }
0887:                    } else {
0888:                        return Boolean.TRUE;
0889:                    }
0890:                }
0891:            }
0892:
0893:            protected boolean visitAttributes(SimpleNode node,
0894:                    ReflectionInfo refInfo) {
0895:                int nrChildren = node.jjtGetNumChildren();
0896:                if (nrChildren != 0) {
0897:                    for (int i = 0; i < nrChildren; i++) {
0898:                        Node child = node.jjtGetChild(i);
0899:                        if (child instanceof  ASTAttribute) {
0900:                            List annotations = refInfo.getAnnotations();
0901:                            if (Boolean.TRUE.equals(child.jjtAccept(this ,
0902:                                    annotations))) {
0903:                                continue;
0904:                            } else {
0905:                                return false;
0906:                            }
0907:                        }
0908:                    }
0909:                }
0910:                return true;
0911:            }
0912:
0913:            protected boolean visitModifiers(SimpleNode node,
0914:                    ReflectionInfo refInfo) {
0915:                int nrChildren = node.jjtGetNumChildren();
0916:                if (nrChildren != 0) {
0917:                    for (int i = 0; i < nrChildren; i++) {
0918:                        Node child = node.jjtGetChild(i);
0919:                        if (child instanceof  ASTModifier) {
0920:                            if (Boolean.TRUE.equals(child.jjtAccept(this ,
0921:                                    refInfo))) {
0922:                                continue;
0923:                            } else {
0924:                                return false;
0925:                            }
0926:                        }
0927:                    }
0928:                }
0929:                return true;
0930:            }
0931:
0932:            protected boolean visitParameters(SimpleNode node,
0933:                    ClassInfo[] parameterTypes) {
0934:                int nrChildren = node.jjtGetNumChildren();
0935:                if (nrChildren <= 0) {
0936:                    return (parameterTypes.length == 0);
0937:                }
0938:
0939:                // collect the parameter nodes
0940:                List parameterNodes = new ArrayList();
0941:                for (int i = 0; i < nrChildren; i++) {
0942:                    Node child = node.jjtGetChild(i);
0943:                    if (child instanceof  ASTParameter) {
0944:                        parameterNodes.add(child);
0945:                    }
0946:                }
0947:
0948:                if (parameterNodes.size() <= 0) {
0949:                    return (parameterTypes.length == 0);
0950:                }
0951:
0952:                //TODO duplicate code with args() match
0953:                //TODO refactor parameterNodes in an array for faster match
0954:
0955:                // look for eager pattern at the beginning and end
0956:                int expressionParameterCount = parameterNodes.size();
0957:                boolean isFirstArgEager = ((ASTParameter) parameterNodes.get(0))
0958:                        .getDeclaringClassPattern().isEagerWildCard();
0959:                boolean isLastArgEager = ((ASTParameter) parameterNodes
0960:                        .get(expressionParameterCount - 1))
0961:                        .getDeclaringClassPattern().isEagerWildCard();
0962:                // foo(..)
0963:                if (isFirstArgEager && expressionParameterCount == 1) {
0964:                    return true;
0965:                }
0966:                int contextParametersCount = parameterTypes.length;
0967:                if (isFirstArgEager && isLastArgEager) {
0968:                    expressionParameterCount -= 2;
0969:                    if (expressionParameterCount == 0) {
0970:                        // foo(.., ..)
0971:                        return true;
0972:                    }
0973:                    // we need to find a starting position - foo(..,int, bar, ..)
0974:                    // foo(int) //int is ok
0975:                    // foo(bar,int,bar) //int is ok
0976:                    // foo(bar,int,foo,int,bar) // int is ok, but then we fail, so move on to next..
0977:                    int matchCount = 0;
0978:                    int ictx = 0;
0979:                    for (int iexp = 0; iexp < expressionParameterCount; iexp++) {
0980:                        if (ictx >= contextParametersCount) {
0981:                            // too many args in foo()
0982:                            matchCount = -1;
0983:                            break;
0984:                        }
0985:                        // do we have an eager wildcard in the middle ?
0986:                        ASTParameter parameterNode = (ASTParameter) parameterNodes
0987:                                .get(iexp + 1);
0988:                        boolean isEager = parameterNode
0989:                                .getDeclaringClassPattern().isEagerWildCard();
0990:                        if (isEager) {
0991:                            // TODO - ignore for now, but not really supported - eager in the middle will match one
0992:                        }
0993:                        if (Boolean.TRUE.equals((Boolean) parameterNode
0994:                                .jjtAccept(this , parameterTypes[ictx]))) {
0995:                            matchCount += 1;
0996:                            ictx++;
0997:                        } else {
0998:                            // assume matched by starting ".." and rewind expression index
0999:                            matchCount = 0;
1000:                            ictx++;
1001:                            iexp = -1;
1002:                        }
1003:                    }
1004:                    if (matchCount == expressionParameterCount) {
1005:                        return true;
1006:                    } else {
1007:                        return false;
1008:                    }
1009:                } else if (isFirstArgEager) {
1010:                    expressionParameterCount--;
1011:                    if (contextParametersCount >= expressionParameterCount) {
1012:                        // do a match from last to first, break when foo() nodes are exhausted
1013:                        for (int i = 0; (i < contextParametersCount)
1014:                                && (expressionParameterCount - i >= 0); i++) {
1015:                            ASTParameter parameterNode = (ASTParameter) parameterNodes
1016:                                    .get(expressionParameterCount - i);
1017:                            if (Boolean.TRUE
1018:                                    .equals((Boolean) parameterNode
1019:                                            .jjtAccept(
1020:                                                    this ,
1021:                                                    parameterTypes[contextParametersCount
1022:                                                            - 1 - i]))) {
1023:                                ;//go on with "next" param
1024:                            } else {
1025:                                return false;
1026:                            }
1027:                        }
1028:                        return true;
1029:                    } else {
1030:                        //foo() as more param than context we try to match
1031:                        return false;
1032:                    }
1033:                } else if (isLastArgEager) {
1034:                    expressionParameterCount--;
1035:                    if (contextParametersCount >= expressionParameterCount) {
1036:                        // do a match from first to last, break when foo() nodes are exhausted
1037:                        for (int i = 0; (i < contextParametersCount)
1038:                                && (i < expressionParameterCount); i++) {
1039:                            ASTParameter parameterNode = (ASTParameter) parameterNodes
1040:                                    .get(i);
1041:                            if (Boolean.TRUE.equals((Boolean) parameterNode
1042:                                    .jjtAccept(this , parameterTypes[i]))) {
1043:                                ;//go on with next param
1044:                            } else {
1045:                                return false;
1046:                            }
1047:                        }
1048:                        return true;
1049:                    } else {
1050:                        return false;
1051:                    }
1052:                } else {
1053:                    // no eager wildcard in foo()
1054:                    // check that param length are equals
1055:                    if (expressionParameterCount == contextParametersCount) {
1056:                        for (int i = 0; i < parameterNodes.size(); i++) {
1057:                            ASTParameter parameterNode = (ASTParameter) parameterNodes
1058:                                    .get(i);
1059:                            if (Boolean.TRUE.equals((Boolean) parameterNode
1060:                                    .jjtAccept(this , parameterTypes[i]))) {
1061:                                ;//go on with next param
1062:                            } else {
1063:                                return false;
1064:                            }
1065:                        }
1066:                        return true;
1067:                    } else {
1068:                        return false;
1069:                    }
1070:                }
1071:            }
1072:
1073:            /**
1074:             * Returns the string representation of the expression.
1075:             *
1076:             * @return
1077:             */
1078:            public String toString() {
1079:                return m_expression;
1080:            }
1081:
1082:            /**
1083:             * Returns the number of parameters to the target method/constructor else -1.
1084:             *
1085:             * @param ctx
1086:             * @return
1087:             */
1088:            private int getParametersCount(final ExpressionContext ctx) {
1089:                ReflectionInfo reflectionInfo = ctx.getReflectionInfo();
1090:                if (reflectionInfo instanceof  MethodInfo) {
1091:                    return ((MethodInfo) reflectionInfo).getParameterTypes().length;
1092:                } else if (reflectionInfo instanceof  ConstructorInfo) {
1093:                    return ((ConstructorInfo) reflectionInfo)
1094:                            .getParameterTypes().length;
1095:                } else if (reflectionInfo instanceof  FieldInfo) {
1096:                    return 1;//field set support for args()
1097:                } else if (ctx.getPointcutType().equals(PointcutType.HANDLER)
1098:                        && reflectionInfo instanceof  ClassInfo) {
1099:                    // handler args(e) binding
1100:                    return 1;
1101:                } else {
1102:                    return -1;
1103:                }
1104:            }
1105:
1106:            /**
1107:             * Test the context upon the expression tree, under a node that can
1108:             * contain annotations.
1109:             * 
1110:             * @param node	root node of the annotation expression
1111:             * @param reflectInfo context reflection info
1112:             * 
1113:             * @return <CODE>Boolean.TRUE</CODE> in case the <tt>reflectInfo</tt> match
1114:             * 		   the expression subtree, <CODE>Boolean.FALSE</CODE> otherwise.
1115:             */
1116:            protected Object visitAnnotatedNode(SimpleNode node,
1117:                    ReflectionInfo reflectInfo) {
1118:                // In an annotated subtree, only the last child node may represent the pattern
1119:                Node patternNode = node
1120:                        .jjtGetChild(node.jjtGetNumChildren() - 1);
1121:                if (!(patternNode instanceof  ASTAttribute)) {
1122:                    if (Boolean.FALSE.equals((Boolean) patternNode.jjtAccept(
1123:                            this , reflectInfo))) {
1124:                        return Boolean.FALSE;
1125:                    }
1126:                }
1127:
1128:                boolean matchedAnnotations = visitAttributes(node, reflectInfo);
1129:                if (!matchedAnnotations) {
1130:                    return Boolean.FALSE;
1131:                } else {
1132:                    return Boolean.TRUE;
1133:                }
1134:            }
1135:
1136:            /**
1137:             * Access the ASTRoot we visit
1138:             *
1139:             * @return
1140:             */
1141:            public Node getASTRoot() {
1142:                return m_root;
1143:            }
1144:
1145:            /**
1146:             * Access the ExpressionInfo we are build on
1147:             *
1148:             * @return
1149:             */
1150:            public ExpressionInfo getExpressionInfo() {
1151:                return m_expressionInfo;
1152:            }
1153:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.