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
67
68
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
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
94
95
96
97
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
112
113
114
115
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
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 }