View Javadoc

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.expression.ast.ASTCall;
11  import org.codehaus.aspectwerkz.expression.ast.ASTCflow;
12  import org.codehaus.aspectwerkz.expression.ast.ASTCflowBelow;
13  import org.codehaus.aspectwerkz.expression.ast.ASTExecution;
14  import org.codehaus.aspectwerkz.expression.ast.ASTGet;
15  import org.codehaus.aspectwerkz.expression.ast.ASTHandler;
16  import org.codehaus.aspectwerkz.expression.ast.ASTHasField;
17  import org.codehaus.aspectwerkz.expression.ast.ASTHasMethod;
18  import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference;
19  import org.codehaus.aspectwerkz.expression.ast.ASTRoot;
20  import org.codehaus.aspectwerkz.expression.ast.ASTSet;
21  import org.codehaus.aspectwerkz.expression.ast.ASTStaticInitialization;
22  import org.codehaus.aspectwerkz.expression.ast.ASTWithin;
23  import org.codehaus.aspectwerkz.expression.ast.ASTWithinCode;
24  import org.codehaus.aspectwerkz.expression.ast.Node;
25  import org.codehaus.aspectwerkz.expression.ast.ASTNot;
26  
27  /***
28   * The advised cflow class filter visitor.
29   * If the expression does not contains any cflow, it returns FALSE.
30   * 
31   * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
32   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
33   * @author Michael Nascimento
34   */
35  public class AdvisedCflowClassFilterExpressionVisitor extends AdvisedClassFilterExpressionVisitor {
36  
37      /***
38       * The expressionInfo this visitor is built on
39       */
40      private ExpressionInfo m_expressionInfo;
41  
42      /***
43       * Creates a new cflow expression.
44       * 
45       * @param expression the expression as a string
46       * @param namespace the namespace
47       * @param root the AST root
48       */
49      public AdvisedCflowClassFilterExpressionVisitor(final ExpressionInfo expressionInfo, final String expression, final String namespace, final ASTRoot root) {
50          super(expression, namespace, root);
51          m_expressionInfo = expressionInfo;
52      }
53  
54      /***
55       * Matches the expression context.
56       * 
57       * @param context
58       * @return
59       */
60      public boolean match(final ExpressionContext context) {
61          if (!m_expressionInfo.hasCflowPointcut()) {
62              return false;
63          }
64          Boolean match = ((Boolean) visit(m_root, context));
65          if (context.hasBeenVisitingCflow()) {
66              // undeterministic is assumed to be "true" at this stage
67              // since it won't be composed anymore with a NOT (unless
68              // thru pointcut reference ie a new visitor)
69              return (match!=null)?match.booleanValue():true;
70          } else {
71              return true;
72          }
73      }
74  
75      public Object visit(ASTNot node, Object data) {
76          ExpressionContext context = (ExpressionContext) data;
77          if (context.inCflowSubAST()) {
78              return super.visit(node, data);
79          } else {
80              // ignore the NOT
81              return Boolean.TRUE;
82          }
83      }
84  
85  
86      public Object visit(ASTCflow node, Object data) {
87          ExpressionContext context = (ExpressionContext) data;
88          context.setHasBeenVisitingCflow(true);
89          context.setInCflowSubAST(true);
90          Node child = node.jjtGetChild(0);
91          Object result;
92  
93  //        // if 'call' or 'handler' but no 'within*' then return true
94  //        if (child instanceof ASTCall || child instanceof ASTHandler) {
95  //            result = Boolean.TRUE;
96  //        } else {
97  //            result = child.jjtAccept(this, context);
98  //        }
99          result = child.jjtAccept(this, context);
100         context.setInCflowSubAST(false);
101         return result;
102     }
103 
104     public Object visit(ASTCflowBelow node, Object data) {
105         ExpressionContext context = (ExpressionContext) data;
106         context.setHasBeenVisitingCflow(true);
107         context.setInCflowSubAST(true);
108         Node child = node.jjtGetChild(0);
109         Object result;
110 
111 //        // if 'call' or 'handler' but no 'within*' then return true
112 //        if (child instanceof ASTCall || child instanceof ASTHandler) {
113 //            result = Boolean.TRUE;
114 //        } else {
115 //            result = child.jjtAccept(this, context);
116 //        }
117         result = child.jjtAccept(this, context);
118         context.setInCflowSubAST(false);
119         return result;
120     }
121 
122     public Object visit(ASTPointcutReference node, Object data) {
123         ExpressionContext context = (ExpressionContext) data;
124         ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace);
125         AdvisedCflowClassFilterExpressionVisitor reference = namespace.getAdvisedCflowClassExpression(node.getName());
126         if (!reference.m_expressionInfo.hasCflowPointcut()) {
127             // ignore sub expression without cflow(...) expressions
128             return Boolean.TRUE;
129         }
130         return new Boolean(reference.match(context));
131     }
132 
133     public Object visit(ASTExecution node, Object data) {
134         ExpressionContext context = (ExpressionContext) data;
135         if (context.inCflowSubAST()) {
136             return super.visit(node, data);
137         } else {
138             return Boolean.TRUE;
139         }
140     }
141 
142     public Object visit(ASTCall node, Object data) {
143         ExpressionContext context = (ExpressionContext) data;
144         if (context.inCflowSubAST()) {
145             return super.visit(node, data);
146         } else {
147             return Boolean.TRUE;
148         }
149     }
150 
151     public Object visit(ASTSet node, Object data) {
152         ExpressionContext context = (ExpressionContext) data;
153         if (context.inCflowSubAST()) {
154             return super.visit(node, data);
155         } else {
156             return Boolean.TRUE;
157         }
158     }
159 
160     public Object visit(ASTGet node, Object data) {
161         ExpressionContext context = (ExpressionContext) data;
162         if (context.inCflowSubAST()) {
163             return super.visit(node, data);
164         } else {
165             return Boolean.TRUE;
166         }
167     }
168 
169     public Object visit(ASTHandler node, Object data) {
170         ExpressionContext context = (ExpressionContext) data;
171         if (context.inCflowSubAST()) {
172             return super.visit(node, data);
173         } else {
174             return Boolean.TRUE;
175         }
176     }
177 
178     public Object visit(ASTStaticInitialization node, Object data) {
179         ExpressionContext context = (ExpressionContext) data;
180         if (context.inCflowSubAST()) {
181             return super.visit(node, data);
182         } else {
183             return Boolean.TRUE;
184         }
185     }
186 
187     public Object visit(ASTWithin node, Object data) {
188         ExpressionContext context = (ExpressionContext) data;
189         if (context.inCflowSubAST()) {
190             return super.visit(node, data);
191         } else {
192             return Boolean.TRUE;
193         }
194     }
195 
196     public Object visit(ASTWithinCode node, Object data) {
197         ExpressionContext context = (ExpressionContext) data;
198         if (context.inCflowSubAST()) {
199             return super.visit(node, data);
200         } else {
201             return Boolean.TRUE;
202         }
203     }
204 
205     public Object visit(ASTHasMethod node, Object data) {
206         ExpressionContext context = (ExpressionContext) data;
207         if (context.inCflowSubAST()) {
208             return super.visit(node, data);
209         } else {
210             return Boolean.TRUE;
211         }
212     }
213 
214     public Object visit(ASTHasField node, Object data) {
215         ExpressionContext context = (ExpressionContext) data;
216         if (context.inCflowSubAST()) {
217             return super.visit(node, data);
218         } else {
219             return Boolean.TRUE;
220         }
221     }
222 }