001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.aspectwerkz.expression;
005:
006: import com.tc.aspectwerkz.reflect.ReflectionInfo;
007: import com.tc.aspectwerkz.reflect.MethodInfo;
008: import com.tc.aspectwerkz.reflect.ConstructorInfo;
009: import com.tc.aspectwerkz.reflect.StaticInitializationInfo;
010: import com.tc.aspectwerkz.reflect.ClassInfo;
011: import com.tc.aspectwerkz.reflect.FieldInfo;
012:
013: import java.util.HashMap;
014:
015: /**
016: * The expression context for AST evaluation.
017: *
018: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
019: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
020: */
021: public class ExpressionContext {
022: public static final int INFO_NOT_AVAILABLE = -1;
023:
024: public static final int METHOD_INFO = 0;
025:
026: public static final int CONSTRUCTOR_INFO = 1;
027:
028: public static final int FIELD_INFO = 2;
029:
030: public static final int CLASS_INFO = 3;
031:
032: private static final int STATIC_INFO = 4;
033:
034: private final int m_reflectionInfoType;
035:
036: private final PointcutType m_pointcutType;
037:
038: private final ReflectionInfo m_matchingReflectionInfo;
039:
040: private final ReflectionInfo m_withinReflectionInfo;
041:
042: private boolean m_inCflowSubAST = false;
043:
044: private boolean m_cflowEvaluation = false;
045:
046: private boolean m_hasBeenVisitingCflow = false;
047:
048: private int m_currentTargetArgsIndex = 0;
049:
050: /**
051: * Expression to advised target (method / ctor) argument index map.
052: * It depends on the matching context and the pointcut signature, as well as args(..)
053: *
054: * Value of this field is cloned, so had to use HashMap type.
055: */
056: public HashMap m_exprIndexToTargetIndex = new HashMap();
057:
058: /**
059: * The variable name corresponding to the this(..) designator,
060: * or null if nothing is bound (this(<type>) or no this(..))
061: */
062: public String m_this BoundedName = null;
063:
064: /**
065: * The variable name corresponding to the target(..) designator,
066: * or null if nothing is bound (target(<type>) or no target(..))
067: */
068: public String m_targetBoundedName = null;
069:
070: /**
071: * Set to true when we encounter a poincut using target(..) and when match cannot be done without a
072: * runtime check with instance of.
073: */
074: public boolean m_targetWithRuntimeCheck = false;
075:
076: /**
077: * Creates a new expression context.
078: *
079: * @param pointcutType
080: * @param reflectionInfo - can be null f.e. with early evaluation of CALL pointcut
081: * @param withinReflectionInfo
082: */
083: public ExpressionContext(final PointcutType pointcutType,
084: final ReflectionInfo reflectionInfo,
085: final ReflectionInfo withinReflectionInfo) {
086: if (pointcutType == null) {
087: throw new IllegalArgumentException(
088: "pointcut type can not be null");
089: }
090: m_pointcutType = pointcutType;
091: m_matchingReflectionInfo = reflectionInfo;
092: if (withinReflectionInfo != null) {
093: m_withinReflectionInfo = withinReflectionInfo;
094: } else {
095: if (PointcutType.EXECUTION.equals(pointcutType)
096: || PointcutType.STATIC_INITIALIZATION
097: .equals(pointcutType)
098: || PointcutType.WITHIN.equals(pointcutType)) {
099: m_withinReflectionInfo = m_matchingReflectionInfo;
100: } else {
101: m_withinReflectionInfo = null;
102: }
103: }
104: if (reflectionInfo instanceof MethodInfo) {
105: m_reflectionInfoType = METHOD_INFO;
106: } else if (reflectionInfo instanceof ConstructorInfo) {
107: m_reflectionInfoType = CONSTRUCTOR_INFO;
108: } else if (reflectionInfo instanceof FieldInfo) {
109: m_reflectionInfoType = FIELD_INFO;
110: } else if (reflectionInfo instanceof ClassInfo) {
111: m_reflectionInfoType = CLASS_INFO;
112: } else if (reflectionInfo instanceof StaticInitializationInfo) {
113: m_reflectionInfoType = STATIC_INFO;
114: } else {
115: m_reflectionInfoType = INFO_NOT_AVAILABLE;// used for early eval on CALL
116: }
117: }
118:
119: public ReflectionInfo getReflectionInfo() {
120: return m_matchingReflectionInfo;
121: }
122:
123: public ReflectionInfo getWithinReflectionInfo() {
124: return m_withinReflectionInfo;
125: }
126:
127: public boolean hasExecutionPointcut() {
128: return m_pointcutType.equals(PointcutType.EXECUTION);
129: }
130:
131: public boolean hasCallPointcut() {
132: return m_pointcutType.equals(PointcutType.CALL);
133: }
134:
135: public boolean hasSetPointcut() {
136: return m_pointcutType.equals(PointcutType.SET);
137: }
138:
139: public boolean hasGetPointcut() {
140: return m_pointcutType.equals(PointcutType.GET);
141: }
142:
143: public boolean hasHandlerPointcut() {
144: return m_pointcutType.equals(PointcutType.HANDLER);
145: }
146:
147: public boolean hasStaticInitializationPointcut() {
148: return m_pointcutType
149: .equals(PointcutType.STATIC_INITIALIZATION);
150: }
151:
152: public boolean hasWithinPointcut() {
153: return m_pointcutType.equals(PointcutType.WITHIN);
154: }
155:
156: //
157: // public boolean hasHasMethodPointcut() {
158: // return m_pointcutType.equals(PointcutType.HAS_METHOD);
159: // }
160: //
161: // public boolean hasHasFieldPointcut() {
162: // return m_pointcutType.equals(PointcutType.HAS_FIELD);
163: // }
164:
165: public boolean hasWithinReflectionInfo() {
166: return m_withinReflectionInfo != null;
167: }
168:
169: public boolean hasMethodInfo() {
170: return m_reflectionInfoType == METHOD_INFO;
171: }
172:
173: public boolean hasConstructorInfo() {
174: return m_reflectionInfoType == CONSTRUCTOR_INFO;
175: }
176:
177: public boolean hasFieldInfo() {
178: return m_reflectionInfoType == FIELD_INFO;
179: }
180:
181: public boolean hasClassInfo() {
182: return m_reflectionInfoType == CLASS_INFO;
183: }
184:
185: public boolean hasReflectionInfo() {
186: return m_reflectionInfoType != INFO_NOT_AVAILABLE;
187: }
188:
189: public void setInCflowSubAST(final boolean inCflowAST) {
190: m_inCflowSubAST = inCflowAST;
191: }
192:
193: public boolean inCflowSubAST() {
194: return m_inCflowSubAST;
195: }
196:
197: public void setHasBeenVisitingCflow(
198: final boolean hasBeenVisitingCflow) {
199: m_hasBeenVisitingCflow = hasBeenVisitingCflow;
200: }
201:
202: public boolean hasBeenVisitingCflow() {
203: return m_hasBeenVisitingCflow;
204: }
205:
206: public boolean getCflowEvaluation() {
207: return m_cflowEvaluation;
208: }
209:
210: public void setCflowEvaluation(boolean cflowEvaluation) {
211: m_cflowEvaluation = cflowEvaluation;
212: }
213:
214: public int getCurrentTargetArgsIndex() {
215: return m_currentTargetArgsIndex;
216: }
217:
218: public void setCurrentTargetArgsIndex(int argsIndex) {
219: this .m_currentTargetArgsIndex = argsIndex;
220: }
221:
222: public boolean equals(Object o) {
223: if (this == o) {
224: return true;
225: }
226: if (!(o instanceof ExpressionContext)) {
227: return false;
228: }
229: final ExpressionContext expressionContext = (ExpressionContext) o;
230: if (m_reflectionInfoType != expressionContext.m_reflectionInfoType) {
231: return false;
232: }
233: if (!m_matchingReflectionInfo
234: .equals(expressionContext.m_matchingReflectionInfo)) {
235: return false;
236: }
237: if (!m_pointcutType.equals(expressionContext.m_pointcutType)) {
238: return false;
239: }
240: if ((m_withinReflectionInfo != null) ? (!m_withinReflectionInfo
241: .equals(expressionContext.m_withinReflectionInfo))
242: : (expressionContext.m_withinReflectionInfo != null)) {
243: return false;
244: }
245: return true;
246: }
247:
248: public int hashCode() {
249: int result;
250: result = m_pointcutType.hashCode();
251: result = (29 * result) + m_matchingReflectionInfo.hashCode();
252: result = (29 * result)
253: + ((m_withinReflectionInfo != null) ? m_withinReflectionInfo
254: .hashCode()
255: : 0);
256: result = (29 * result) + m_reflectionInfoType;
257: return result;
258: }
259:
260: public PointcutType getPointcutType() {
261: return m_pointcutType;
262: }
263:
264: public void resetRuntimeState() {
265: m_targetBoundedName = null;
266: m_this BoundedName = null;
267: m_exprIndexToTargetIndex = new HashMap();
268: m_targetWithRuntimeCheck = false;
269: }
270:
271: public String getDebugString() {
272: StringBuffer buffer = new StringBuffer();
273: buffer.append("[ExpressionContext:");
274: buffer.append(" INFO_NOT_AVAILABLE: ");
275: buffer.append(INFO_NOT_AVAILABLE);
276: buffer.append(" METHOD_INFO: ");
277: buffer.append(METHOD_INFO);
278: buffer.append(" CONSTRUCTOR_INFO: ");
279: buffer.append(CONSTRUCTOR_INFO);
280: buffer.append(" FIELD_INFO: ");
281: buffer.append(FIELD_INFO);
282: buffer.append(" CLASS_INFO: ");
283: buffer.append(CLASS_INFO);
284: buffer.append(" STATIC_INFO: ");
285: buffer.append(STATIC_INFO);
286: buffer.append(" m_reflectionInfoType: ");
287: buffer.append(m_reflectionInfoType);
288: buffer.append(" m_pointcutType: ");
289: buffer.append(m_pointcutType);
290: buffer.append(" m_matchingReflectionInfo: ");
291: buffer.append(m_matchingReflectionInfo);
292: buffer.append(" m_withinReflectionInfo: ");
293: buffer.append(m_withinReflectionInfo);
294: buffer.append(" m_inCflowSubAST: ");
295: buffer.append(m_inCflowSubAST);
296: buffer.append(" m_cflowEvaluation: ");
297: buffer.append(m_cflowEvaluation);
298: buffer.append(" m_hasBeenVisitingCflow: ");
299: buffer.append(m_hasBeenVisitingCflow);
300: buffer.append(" m_currentTargetArgsIndex: ");
301: buffer.append(m_currentTargetArgsIndex);
302: buffer.append(" m_exprIndexToTargetIndex: ");
303: buffer.append(m_exprIndexToTargetIndex);
304: buffer.append(" m_thisBoundedName: ");
305: buffer.append(m_this BoundedName);
306: buffer.append(" m_targetBoundedName: ");
307: buffer.append(m_targetBoundedName);
308: buffer.append(" m_targetWithRuntimeCheck: ");
309: buffer.append(m_targetWithRuntimeCheck);
310: buffer.append("]");
311: return buffer.toString();
312: }
313:
314: }
|