KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > transform > inlining > model > AopAllianceAspectModel


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.transform.inlining.model;
5
6 import com.tc.asm.MethodVisitor;
7 import com.tc.asm.ClassWriter;
8 import com.tc.asm.ClassVisitor;
9 import com.tc.asm.Type;
10
11 import com.tc.aspectwerkz.definition.AspectDefinition;
12 import com.tc.aspectwerkz.transform.JoinPointCompiler;
13 import com.tc.aspectwerkz.transform.TransformationConstants;
14 import com.tc.aspectwerkz.transform.inlining.AdviceMethodInfo;
15 import com.tc.aspectwerkz.transform.inlining.AspectInfo;
16 import com.tc.aspectwerkz.transform.inlining.compiler.CompilationInfo;
17 import com.tc.aspectwerkz.transform.inlining.compiler.CompilerInput;
18 import com.tc.aspectwerkz.transform.inlining.model.AspectWerkzAspectModel;
19 import com.tc.aspectwerkz.transform.inlining.spi.AspectModel;
20 import com.tc.aspectwerkz.reflect.ClassInfo;
21
22 /**
23  * TODO support ConstructorInvocation (1h work) (plus tests)
24  * <p/>
25  * Implementation of the AspectModel interface for AOP Alliance based frameworks (e.g. Spring, dynaop etc.).
26  * <p/>
27  * Provides methods for definition of aspects and framework specific bytecode generation
28  * used by the join point compiler.
29  *
30  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bon&#233;r </a>
31  */

