KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > instrument > OptimizedFieldAccessTransformer


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aop.instrument;
23
24 import javassist.CannotCompileException;
25 import javassist.CtClass;
26 import javassist.CtField;
27 import javassist.CtMethod;
28 import javassist.Modifier;
29 import javassist.NotFoundException;
30 import javassist.expr.FieldAccess;
31
32 /**
33  * Comment
34  *
35  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
36  * @version $Revision$
37  */

38 public class OptimizedFieldAccessTransformer extends FieldAccessTransformer
39 {
40
41    public OptimizedFieldAccessTransformer(Instrumentor instrumentor)
42    {
43       super(instrumentor);
44    }
45
46    protected void doBuildFieldWrappers(CtClass clazz, CtField field, int fieldIndex, JoinpointClassification classificationGet, JoinpointClassification classificationSet) throws NotFoundException, CannotCompileException
47    {
48       instrumentor.setupBasics(clazz);
49       boolean wrappedGet = classificationGet.equals(JoinpointClassification.WRAPPED);
50       boolean wrappedSet = classificationSet.equals(JoinpointClassification.WRAPPED);
51       int mod = getStaticModifiers(field);
52                   
53       //Create placeholder static wrappers, since without these methods replaceFieldAccessInternally()
54
//will not compile.
55
//If we add the actual static wrappers before calling replaceFieldAccessInternally()
56
//field access done in the inner invocation classes as well as in the static wrappers
57
//is replaced with a call to the wrapper instead, which means infinite recursion
58
buildWrapperPlaceHolders(clazz, field, isPrepared(classificationGet), isPrepared(classificationSet), mod);
59       try {
60          if (isPrepared(classificationGet))
61          {
62             addFieldReadInfoFieldWithAccessors(Modifier.PRIVATE | Modifier.STATIC, clazz, field);
63             OptimizedFieldInvocations.createOptimizedInvocationClass(instrumentor, clazz, field, true);
64             // prepareForWrapping
65
wrapper.prepareForWrapping(field, GET_INDEX);
66          }
67             
68          if (isPrepared(classificationSet))
69          {
70             addFieldWriteInfoField(Modifier.PRIVATE | Modifier.STATIC, clazz, field);
71             OptimizedFieldInvocations.createOptimizedInvocationClass(instrumentor, clazz, field, false);
72             // prepareForWrapping
73
wrapper.prepareForWrapping(field, SET_INDEX);
74          }
75       } catch (Exception JavaDoc e)
76       {
77          throw new CannotCompileException(e);
78       }
79       
80       // wrap
81
if (wrappedGet)
82       {
83          wrapper.wrap(field, GET_INDEX);
84          if (classificationGet.equals(JoinpointClassification.DYNAMICALY_WRAPPED))
85          {
86             instrumentor.dynamicTransformationObserver.fieldReadDynamicalyWrapped(field);
87          }
88       }
89       if (wrappedSet)
90       {
91          wrapper.wrap(field, SET_INDEX);
92          if (classificationSet.equals(JoinpointClassification.DYNAMICALY_WRAPPED))
93          {
94             instrumentor.dynamicTransformationObserver.fieldWriteDynamicalyWrapped(field);
95          }
96       }
97       
98       // executeWrapping
99
replaceFieldAccessInternally(clazz, field, wrappedGet, wrappedSet, fieldIndex);
100       buildWrappers(clazz, field, wrappedGet, wrappedSet, fieldIndex);
101    }
102
103    /**
104     * Returns the body of the optimized wrapper method.
105     * @param clazz the class declaring <code>field</code>.
106     * @param field the field whose joinpoint wrapper body will be returned.
107     * @param get indicates if the wrapper is a field read wrapper or a field
108     * write wrapper.
109     * @param index the <code>field</code> index.
110     * @return the optimized wrapper body.
111     */

112    protected String JavaDoc getWrapperBody(CtClass clazz, CtField field, boolean get, int index)
113            throws NotFoundException, CannotCompileException
114    {
115       if (get)
116       {
117          return getReadWrapperBody(clazz, field, index);
118       }
119       return getWriteWrapperBody(clazz, field, index);
120    }
121
122    /**
123     * Returns the body of the optimized wrapper method.
124     * @param clazz the class declaring <code>field</code>.
125     * @param field the field whose read joinpoint wrapper body will be returned.
126     * @param index the <code>field</code> index.
127     * @return the optimized wrapper body.
128     */

129    private String JavaDoc getReadWrapperBody(CtClass clazz, CtField field, int index)
130            throws NotFoundException, CannotCompileException
131    {
132       String JavaDoc wrappedName = field.getName();
133
134       String JavaDoc optimizedInvocation;
135       try
136       {
137          optimizedInvocation = OptimizedFieldInvocations.getOptimizedInvocationClassName(clazz, field, true);
138                optimizedInvocation = optimizedInvocation.substring(optimizedInvocation.lastIndexOf('.') + 1);
139                optimizedInvocation = clazz.getName() + "$" + optimizedInvocation;
140       }
141       catch (Exception JavaDoc e)
142       {
143          e.printStackTrace();
144          throw new CannotCompileException(e);
145       }
146
147       String JavaDoc infoName = getFieldReadInfoFieldName(field.getName());
148       boolean isStatic = javassist.Modifier.isStatic(field.getModifiers());
149
150       String JavaDoc code;
151
152       if (!isStatic)
153       {
154          code =
155          "{ "
156          + " " + fieldInfoFromWeakReference("info", infoName)
157          + " org.jboss.aop.ClassInstanceAdvisor instAdv = (org.jboss.aop.ClassInstanceAdvisor)((org.jboss.aop.InstanceAdvised)$1)._getInstanceAdvisor();"
158          + " org.jboss.aop.advice.Interceptor[] interceptors = info.getInterceptors(); "
159          + " if (interceptors != (org.jboss.aop.advice.Interceptor[])null || (instAdv != null && instAdv.hasInstanceAspects))"
160          + " { "
161          + " if (instAdv != null) "
162          + " { "
163          + " interceptors = instAdv.getInterceptors(interceptors); "
164          + " } "
165          + " " + optimizedInvocation + " invocation = new " + optimizedInvocation + "(" + Instrumentor.HELPER_FIELD_NAME + ".getAdvisedFields()[" + index + "]," + index + ", interceptors); "
166          + " invocation.setTargetObject($1); "
167          + " invocation.typedTargetObject = (" + clazz.getName() + ")$1; "
168          + " invocation.setAdvisor(" + Instrumentor.HELPER_FIELD_NAME + "); "
169          + " return ($r)invocation.invokeNext(); "
170          + " } "
171          + " else "
172          + " {"
173          + " return ((" + clazz.getName() + ")$1)." + wrappedName + ";"
174          + " }"
175          + "}";
176       }
177       else
178       {
179          code =
180          "{ "
181          + " org.jboss.aop.advice.Interceptor[] interceptors = " + Instrumentor.HELPER_FIELD_NAME + ".getFieldReadInfos()[" + index + "].getInterceptors(); "
182          + " if (interceptors != (org.jboss.aop.advice.Interceptor[])null) "
183          + " { "
184          + " " + optimizedInvocation + " invocation = new " + optimizedInvocation + "(" + Instrumentor.HELPER_FIELD_NAME + ".getAdvisedFields()[" + index + "]," + index + ", interceptors); "
185          + " invocation.setTargetObject($1); "
186          + " invocation.setAdvisor(" + Instrumentor.HELPER_FIELD_NAME + "); "
187          + " return ($r)invocation.invokeNext(); "
188          + " } "
189          + " else "
190          + " {"
191          + " return " + clazz.getName() + "." + wrappedName + ";"
192          + " }"
193          + "}";
194       }
195       return code;
196    }
197
198    /**
199     * Returns the body of the optimized wrapper method.
200     * @param clazz the class declaring <code>field</code>.
201     * @param field the field whose write joinpoint wrapper body will be returned.
202     * @param index the <code>field</code> index.
203     * @return the optimized wrapper body.
204     */

205    private String JavaDoc getWriteWrapperBody(CtClass clazz, CtField field, int index)
206            throws NotFoundException, CannotCompileException
207    {
208       String JavaDoc wrappedName = field.getName();
209
210       String JavaDoc optimizedInvocation;
211       try
212       {
213          optimizedInvocation = OptimizedFieldInvocations.getOptimizedInvocationClassName(clazz, field, false);
214             optimizedInvocation = optimizedInvocation.substring(optimizedInvocation.lastIndexOf('.') + 1);
215             optimizedInvocation = clazz.getName() + "$" + optimizedInvocation;
216       }
217       catch (Exception JavaDoc e)
218       {
219          throw new CannotCompileException(e);
220       }
221
222       final String JavaDoc infoName = getFieldWriteInfoFieldName(field.getName());
223       final boolean isStatic = javassist.Modifier.isStatic(field.getModifiers());
224       String JavaDoc code;
225       if (!isStatic)
226       {
227          code =
228          "{ "
229          + " " + fieldInfoFromWeakReference("info", infoName)
230          + " org.jboss.aop.ClassInstanceAdvisor instAdv = (org.jboss.aop.ClassInstanceAdvisor)((org.jboss.aop.InstanceAdvised)$1)._getInstanceAdvisor();"
231          + " org.jboss.aop.advice.Interceptor[] interceptors = info.getInterceptors();"
232          + " if (interceptors != (org.jboss.aop.advice.Interceptor[])null || (instAdv != null && instAdv.hasInstanceAspects)) "
233          + " { "
234          + " if (instAdv != null) "
235          + " { "
236          + " interceptors = instAdv.getInterceptors(interceptors); "
237          + " } "
238          + " " + optimizedInvocation + " invocation = new " + optimizedInvocation + "(" + Instrumentor.HELPER_FIELD_NAME + ".getAdvisedFields()[" + index + "]," + index + ", ($w)$2" + ", interceptors); "
239          + " invocation.setTargetObject($1); "
240          + " invocation.typedTargetObject = (" + clazz.getName() + ")$1; "
241          + " invocation.setAdvisor(" + Instrumentor.HELPER_FIELD_NAME + "); "
242          + " invocation.invokeNext(); "
243          + " } "
244          + " else "
245          + " {"
246          + " ((" + clazz.getName() + ")$1)." + wrappedName + "=$2" + ";"
247          + " }"
248          + "}";
249       }
250       else
251       {
252          code =
253          "{ "
254          + " org.jboss.aop.advice.Interceptor[] interceptors = " + Instrumentor.HELPER_FIELD_NAME + ".getFieldWriteInfos()[" + index + "].getInterceptors(); "
255          + " if (interceptors != (org.jboss.aop.advice.Interceptor[])null) "
256          + " { "
257          + " " + optimizedInvocation + " invocation = new " + optimizedInvocation + "(" + Instrumentor.HELPER_FIELD_NAME + ".getAdvisedFields()[" + index + "]," + index + ", ($w)$2" + ", interceptors); "
258          + " invocation.setTargetObject($1); "
259          + " invocation.setAdvisor(" + Instrumentor.HELPER_FIELD_NAME + "); "
260          + " invocation.invokeNext(); "
261          + " } "
262          + " else "
263          + " {"
264          + " " + clazz.getName() + "." + wrappedName + "=$2" + ";"
265          + " }"
266          + "}";
267       }
268       return code;
269    }
270    
271    
272    private void buildWrappers(CtClass clazz, CtField field, boolean doGet, boolean doSet, int index) throws NotFoundException, CannotCompileException
273    {
274       if (doGet)
275       {
276          String JavaDoc code = getReadWrapperBody(clazz, field, index);
277          CtMethod method = clazz.getDeclaredMethod(fieldRead(field.getName()));
278          method.setBody(code);
279       }
280       if (doSet)
281       {
282          String JavaDoc code = getWriteWrapperBody(clazz, field, index);
283          CtMethod method = clazz.getDeclaredMethod(fieldWrite(field.getName()));
284          method.setBody(code);
285       }
286
287
288    }
289    
290    protected void replaceFieldAccessInternally(CtClass clazz, CtField field, boolean doGet, boolean doSet, int index) throws CannotCompileException
291    {
292       OptimizedFieldAccessExprEditor expr = new OptimizedFieldAccessExprEditor(clazz, field, doGet, doSet, index);
293       clazz.instrument(expr);
294    }
295
296    protected class OptimizedFieldAccessExprEditor extends FieldAccessExprEditor
297    {
298       public OptimizedFieldAccessExprEditor(CtClass clazz, CtField field, boolean doGet, boolean doSet, int index)
299       {
300          super(clazz, field, doGet, doSet, index);
301       }
302
303       protected void replaceRead(FieldAccess fieldAccess) throws CannotCompileException
304       {
305          if (fieldAccess.isStatic())
306          {
307             String JavaDoc code =
308                     " { " +
309                     " $_ = ($r)" + fieldRead(field.getName()) + "(null);" +
310                     " } " +
311                      "";
312             fieldAccess.replace(code);
313          }
314          else
315          {
316             String JavaDoc code =
317                     " { " +
318                     " $_ = ($r)" + fieldRead(field.getName()) + "($0);" +
319                     " } " +
320                     "";
321             fieldAccess.replace(code);
322          }
323       }
324
325       protected void replaceWrite(FieldAccess fieldAccess) throws CannotCompileException
326       {
327          String JavaDoc fieldWrite = fieldWrite(field.getName());
328          if (fieldAccess.isStatic())
329          {
330             String JavaDoc code =
331                     " { " +
332                     " " + fieldWrite + "(null, $1);" +
333                     " } " +
334                     "";
335             fieldAccess.replace(code);
336
337          }
338          else
339          {
340             String JavaDoc code =
341                     " { " +
342                     " " + fieldWrite + "($0, $1);" +
343                     " } " +
344                     "";
345             fieldAccess.replace(code);
346          }
347       }
348    }
349
350    
351 }
352
Popular Tags