KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > transform > inlining > weaver > StaticInitializationVisitor


1 /**************************************************************************************
2  * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.transform.inlining.weaver;
9
10
11 import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType;
12 import org.codehaus.aspectwerkz.reflect.ClassInfo;
13 import org.codehaus.aspectwerkz.transform.Context;
14 import org.codehaus.aspectwerkz.transform.TransformationConstants;
15 import org.codehaus.aspectwerkz.transform.TransformationUtil;
16 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
17 import org.codehaus.aspectwerkz.transform.inlining.ContextImpl;
18 import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint;
19 import org.objectweb.asm.Attribute;
20 import org.objectweb.asm.ClassAdapter;
21 import org.objectweb.asm.ClassVisitor;
22 import org.objectweb.asm.CodeVisitor;
23 import org.objectweb.asm.Type;
24
25 import java.util.Set JavaDoc;
26
27 /**
28  * Adds a "proxy method" to the <tt>&lt;clinit&gt;</tt> that matches an
29  * <tt>staticinitialization</tt> pointcut as well as prefixing the "original method"
30  * (see {@link org.codehaus.aspectwerkz.transform.TransformationUtil#getPrefixedOriginalClinitName(String)}).
31  * <br/>
32  *
33  * @author <a HREF="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
34  */

35 public class StaticInitializationVisitor extends ClassAdapter implements TransformationConstants {
36
37     private final ContextImpl m_ctx;
38     private String JavaDoc m_declaringTypeName;
39     private final Set JavaDoc m_addedMethods;
40
41     /**
42      * Creates a new class adapter.
43      *
44      * @param cv
45      * @param ctx
46      * @param addedMethods already added methods by AW
47      */

48     public StaticInitializationVisitor( final ClassVisitor cv,
49                                         final Context ctx,
50                                         final Set JavaDoc addedMethods) {
51         super(cv);
52         m_ctx = (ContextImpl) ctx;
53         m_addedMethods = addedMethods;
54     }
55
56     /**
57      * Visits the class.
58      *
59      * @param access
60      * @param name
61      * @param superName
62      * @param interfaces
63      * @param sourceFile
64      */

65     public void visit( final int version,
66                         final int access,
67                         final String JavaDoc name,
68                         final String JavaDoc superName,
69                         final String JavaDoc[] interfaces,
70                         final String JavaDoc sourceFile) {
71         m_declaringTypeName = name;
72         super.visit(version, access, name, superName, interfaces, sourceFile);
73     }
74
75     /**
76      * Visits the methods.
77      *
78      * @param access
79      * @param name
80      * @param desc
81      * @param exceptions
82      * @param attrs
83      * @return
84      */

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

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