KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > aop > aspectj > RuntimeTestWalker


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.aop.aspectj;
18
19 import java.lang.reflect.Field JavaDoc;
20
21 import org.aspectj.weaver.ast.And;
22 import org.aspectj.weaver.ast.Call;
23 import org.aspectj.weaver.ast.FieldGetCall;
24 import org.aspectj.weaver.ast.HasAnnotation;
25 import org.aspectj.weaver.ast.ITestVisitor;
26 import org.aspectj.weaver.ast.Instanceof;
27 import org.aspectj.weaver.ast.Literal;
28 import org.aspectj.weaver.ast.Not;
29 import org.aspectj.weaver.ast.Or;
30 import org.aspectj.weaver.ast.Test;
31 import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
32 import org.aspectj.weaver.reflect.ReflectionVar;
33 import org.aspectj.weaver.reflect.ShadowMatchImpl;
34 import org.aspectj.weaver.tools.ShadowMatch;
35
36 /**
37  * <p>This class encapsulates some AspectJ internal knowledge that should be
38  * pushed back into the AspectJ project in a future release.
39  *
40  * <p>It relies on implementation specific knowledge in AspectJ to break
41  * encapsulation and do something AspectJ was not designed to do :- query
42  * the types of runtime tests that will be performed. The code here should
43  * migrate to ShadowMatch.getVariablesInvolvedInRuntimeTest() or some similar
44  * operation.
45  *
46  * <p>See https://bugs.eclipse.org/bugs/show_bug.cgi?id=151593
47  *
48  * @author Adrian Colyer
49  * @since 2.0
50  */

51 public class RuntimeTestWalker {
52
53     private Test runtimeTest;
54     
55     public RuntimeTestWalker(ShadowMatch shadowMatch) {
56         ShadowMatchImpl shadowMatchImplementation = (ShadowMatchImpl) shadowMatch;
57         try {
58             Field JavaDoc testField = shadowMatchImplementation.getClass().getDeclaredField("residualTest");
59             testField.setAccessible(true);
60             this.runtimeTest = (Test) testField.get(shadowMatch);
61         }
62         catch(NoSuchFieldException JavaDoc noSuchFieldEx) {
63             throw new IllegalStateException JavaDoc("the version of aspectjtools.jar / aspectjweaver.jar " +
64                     "on the classpath is incompatible with this version of Spring:- expected field " +
65                     "'runtimeTest' is not present on ShadowMatchImpl class");
66         }
67         catch (IllegalAccessException JavaDoc illegalAccessEx) {
68             // famous last words... but I don't see how this can happen given the
69
// setAccessible call above
70
throw new IllegalStateException JavaDoc("Unable to access ShadowMatchImpl.runtimeTest field.");
71         }
72     }
73
74     /**
75      * If the test uses any of the this, target, at_this, at_target, and at_annotation vars,
76      * then it tests subtype sensitive vars.
77      */

78     public boolean testsSubtypeSensitiveVars() {
79         return new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest);
80     }
81
82
83     private static class SubtypeSensitiveVarTypeTestVisitor implements ITestVisitor {
84
85         private static final int AT_THIS_VAR = 3;
86         private static final int AT_TARGET_VAR = 4;
87         private static final int AT_ANNOTATION_VAR = 8;
88
89         private final Object JavaDoc thisObj = new Object JavaDoc();
90         private final Object JavaDoc targetObj = new Object JavaDoc();
91         private final Object JavaDoc[] argsObjs = new Object JavaDoc[0];
92
93         private boolean testsSubtypeSensitiveVars = false;
94
95         public boolean testsSubtypeSensitiveVars(Test aTest) {
96             aTest.accept(this);
97             return this.testsSubtypeSensitiveVars;
98         }
99         
100         public void visit(And e) {
101             e.getLeft().accept(this);
102             e.getRight().accept(this);
103         }
104
105         public void visit(Or e) {
106             e.getLeft().accept(this);
107             e.getRight().accept(this);
108         }
109
110         public void visit(Not e) {
111             e.getBody().accept(this);
112         }
113
114         public void visit(Instanceof i) {
115             ReflectionVar v = (ReflectionVar) i.getVar();
116             Object JavaDoc varUnderTest = v.getBindingAtJoinPoint(thisObj,targetObj,argsObjs);
117             if ((varUnderTest == thisObj) || (varUnderTest == targetObj)) {
118                 this.testsSubtypeSensitiveVars = true;
119             }
120         }
121
122         public void visit(HasAnnotation hasAnn) {
123             // if you thought things were bad before, now we sink to new levels
124
// of horror...
125
ReflectionVar v = (ReflectionVar) hasAnn.getVar();
126             try {
127                 Field JavaDoc varTypeField = ReflectionVar.class.getDeclaredField("varType");
128                 varTypeField.setAccessible(true);
129                 Integer JavaDoc varTypeValue = (Integer JavaDoc) varTypeField.get(v);
130                 int varType = varTypeValue.intValue();
131                 if ((varType == AT_THIS_VAR) ||
132                     (varType == AT_TARGET_VAR) ||
133                     (varType == AT_ANNOTATION_VAR)) {
134                     this.testsSubtypeSensitiveVars = true;
135                 }
136             }
137             catch(NoSuchFieldException JavaDoc noSuchFieldEx) {
138                 throw new IllegalStateException JavaDoc("the version of aspectjtools.jar / aspectjweaver.jar " +
139                         "on the classpath is incompatible with this version of Spring:- expected field " +
140                         "'varType' is not present on ReflectionVar class");
141             }
142             catch(IllegalAccessException JavaDoc illegalAccessEx) {
143                 // famous last words... but I don't see how this can happen given the setAccessible call
144
// above
145
throw new IllegalStateException JavaDoc("Unable to access ReflectionVar.varType field.");
146             }
147         }
148
149         public void visit(Literal e) {
150             // NO-OP
151
}
152
153         public void visit(Call e) {
154             // NO-OP
155
}
156
157         public void visit(FieldGetCall e) {
158             // NO-OP
159
}
160
161         public void visit(MatchingContextBasedTest arg0) {
162             // NO-OP
163
}
164         
165     }
166 }
167
Popular Tags