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