KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > transform > inlining > compiler > CompilerHelper


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.compiler;
5
6 import java.util.Map JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.WeakHashMap JavaDoc;
9 import java.util.HashSet JavaDoc;
10 import java.util.Set JavaDoc;
11
12 import com.tc.aspectwerkz.joinpoint.management.JoinPointType;
13 import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
14 import com.tc.aspectwerkz.reflect.ClassInfo;
15 import com.tc.aspectwerkz.reflect.MethodInfo;
16 import com.tc.aspectwerkz.transform.inlining.AsmHelper;
17 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint;
18 import com.tc.aspectwerkz.expression.PointcutType;
19 import com.tc.aspectwerkz.expression.ExpressionContext;
20 import com.tc.aspectwerkz.expression.ExpressionInfo;
21
22 /**
23  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
24  */

25 public class CompilerHelper {
26
27   /**
28    * Stores the compilation infos - mapped to the last compiled join point class based on this compilation info.
29    */

30   private static final Map JavaDoc COMPILATION_INFO_REPOSITORY = new WeakHashMap JavaDoc();
31
32   /**
33    * Compiles and loades a join point class, one specific class for each distinct join point.
34    *
35    * @param model the model for the compilation
36    * @param loader the class loader that the compiled join point should live in
37    * @return the compiled join point class
38    */

39   public static Class JavaDoc compileJoinPointAndAttachToClassLoader(final CompilationInfo.Model model,
40                                                              final ClassLoader JavaDoc loader) {
41     return attachToClassLoader(model.getJoinPointClassName(), loader, compileJoinPoint(model));
42   }
43
44   /**
45    * Loads a join point class, one specific class for each distinct join point.
46    *
47    * @param joinpointClassName
48    * @param loader the class loader that the compiled join point should live in
49    * @param bytecode of the joinpoint
50    * @return the compiled join point class
51    */

52   public static Class JavaDoc attachToClassLoader(final String JavaDoc joinpointClassName,
53                                           final ClassLoader JavaDoc loader,
54                                           final byte[] bytecode) {
55     return AsmHelper.defineClass(loader, bytecode, joinpointClassName);
56   }
57
58   /**
59    * Adds or updates a compilation info. The class key is always the first compiled join point class.
60    *
61    * @param clazz
62    * @param compilationInfo
63    */

64   public static void addCompilationInfo(final Class JavaDoc clazz, final CompilationInfo compilationInfo) {
65     COMPILATION_INFO_REPOSITORY.put(clazz, compilationInfo);
66   }
67
68   /**
69    * Compiles a join point class, one specific class for each distinct join point.
70    *
71    * @param model the model for the compilation
72    * @return the compiled join point bytecode
73    */

74   public static byte[] compileJoinPoint(final CompilationInfo.Model model) {
75     switch (model.getEmittedJoinPoint().getJoinPointType()) {
76       case JoinPointType.METHOD_EXECUTION_INT:
77         return new MethodExecutionJoinPointCompiler(model).compile();
78       case JoinPointType.METHOD_CALL_INT:
79         return new MethodCallJoinPointCompiler(model).compile();
80       case JoinPointType.CONSTRUCTOR_EXECUTION_INT:
81         return new ConstructorExecutionJoinPointCompiler(model).compile();
82       case JoinPointType.CONSTRUCTOR_CALL_INT:
83         return new ConstructorCallJoinPointCompiler(model).compile();
84       case JoinPointType.FIELD_SET_INT:
85         return new FieldSetJoinPointCompiler(model).compile();
86       case JoinPointType.FIELD_GET_INT:
87         return new FieldGetJoinPointCompiler(model).compile();
88       case JoinPointType.HANDLER_INT:
89         return new HandlerJoinPointCompiler(model).compile();
90       case JoinPointType.STATIC_INITIALIZATION_INT:
91         return new StaticInitializationJoinPointCompiler(model).compile();
92       default:
93         throw new UnsupportedOperationException JavaDoc(
94                 "join point type is not supported: " + model.getEmittedJoinPoint().getJoinPointType()
95         );
96     }
97   }
98
99   /**
100    * Redefines the originally compiled join point.
101    *
102    * @param compilationInfo the model for the compilation
103    * @return the compiled join point bytecode
104    */

105   public static byte[] redefineJoinPoint(final CompilationInfo compilationInfo) {
106     switch (compilationInfo.getInitialModel().getEmittedJoinPoint().getJoinPointType()) {
107       case JoinPointType.METHOD_EXECUTION_INT:
108         return new MethodExecutionJoinPointRedefiner(compilationInfo).compile();
109       case JoinPointType.METHOD_CALL_INT:
110         return new MethodCallJoinPointRedefiner(compilationInfo).compile();
111       case JoinPointType.CONSTRUCTOR_EXECUTION_INT:
112         return new ConstructorExecutionJoinPointRedefiner(compilationInfo).compile();
113       case JoinPointType.CONSTRUCTOR_CALL_INT:
114         return new ConstructorCallJoinPointRedefiner(compilationInfo).compile();
115       case JoinPointType.FIELD_SET_INT:
116         return new FieldSetJoinPointRedefiner(compilationInfo).compile();
117       case JoinPointType.FIELD_GET_INT:
118         return new FieldGetJoinPointRedefiner(compilationInfo).compile();
119       case JoinPointType.HANDLER_INT:
120         return new HandlerJoinPointRedefiner(compilationInfo).compile();
121       default:
122         throw new UnsupportedOperationException JavaDoc(
123                 "join point type is not supported: " +
124                         compilationInfo.getInitialModel().getEmittedJoinPoint().getJoinPointType()
125         );
126     }
127   }
128
129   /**
130    * Returns a list with all the join point compilers that matches a specific pointcut expression.
131    * <p/>
132    * To be used for redefinition of the join point compilers only. This since the compilers must have been created
133    * in advance to exist in the repository (which is done when the target class is loaded).
134    *
135    * @param expression the pointcut expression
136    * @return a set with the matching emitted join point
137    */

138   public static Set JavaDoc getJoinPointsMatching(final ExpressionInfo expression) {
139     final Set JavaDoc matchingJoinPointInfos = new HashSet JavaDoc();
140     for (Iterator JavaDoc it = COMPILATION_INFO_REPOSITORY.entrySet().iterator(); it.hasNext();) {
141       final Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
142
143       final Class JavaDoc clazz = (Class JavaDoc) entry.getKey();
144       final CompilationInfo compilationInfo = (CompilationInfo) entry.getValue();
145       final EmittedJoinPoint joinPoint = (EmittedJoinPoint) compilationInfo.
146               getInitialModel().getEmittedJoinPoint();
147       final ClassLoader JavaDoc loader = clazz.getClassLoader();
148
149       final ClassInfo calleeClassInfo = AsmClassInfo.getClassInfo(joinPoint.getCalleeClassName(), loader);
150       final ClassInfo callerClassInfo = AsmClassInfo.getClassInfo(joinPoint.getCallerClassName(), loader);
151       final MethodInfo callerMethodInfo = getCallerMethodInfo(callerClassInfo, joinPoint);
152
153       ExpressionContext ctx = null;
154       switch (joinPoint.getJoinPointType()) {
155         case JoinPointType.METHOD_EXECUTION_INT:
156           ctx = new ExpressionContext(
157                   PointcutType.EXECUTION,
158                   calleeClassInfo.getMethod(joinPoint.getJoinPointHash()),
159                   callerMethodInfo
160           );
161           break;
162         case JoinPointType.METHOD_CALL_INT:
163           ctx = new ExpressionContext(
164                   PointcutType.CALL,
165                   calleeClassInfo.getMethod(joinPoint.getJoinPointHash()),
166                   callerMethodInfo
167           );
168           break;
169         case JoinPointType.CONSTRUCTOR_EXECUTION_INT:
170           ctx = new ExpressionContext(
171                   PointcutType.EXECUTION,
172                   calleeClassInfo.getConstructor(joinPoint.getJoinPointHash()),
173                   callerMethodInfo
174           );
175           break;
176         case JoinPointType.CONSTRUCTOR_CALL_INT:
177           ctx = new ExpressionContext(
178                   PointcutType.CALL,
179                   calleeClassInfo.getConstructor(joinPoint.getJoinPointHash()),
180                   callerMethodInfo
181           );
182           break;
183         case JoinPointType.FIELD_SET_INT:
184           ctx = new ExpressionContext(
185                   PointcutType.SET,
186                   calleeClassInfo.getField(joinPoint.getJoinPointHash()),
187                   callerMethodInfo
188           );
189           break;
190         case JoinPointType.FIELD_GET_INT:
191           ctx = new ExpressionContext(
192                   PointcutType.GET,
193                   calleeClassInfo.getField(joinPoint.getJoinPointHash()),
194                   callerMethodInfo
195           );
196           break;
197         case JoinPointType.HANDLER_INT:
198           ctx = new ExpressionContext(
199                   PointcutType.HANDLER,
200                   AsmClassInfo.getClassInfo(joinPoint.getCalleeClassName(), loader),
201                   callerMethodInfo
202           );
203           break;
204         case JoinPointType.STATIC_INITIALIZATION_INT:
205           ctx = new ExpressionContext(
206                   PointcutType.STATIC_INITIALIZATION,
207                   calleeClassInfo.staticInitializer(),
208                   calleeClassInfo
209           );
210       }
211       if (expression.getExpression().match(ctx)) {
212         matchingJoinPointInfos.add(new MatchingJoinPointInfo(clazz, compilationInfo, ctx));
213       }
214     }
215     return matchingJoinPointInfos;
216   }
217
218   /**
219    * Returns the emitted join point structure for a specific JIT generated join point class.
220    *
221    * @param clazz the join point class
222    * @return the emitted join point structure
223    */

224   public static EmittedJoinPoint getEmittedJoinPoint(final Class JavaDoc clazz) {
225     return (EmittedJoinPoint) COMPILATION_INFO_REPOSITORY.get(clazz);
226   }
227
228   /**
229    * Grabs the caller method info.
230    *
231    * @param callerClassInfo
232    * @param emittedJoinPoint
233    * @return
234    */

235   private static MethodInfo getCallerMethodInfo(final ClassInfo callerClassInfo,
236                                                 final EmittedJoinPoint emittedJoinPoint) {
237     MethodInfo callerMethodInfo = null;
238     MethodInfo[] callerMethods = callerClassInfo.getMethods();
239     for (int i = 0; i < callerMethods.length; i++) {
240       MethodInfo method = callerMethods[i];
241       if (method.getName().equals(emittedJoinPoint.getCallerMethodName()) &&
242               method.getSignature().equals(emittedJoinPoint.getCallerMethodDesc())) {
243         callerMethodInfo = method;
244         break;
245       }
246     }
247     return callerMethodInfo;
248   }
249 }
250
Popular Tags