KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > transform > inlining > weaver > StaticInitializationVisitor


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.weaver;
5
6 import com.tc.asm.ClassAdapter;
7 import com.tc.asm.ClassVisitor;
8 import com.tc.asm.MethodVisitor;
9 import com.tc.asm.Type;
10
11 import com.tc.aspectwerkz.joinpoint.management.JoinPointType;
12 import com.tc.aspectwerkz.transform.InstrumentationContext;
13 import com.tc.aspectwerkz.transform.TransformationConstants;
14 import com.tc.aspectwerkz.transform.TransformationUtil;
15 import com.tc.aspectwerkz.transform.inlining.AsmHelper;
16 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint;
17
18 import java.util.Set JavaDoc;
19
20 /**
21  * Adds a "proxy method" to the <tt>&lt;clinit&gt;</tt> that matches an
22  * <tt>staticinitialization</tt> pointcut as well as prefixing the "original method"
23  * (see {@link com.tc.aspectwerkz.transform.TransformationUtil#getPrefixedOriginalClinitName(String)}).
24  * <br/>
25  *
26  * @author <a HREF="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
27  */

28 public class StaticInitializationVisitor extends ClassAdapter implements TransformationConstants {
29
30   private final InstrumentationContext m_ctx;
31   private String JavaDoc m_declaringTypeName;
32   private final Set JavaDoc m_addedMethods;
33
34   /**
35    * Creates a new class adapter.
36    *
37    * @param cv
38    * @param ctx
39    * @param addedMethods already added methods by AW
40    */

41   public StaticInitializationVisitor(final ClassVisitor cv,
42                                      final InstrumentationContext ctx,
43                                      final Set JavaDoc addedMethods) {
44     super(cv);
45     m_ctx = (InstrumentationContext) ctx;
46     m_addedMethods = addedMethods;
47   }
48
49   /**
50    * Visits the class.
51    *
52    * @param access
53    * @param name
54    * @param signature
55    * @param superName
56    * @param interfaces
57    */

58   public void visit(final int version,
59                     final int access,
60                     final String JavaDoc name,
61                     final String JavaDoc signature,
62                     final String JavaDoc superName,
63                     final String JavaDoc[] interfaces) {
64     m_declaringTypeName = name;
65     super.visit(version, access, name, signature, superName, interfaces);
66   }
67
68   /**
69    * Visits the methods.
70    *
71    * @param access
72    * @param name
73    * @param desc
74    * @param signature
75    * @param exceptions
76    * @return
77    */

78   public MethodVisitor visitMethod(final int access,
79                                    final String JavaDoc name,
80                                    final String JavaDoc desc,
81                                    final String JavaDoc signature,
82                                    final String JavaDoc[] exceptions) {
83     if (!CLINIT_METHOD_NAME.equals(name)) {
84       return super.visitMethod(access, name, desc, signature, exceptions);
85     }
86
87     String JavaDoc prefixedOriginalName = TransformationUtil.getPrefixedOriginalClinitName(m_declaringTypeName);
88     if (m_addedMethods.contains(AlreadyAddedMethodAdapter.getMethodKey(prefixedOriginalName, CLINIT_METHOD_SIGNATURE)))
89     {
90       return super.visitMethod(access, name, desc, signature, exceptions);
91     }
92
93     m_ctx.markAsAdvised();
94
95     // create the proxy for the original method
96
createProxyMethod(access, name, desc, signature, exceptions);
97
98     // prefix the original method
99
return cv.visitMethod(access + ACC_PUBLIC, prefixedOriginalName, desc, signature, exceptions);
100   }
101
102   /**
103    * Creates the "proxy method", e.g. the method that has the same name and
104    * signature as the original method but a completely other implementation.
105    *
106    * @param access
107    * @param name
108    * @param desc
109    * @param signature
110    * @param exceptions
111    */

112   private void createProxyMethod(final int access,
113                                  final String JavaDoc name,
114                                  final String JavaDoc desc,
115                                  final String JavaDoc signature,
116                                  final String JavaDoc[] exceptions) {
117     MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
118
119     //caller instance is null
120
mv.visitInsn(ACONST_NULL);
121
122     int joinPointHash = AsmHelper.calculateMethodHash(name, desc);
123     String JavaDoc joinPointClassName = TransformationUtil
124             .getJoinPointClassName(m_declaringTypeName,
125                     name,
126                     desc,
127                     m_declaringTypeName,
128                     JoinPointType.STATIC_INITIALIZATION_INT,
129                     joinPointHash);
130
131     mv.visitMethodInsn(INVOKESTATIC,
132             joinPointClassName,
133             INVOKE_METHOD_NAME,
134             TransformationUtil.getInvokeSignatureForCodeJoinPoints(access,
135                     desc,
136                     m_declaringTypeName,
137                     m_declaringTypeName));
138
139     AsmHelper.addReturnStatement(mv, Type.VOID_TYPE);
140     mv.visitMaxs(0, 0);
141
142     // emit the joinpoint
143
m_ctx.addEmittedJoinPoint(
144             new EmittedJoinPoint(JoinPointType.STATIC_INITIALIZATION_INT,
145                     m_declaringTypeName,
146                     name,
147                     desc,
148                     access,
149                     m_declaringTypeName,
150                     name,
151                     desc,
152                     access,
153                     joinPointHash,
154                     joinPointClassName,
155                     EmittedJoinPoint.NO_LINE_NUMBER
156             )
157     );
158   }
159 }
160
Popular Tags