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.cflow;
9   
10  import org.codehaus.aspectwerkz.expression.ast.ExpressionParserVisitor;
11  import org.codehaus.aspectwerkz.expression.ast.SimpleNode;
12  import org.codehaus.aspectwerkz.expression.ast.ASTRoot;
13  import org.codehaus.aspectwerkz.expression.ast.ASTExpression;
14  import org.codehaus.aspectwerkz.expression.ast.ASTAnd;
15  import org.codehaus.aspectwerkz.expression.ast.ASTOr;
16  import org.codehaus.aspectwerkz.expression.ast.ASTNot;
17  import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference;
18  import org.codehaus.aspectwerkz.expression.ast.ASTExecution;
19  import org.codehaus.aspectwerkz.expression.ast.ASTCall;
20  import org.codehaus.aspectwerkz.expression.ast.ASTSet;
21  import org.codehaus.aspectwerkz.expression.ast.ASTGet;
22  import org.codehaus.aspectwerkz.expression.ast.ASTHandler;
23  import org.codehaus.aspectwerkz.expression.ast.ASTWithin;
24  import org.codehaus.aspectwerkz.expression.ast.ASTWithinCode;
25  import org.codehaus.aspectwerkz.expression.ast.ASTStaticInitialization;
26  import org.codehaus.aspectwerkz.expression.ast.ASTCflow;
27  import org.codehaus.aspectwerkz.expression.ast.ASTCflowBelow;
28  import org.codehaus.aspectwerkz.expression.ast.ASTArgs;
29  import org.codehaus.aspectwerkz.expression.ast.ASTHasMethod;
30  import org.codehaus.aspectwerkz.expression.ast.ASTHasField;
31  import org.codehaus.aspectwerkz.expression.ast.ASTTarget;
32  import org.codehaus.aspectwerkz.expression.ast.ASTThis;
33  import org.codehaus.aspectwerkz.expression.ast.ASTClassPattern;
34  import org.codehaus.aspectwerkz.expression.ast.ASTMethodPattern;
35  import org.codehaus.aspectwerkz.expression.ast.ASTConstructorPattern;
36  import org.codehaus.aspectwerkz.expression.ast.ASTFieldPattern;
37  import org.codehaus.aspectwerkz.expression.ast.ASTParameter;
38  import org.codehaus.aspectwerkz.expression.ast.ASTArgParameter;
39  import org.codehaus.aspectwerkz.expression.ast.ASTAttribute;
40  import org.codehaus.aspectwerkz.expression.ast.ASTModifier;
41  import org.codehaus.aspectwerkz.expression.ast.Node;
42  import org.codehaus.aspectwerkz.expression.ExpressionNamespace;
43  import org.codehaus.aspectwerkz.expression.ExpressionInfo;
44  
45  import java.util.List;
46  
47  /***
48   * A visitor to create the bindings between cflow aspect and cflow subexpression.
49   * For each visited cflow / cflowbelow node, one CflowBinding is created
50   * with the cflow(below) subexpression as expressionInfo.
51   *
52   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
53   */
54  public class CflowAspectExpressionVisitor implements ExpressionParserVisitor {
55  
56      private ExpressionInfo m_expressionInfo;
57      private Node m_root;
58      private String m_namespace;
59  
60      public CflowAspectExpressionVisitor(ExpressionInfo expressionInfo, Node root, String namespace) {
61          m_expressionInfo = expressionInfo;
62          m_root = root;
63          m_namespace = namespace;
64      }
65  
66      /***
67       * Visit the expression and populate the list with CflowBinding for each cflow() or cflowbelow()
68       * subexpression encountered (including thru pointcut references)
69       *
70       * @param bindings
71       * @return the list of bindings
72       */
73      public List populateCflowAspectBindings(List bindings) {
74          visit(m_root, bindings);
75          return bindings;
76      }
77  
78      public Object visit(Node node, Object data) {
79          return node.jjtGetChild(0).jjtAccept(this, data);
80      }
81  
82      public Object visit(SimpleNode node, Object data) {
83          return node.jjtGetChild(0).jjtAccept(this, data);
84      }
85  
86      public Object visit(ASTRoot node, Object data) {
87          return node.jjtGetChild(0).jjtAccept(this, data);
88      }
89  
90      public Object visit(ASTExpression node, Object data) {
91          return node.jjtGetChild(0).jjtAccept(this, data);
92      }
93  
94      public Object visit(ASTAnd node, Object data) {
95          // the AND and OR can have more than 2 nodes [see jjt grammar]
96          for (int i = 0; i < node.jjtGetNumChildren(); i++) {
97              node.jjtGetChild(i).jjtAccept(this, data);
98          }
99          return data;
100     }
101 
102     public Object visit(ASTOr node, Object data) {
103         // the AND and OR can have more than 2 nodes [see jjt grammar]
104         for (int i = 0; i < node.jjtGetNumChildren(); i++) {
105             node.jjtGetChild(i).jjtAccept(this, data);
106         }
107         return data;
108     }
109 
110     public Object visit(ASTNot node, Object data) {
111         return node.jjtGetChild(0).jjtAccept(this, data);
112     }
113 
114     /***
115      * Resolve pointcut references
116      *
117      * @param node
118      * @param data
119      * @return
120      */
121     public Object visit(ASTPointcutReference node, Object data) {
122         ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace);
123         CflowAspectExpressionVisitor expression = namespace.getExpressionInfo(node.getName()).getCflowAspectExpression();
124         return expression.populateCflowAspectBindings((List)data);
125     }
126 
127     public Object visit(ASTExecution node, Object data) {
128         return data;
129     }
130 
131     public Object visit(ASTCall node, Object data) {
132         return data;
133     }
134 
135     public Object visit(ASTSet node, Object data) {
136         return data;
137     }
138 
139     public Object visit(ASTGet node, Object data) {
140         return data;
141     }
142 
143     public Object visit(ASTHandler node, Object data) {
144         return data;
145     }
146 
147     public Object visit(ASTWithin node, Object data) {
148         return data;
149     }
150 
151     public Object visit(ASTWithinCode node, Object data) {
152         return data;
153     }
154 
155     public Object visit(ASTStaticInitialization node, Object data) {
156         return data;
157     }
158 
159     /***
160      * build a cflow binding with the cflow sub expression
161      *
162      * @param node
163      * @param data
164      * @return
165      */
166     public Object visit(ASTCflow node, Object data) {
167         int cflowID = node.hashCode();
168         Node subNode = node.jjtGetChild(0);
169         ExpressionInfo subExpression = new ExpressionInfo(subNode, m_namespace);
170         subExpression.inheritPossibleArgumentFrom(m_expressionInfo);
171         ((List)data).add(new CflowBinding(cflowID, subExpression, m_expressionInfo, false));
172         return data;
173     }
174 
175     /***
176      * build a cflowbelow binding with the cflowbelow sub expression
177      *
178      * @param node
179      * @param data
180      * @return
181      */
182     public Object visit(ASTCflowBelow node, Object data) {
183         int cflowID = node.hashCode();
184         Node subNode = node.jjtGetChild(0);
185         ExpressionInfo subExpression = new ExpressionInfo(subNode, m_namespace);
186         subExpression.inheritPossibleArgumentFrom(m_expressionInfo);
187         ((List)data).add(new CflowBinding(cflowID, subExpression, m_expressionInfo, true));
188         return data;
189     }
190 
191     public Object visit(ASTArgs node, Object data) {
192         return data;
193     }
194 
195     public Object visit(ASTHasMethod node, Object data) {
196         return data;
197     }
198 
199     public Object visit(ASTHasField node, Object data) {
200         return data;
201     }
202 
203     public Object visit(ASTTarget node, Object data) {
204         return data;
205     }
206 
207     public Object visit(ASTThis node, Object data) {
208         return data;
209     }
210 
211     public Object visit(ASTClassPattern node, Object data) {
212         throw new UnsupportedOperationException("Should not be reached");
213     }
214 
215     public Object visit(ASTMethodPattern node, Object data) {
216         throw new UnsupportedOperationException("Should not be reached");
217     }
218 
219     public Object visit(ASTConstructorPattern node, Object data) {
220         throw new UnsupportedOperationException("Should not be reached");
221     }
222 
223     public Object visit(ASTFieldPattern node, Object data) {
224         throw new UnsupportedOperationException("Should not be reached");
225     }
226 
227     public Object visit(ASTParameter node, Object data) {
228         throw new UnsupportedOperationException("Should not be reached");
229     }
230 
231     public Object visit(ASTArgParameter node, Object data) {
232         throw new UnsupportedOperationException("Should not be reached");
233     }
234 
235     public Object visit(ASTAttribute node, Object data) {
236         throw new UnsupportedOperationException("Should not be reached");
237     }
238 
239     public Object visit(ASTModifier node, Object data) {
240         throw new UnsupportedOperationException("Should not be reached");
241     }
242 }