1 8 package org.codehaus.aspectwerkz.transform.inlining.weaver; 9 10 import java.lang.reflect.Modifier ; 11 import java.util.Iterator ; 12 import java.util.Set ; 13 14 import org.objectweb.asm.*; 15 import org.codehaus.aspectwerkz.transform.Context; 16 import org.codehaus.aspectwerkz.transform.TransformationUtil; 17 import org.codehaus.aspectwerkz.transform.TransformationConstants; 18 import org.codehaus.aspectwerkz.transform.inlining.ContextImpl; 19 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper; 20 import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint; 21 import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType; 22 import org.codehaus.aspectwerkz.definition.SystemDefinition; 23 import org.codehaus.aspectwerkz.expression.ExpressionContext; 24 import org.codehaus.aspectwerkz.expression.PointcutType; 25 import org.codehaus.aspectwerkz.reflect.ClassInfo; 26 import org.codehaus.aspectwerkz.reflect.MethodInfo; 27 28 43 public class MethodExecutionVisitor extends ClassAdapter implements TransformationConstants { 44 45 private final ClassInfo m_classInfo; 46 private final ContextImpl m_ctx; 47 private String m_declaringTypeName; 48 private final Set m_addedMethods; 49 50 58 public MethodExecutionVisitor(final ClassVisitor cv, 59 final ClassInfo classInfo, 60 final Context ctx, 61 final Set addedMethods) { 62 super(cv); 63 m_classInfo = classInfo; 64 m_ctx = (ContextImpl) ctx; 65 m_addedMethods = addedMethods; 66 } 67 68 77 public void visit(final int version, 78 final int access, 79 final String name, 80 final String superName, 81 final String [] interfaces, 82 final String sourceFile) { 83 m_declaringTypeName = name; 84 super.visit(version, access, name, superName, interfaces, sourceFile); 85 } 86 87 97 public CodeVisitor visitMethod(final int access, 98 final String name, 99 final String desc, 100 final String [] exceptions, 101 final Attribute attrs) { 102 103 if (INIT_METHOD_NAME.equals(name) || 104 CLINIT_METHOD_NAME.equals(name) || 105 name.startsWith(ASPECTWERKZ_PREFIX) || 106 name.startsWith(SYNTHETIC_MEMBER_PREFIX) || 107 name.startsWith(WRAPPER_METHOD_PREFIX)) { 108 return cv.visitMethod(access, name, desc, exceptions, attrs); 109 } 110 111 int hash = AsmHelper.calculateMethodHash(name, desc); 112 MethodInfo methodInfo = m_classInfo.getMethod(hash); 113 if (methodInfo == null) { 114 System.err.println( 115 "AW::WARNING " + 116 "metadata structure could not be build for method [" 117 + m_classInfo.getName().replace('/', '.') 118 + '.' + name + ':' + desc + ']' 119 ); 120 return cv.visitMethod(access, name, desc, exceptions, attrs); 122 } 123 124 ExpressionContext ctx = new ExpressionContext(PointcutType.EXECUTION, methodInfo, methodInfo); 125 126 if (methodFilter(m_ctx.getDefinitions(), ctx, methodInfo)) { 127 return cv.visitMethod(access, name, desc, exceptions, attrs); 128 } else { 129 String prefixedOriginalName = TransformationUtil.getPrefixedOriginalMethodName(name, m_declaringTypeName); 130 if (m_addedMethods.contains(AlreadyAddedMethodAdapter.getMethodKey(prefixedOriginalName, desc))) { 131 return cv.visitMethod(access, name, desc, exceptions, attrs); 132 } 133 134 m_ctx.markAsAdvised(); 135 136 createProxyMethod(access, name, desc, exceptions, attrs, methodInfo); 138 139 int modifiers = ACC_SYNTHETIC; 140 if (Modifier.isStatic(access)) { 141 modifiers |= ACC_STATIC; 142 } 143 return cv.visitMethod( 145 modifiers, 146 prefixedOriginalName, 147 desc, exceptions, attrs 148 ); 149 } 150 } 151 152 162 private void createProxyMethod(final int access, 163 final String name, 164 final String desc, 165 final String [] exceptions, 166 final Attribute attrs, 167 final MethodInfo methodInfo) { 168 CodeVisitor mv = cv.visitMethod(access, name, desc, exceptions, attrs); 169 170 if (!Modifier.isStatic(access)) { 172 mv.visitVarInsn(ALOAD, 0); 173 } 174 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), Modifier.isStatic(access)); 176 if (Modifier.isStatic(access)) { 178 mv.visitInsn(ACONST_NULL); 179 } else { 180 mv.visitVarInsn(ALOAD, 0); 181 } 182 183 int joinPointHash = AsmHelper.calculateMethodHash(name, desc); 184 String joinPointClassName = TransformationUtil.getJoinPointClassName( 185 m_declaringTypeName, 186 name, 187 desc, 188 m_declaringTypeName, 189 JoinPointType.METHOD_EXECUTION_INT, 190 joinPointHash 191 ); 192 193 196 mv.visitMethodInsn( 197 INVOKESTATIC, 198 joinPointClassName, 199 INVOKE_METHOD_NAME, 200 TransformationUtil.getInvokeSignatureForCodeJoinPoints( 201 access, desc, m_declaringTypeName, m_declaringTypeName 202 ) 203 ); 204 205 AsmHelper.addReturnStatement(mv, Type.getReturnType(desc)); 206 mv.visitMaxs(0, 0); 207 208 m_ctx.addEmittedJoinPoint( 210 new EmittedJoinPoint( 211 JoinPointType.METHOD_EXECUTION_INT, 212 m_declaringTypeName, 213 name, 214 desc, 215 access, 216 m_declaringTypeName, 217 name, 218 desc, 219 access, 220 joinPointHash, 221 joinPointClassName, 222 EmittedJoinPoint.NO_LINE_NUMBER 223 ) 224 ); 225 } 226 227 235 public static boolean methodFilter(final Set definitions, 236 final ExpressionContext ctx, 237 final MethodInfo methodInfo) { 238 if (Modifier.isAbstract(methodInfo.getModifiers()) 239 || Modifier.isNative(methodInfo.getModifiers()) 240 || methodInfo.getName().equals(INIT_METHOD_NAME) 241 || methodInfo.getName().equals(CLINIT_METHOD_NAME) 242 || methodInfo.getName().startsWith(ORIGINAL_METHOD_PREFIX)) { 243 return true; 244 } 245 for (Iterator it = definitions.iterator(); it.hasNext();) { 246 if (((SystemDefinition) it.next()).hasPointcut(ctx)) { 247 return false; 248 } else { 249 continue; 250 } 251 } 252 return true; 253 } 254 } | Popular Tags |