32 public class AopAllianceAspectModel implements AspectModel, TransformationConstants {
33
34   protected static final String JavaDoc ASPECT_MODEL_TYPE = "aop-alliance";
35
36   private static final String JavaDoc CONSTRUCTOR_INTERCEPTOR_CLASS = "org.aopalliance.intercept.ConstructorInterceptor";
37   private static final String JavaDoc METHOD_INTERCEPTOR_CLASS = "org.aopalliance.intercept.MethodInterceptor";
38   
39   protected static final String JavaDoc AOP_ALLIANCE_CLOSURE_CLASS_NAME = "org/aopalliance/intercept/MethodInvocation";
40   protected static final String JavaDoc AOP_ALLIANCE_CLOSURE_PROCEED_METHOD_NAME = "invoke";
41   protected static final String JavaDoc AOP_ALLIANCE_CLOSURE_PROCEED_METHOD_SIGNATURE = "(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object;";
42   protected static final String JavaDoc GET_METHOD_METHOD_NAME = "getMethod";
43   protected static final String JavaDoc GET_METHOD_METHOD_SIGNATURE = "()Ljava/lang/reflect/Method;";
44   protected static final String JavaDoc GET_STATIC_PART_METHOD_NAME = "getStaticPart";
45   protected static final String JavaDoc GET_STATIC_PART_METHOD_SIGNATURE = "()Ljava/lang/reflect/AccessibleObject;";
46   protected static final String JavaDoc GET_PARAMETER_VALUES_METHOD_NAME = "getParameterValues";
47   protected static final String JavaDoc GET_ARGUMENTS_METHOD_SIGNATURE = "()[Ljava/lang/Object;";
48   protected static final String JavaDoc GET_ARGUMENTS_METHOD_NAME = "getArguments";
49
50   /**
51    * Use an AspectWerkzAspectModel to delegate common things to it.
52    */

53   private final static AspectModel s_modelHelper = new AspectWerkzAspectModel();
54
55   /**
56    * Returns the aspect model type, which is an id for the the special aspect model, can be anything as long
57    * as it is unique.
58    *
59    * @return the aspect model type id
60    */

61   public String JavaDoc getAspectModelType() {
62     return ASPECT_MODEL_TYPE;
63   }
64
65   /**
66    * Defines the aspect.
67    */

68   public void defineAspect(final ClassInfo classInfo,
69                            final AspectDefinition aspectDef,
70                            final ClassLoader JavaDoc loader) {
71     ClassInfo[] interfaces = classInfo.getInterfaces();
72     for (int i = 0; i < interfaces.length; i++) {
73       String JavaDoc name = interfaces[i].getName();
74       // can't use .class here due to class loading issues
75
if (METHOD_INTERCEPTOR_CLASS.equals(name)
76           || CONSTRUCTOR_INTERCEPTOR_CLASS.equals(name)) {
77         aspectDef.setAspectModel(ASPECT_MODEL_TYPE);
78         aspectDef.setContainerClassName(null);// no container. Inlined factory is enough
79
return;
80       }
81     }
82   }
83
84   /**
85    * AOP Alliance is a reflection based model and therefore in need of RTTI info: returns true.
86    *
87    * @return true
88    */

89   public boolean requiresReflectiveInfo() {
90     return true;
91   }
92
93   /**
94    * Returns info about the closure class, name and type (interface or class).
95    *
96    * @return the closure class info
97    */

98   public AroundClosureClassInfo getAroundClosureClassInfo() {
99     return new AspectModel.AroundClosureClassInfo(null, new String JavaDoc[]{AOP_ALLIANCE_CLOSURE_CLASS_NAME});
100   }
101
102   /**
103    * Returns an instance for a given compilation. Singleton is enough.
104    *
105    * @param compilationModel
106    * @return
107    */

108   public AspectModel getInstance(CompilationInfo.Model compilationModel) {
109     return this;
110   }
111
112   /**
113    * Creates the methods required to implement or extend to implement the closure for the specific
114    * aspect model type.
115    *
116    * @param cw
117    * @param compiler
118    */

119   public void createMandatoryMethods(final ClassWriter cw, final JoinPointCompiler compiler) {
120     final String JavaDoc className = compiler.getJoinPointClassName();
121     MethodVisitor cv;
122
123     // invoke
124
{
125       cv = cw.visitMethod(
126               ACC_PUBLIC,
127               AOP_ALLIANCE_CLOSURE_PROCEED_METHOD_NAME,
128               AOP_ALLIANCE_CLOSURE_PROCEED_METHOD_SIGNATURE,
129               null,
130               new String JavaDoc[]{THROWABLE_CLASS_NAME}
131       );
132       cv.visitVarInsn(ALOAD, 0);
133       cv.visitMethodInsn(INVOKEVIRTUAL, className, PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
134       cv.visitInsn(ARETURN);
135       cv.visitMaxs(0, 0);
136     }
137
138     // getStaticPart
139
{
140       cv = cw.visitMethod(
141               ACC_PUBLIC,
142               GET_STATIC_PART_METHOD_NAME,
143               GET_STATIC_PART_METHOD_SIGNATURE,
144               null, null
145       );
146       cv.visitFieldInsn(GETSTATIC, className, SIGNATURE_FIELD_NAME, METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE);
147       cv.visitTypeInsn(CHECKCAST, METHOD_SIGNATURE_IMPL_CLASS_NAME);
148       cv.visitMethodInsn(
149               INVOKEVIRTUAL, METHOD_SIGNATURE_IMPL_CLASS_NAME, GET_METHOD_METHOD_NAME,
150               GET_METHOD_METHOD_SIGNATURE
151       );
152       cv.visitInsn(ARETURN);
153       cv.visitMaxs(1, 1);
154     }
155
156     // getMethod
157
{
158       cv =
159               cw.visitMethod(
160                       ACC_PUBLIC,
161                       GET_METHOD_METHOD_NAME,
162                       GET_METHOD_METHOD_SIGNATURE,
163                       null, null
164               );
165       cv.visitFieldInsn(GETSTATIC, className, SIGNATURE_FIELD_NAME, METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE);
166       cv.visitTypeInsn(CHECKCAST, METHOD_SIGNATURE_IMPL_CLASS_NAME);
167       cv.visitMethodInsn(
168               INVOKEVIRTUAL, METHOD_SIGNATURE_IMPL_CLASS_NAME, GET_METHOD_METHOD_NAME,
169               GET_METHOD_METHOD_SIGNATURE
170       );
171       cv.visitInsn(ARETURN);
172       cv.visitMaxs(1, 1);
173     }
174
175     // getArguments
176
{
177       cv = cw.visitMethod(
178               ACC_PUBLIC,
179               GET_ARGUMENTS_METHOD_NAME,
180               GET_ARGUMENTS_METHOD_SIGNATURE,
181               null, null
182       );
183       cv.visitVarInsn(ALOAD, 0);
184       cv.visitMethodInsn(INVOKESPECIAL, className, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE);
185       cv.visitTypeInsn(CHECKCAST, METHOD_RTTI_IMPL_CLASS_NAME);
186       cv.visitMethodInsn(
187               INVOKEVIRTUAL,
188               METHOD_RTTI_IMPL_CLASS_NAME,
189               GET_PARAMETER_VALUES_METHOD_NAME,
190               GET_ARGUMENTS_METHOD_SIGNATURE
191       );
192       cv.visitInsn(ARETURN);
193       cv.visitMaxs(1, 1);
194     }
195
196   }
197
198   /**
199    * Creates an invocation of the around closure class' constructor.
200    */

201   public void createInvocationOfAroundClosureSuperClass(final MethodVisitor cv) {
202     // just an interface
203
}
204
205   /**
206    * Creates host of the aop alliance aspect instance by invoking aspectOf().
207    */

208   public void createAndStoreStaticAspectInstantiation(ClassVisitor classVisitor, MethodVisitor methodVisitor, AspectInfo aspectInfo, String JavaDoc joinPointClassName) {
209     // we use static field and handle instantiation thru perJVM factory
210
s_modelHelper.createAndStoreStaticAspectInstantiation(
211             classVisitor, methodVisitor, aspectInfo, joinPointClassName
212     );
213   }
214
215   public void createAndStoreRuntimeAspectInstantiation(MethodVisitor methodVisitor, CompilerInput compilerInput, AspectInfo aspectInfo) {
216     // does not happen
217
}
218
219   public void loadAspect(MethodVisitor methodVisitor, CompilerInput compilerInput, AspectInfo aspectInfo) {
220     s_modelHelper.loadAspect(methodVisitor, compilerInput, aspectInfo);
221   }
222
223   public void createAroundAdviceArgumentHandling(MethodVisitor methodVisitor, CompilerInput compilerInput, Type[] types, AdviceMethodInfo adviceMethodInfo) {
224     // push jp ie AOP Alliance MethodInvocation
225
methodVisitor.visitVarInsn(ALOAD, 0);
226
227   }
228
229   public void createBeforeOrAfterAdviceArgumentHandling(MethodVisitor methodVisitor, CompilerInput compilerInput, Type[] types, AdviceMethodInfo adviceMethodInfo, int i) {
230     //does not happen
231
}
232 }
233
Popular Tags