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
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
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 }