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.reflect.ClassInfo;
11 import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
12 import org.codehaus.aspectwerkz.reflect.FieldInfo;
13 import org.codehaus.aspectwerkz.reflect.MethodInfo;
14 import org.codehaus.aspectwerkz.reflect.ReflectionInfo;
15 import org.codehaus.aspectwerkz.reflect.StaticInitializationInfo;
16
17 import gnu.trove.TIntIntHashMap;
18 import gnu.trove.TObjectIntHashMap;
19
20 /***
21 * The expression context for AST evaluation.
22 *
23 * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
24 * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
25 */
26 public class ExpressionContext {
27 public static final int INFO_NOT_AVAILABLE = -1;
28
29 public static final int METHOD_INFO = 0;
30
31 public static final int CONSTRUCTOR_INFO = 1;
32
33 public static final int FIELD_INFO = 2;
34
35 public static final int CLASS_INFO = 3;
36
37 private static final int STATIC_INFO = 4;
38
39 private final int m_reflectionInfoType;
40
41 private final PointcutType m_pointcutType;
42
43 private final ReflectionInfo m_matchingReflectionInfo;
44
45 private final ReflectionInfo m_withinReflectionInfo;
46
47 private boolean m_inCflowSubAST = false;
48
49 private boolean m_cflowEvaluation = false;
50
51 private boolean m_hasBeenVisitingCflow = false;
52
53 private int m_currentTargetArgsIndex = 0;
54
55 /***
56 * Expression to advised target (method / ctor) argument index map.
57 * It depends on the matching context and the pointcut signature, as well as args(..)
58 */
59 public gnu.trove.TObjectIntHashMap m_exprIndexToTargetIndex = new TObjectIntHashMap();
60
61 /***
62 * The variable name corresponding to the this(..) designator,
63 * or null if nothing is bound (this(<type>) or no this(..))
64 */
65 public String m_thisBoundedName = null;
66
67 /***
68 * The variable name corresponding to the target(..) designator,
69 * or null if nothing is bound (target(<type>) or no target(..))
70 */
71 public String m_targetBoundedName = null;
72
73 /***
74 * Set to true when we encounter a poincut using target(..) and when match cannot be done without a
75 * runtime check with instance of.
76 */
77 public boolean m_targetWithRuntimeCheck = false;
78
79 /***
80 * Creates a new expression context.
81 *
82 * @param pointcutType
83 * @param reflectionInfo - can be null f.e. with early evaluation of CALL pointcut
84 * @param withinReflectionInfo
85 */
86 public ExpressionContext(final PointcutType pointcutType,
87 final ReflectionInfo reflectionInfo,
88 final ReflectionInfo withinReflectionInfo) {
89 if (pointcutType == null) {
90 throw new IllegalArgumentException("pointcut type can not be null");
91 }
92 m_pointcutType = pointcutType;
93 m_matchingReflectionInfo = reflectionInfo;
94 if (withinReflectionInfo != null) {
95 m_withinReflectionInfo = withinReflectionInfo;
96 } else {
97 if (PointcutType.EXECUTION.equals(pointcutType)
98 || PointcutType.STATIC_INITIALIZATION.equals(pointcutType)
99 || PointcutType.WITHIN.equals(pointcutType)) {
100 m_withinReflectionInfo = m_matchingReflectionInfo;
101 } else {
102 m_withinReflectionInfo = null;
103 }
104 }
105 if (reflectionInfo instanceof MethodInfo) {
106 m_reflectionInfoType = METHOD_INFO;
107 } else if (reflectionInfo instanceof ConstructorInfo) {
108 m_reflectionInfoType = CONSTRUCTOR_INFO;
109 } else if (reflectionInfo instanceof FieldInfo) {
110 m_reflectionInfoType = FIELD_INFO;
111 } else if (reflectionInfo instanceof ClassInfo) {
112 m_reflectionInfoType = CLASS_INFO;
113 } else if (reflectionInfo instanceof StaticInitializationInfo) {
114 m_reflectionInfoType = STATIC_INFO;
115 } else {
116 m_reflectionInfoType = INFO_NOT_AVAILABLE;
117 }
118 }
119
120 public ReflectionInfo getReflectionInfo() {
121 return m_matchingReflectionInfo;
122 }
123
124 public ReflectionInfo getWithinReflectionInfo() {
125 return m_withinReflectionInfo;
126 }
127
128 public boolean hasExecutionPointcut() {
129 return m_pointcutType.equals(PointcutType.EXECUTION);
130 }
131
132 public boolean hasCallPointcut() {
133 return m_pointcutType.equals(PointcutType.CALL);
134 }
135
136 public boolean hasSetPointcut() {
137 return m_pointcutType.equals(PointcutType.SET);
138 }
139
140 public boolean hasGetPointcut() {
141 return m_pointcutType.equals(PointcutType.GET);
142 }
143
144 public boolean hasHandlerPointcut() {
145 return m_pointcutType.equals(PointcutType.HANDLER);
146 }
147
148 public boolean hasStaticInitializationPointcut() {
149 return m_pointcutType.equals(PointcutType.STATIC_INITIALIZATION);
150 }
151
152 public boolean hasWithinPointcut() {
153 return m_pointcutType.equals(PointcutType.WITHIN);
154 }
155
156
157
158
159
160
161
162
163
164 public boolean hasWithinReflectionInfo() {
165 return m_withinReflectionInfo != null;
166 }
167
168 public boolean hasMethodInfo() {
169 return m_reflectionInfoType == METHOD_INFO;
170 }
171
172 public boolean hasConstructorInfo() {
173 return m_reflectionInfoType == CONSTRUCTOR_INFO;
174 }
175
176 public boolean hasFieldInfo() {
177 return m_reflectionInfoType == FIELD_INFO;
178 }
179
180 public boolean hasClassInfo() {
181 return m_reflectionInfoType == CLASS_INFO;
182 }
183
184 public boolean hasReflectionInfo() {
185 return m_reflectionInfoType != INFO_NOT_AVAILABLE;
186 }
187
188 public void setInCflowSubAST(final boolean inCflowAST) {
189 m_inCflowSubAST = inCflowAST;
190 }
191
192 public boolean inCflowSubAST() {
193 return m_inCflowSubAST;
194 }
195
196 public void setHasBeenVisitingCflow(final boolean hasBeenVisitingCflow) {
197 m_hasBeenVisitingCflow = hasBeenVisitingCflow;
198 }
199
200 public boolean hasBeenVisitingCflow() {
201 return m_hasBeenVisitingCflow;
202 }
203
204 public boolean getCflowEvaluation() {
205 return m_cflowEvaluation;
206 }
207
208 public void setCflowEvaluation(boolean cflowEvaluation) {
209 m_cflowEvaluation = cflowEvaluation;
210 }
211
212 public int getCurrentTargetArgsIndex() {
213 return m_currentTargetArgsIndex;
214 }
215
216 public void setCurrentTargetArgsIndex(int argsIndex) {
217 this.m_currentTargetArgsIndex = argsIndex;
218 }
219
220 public boolean equals(Object o) {
221 if (this == o) {
222 return true;
223 }
224 if (!(o instanceof ExpressionContext)) {
225 return false;
226 }
227 final ExpressionContext expressionContext = (ExpressionContext) o;
228 if (m_reflectionInfoType != expressionContext.m_reflectionInfoType) {
229 return false;
230 }
231 if (!m_matchingReflectionInfo.equals(expressionContext.m_matchingReflectionInfo)) {
232 return false;
233 }
234 if (!m_pointcutType.equals(expressionContext.m_pointcutType)) {
235 return false;
236 }
237 if ((m_withinReflectionInfo != null) ?
238 (!m_withinReflectionInfo
239 .equals(expressionContext.m_withinReflectionInfo)) :
240 (expressionContext.m_withinReflectionInfo != null)) {
241 return false;
242 }
243 return true;
244 }
245
246 public int hashCode() {
247 int result;
248 result = m_pointcutType.hashCode();
249 result = (29 * result) + m_matchingReflectionInfo.hashCode();
250 result = (29 * result) + ((m_withinReflectionInfo != null) ? m_withinReflectionInfo.hashCode() : 0);
251 result = (29 * result) + m_reflectionInfoType;
252 return result;
253 }
254
255 public PointcutType getPointcutType() {
256 return m_pointcutType;
257 }
258
259 public void resetRuntimeState() {
260 m_targetBoundedName = null;
261 m_thisBoundedName = null;
262 m_exprIndexToTargetIndex = new TObjectIntHashMap();
263 m_targetWithRuntimeCheck = false;
264 }
265 }