1 22 package org.jboss.aop.instrument; 23 24 import java.lang.reflect.Method ; 25 26 import javassist.CannotCompileException; 27 import javassist.ClassPool; 28 import javassist.CtClass; 29 import javassist.CtField; 30 import javassist.CtMethod; 31 import javassist.CtNewMethod; 32 import javassist.Modifier; 33 import javassist.NotFoundException; 34 35 import org.jboss.aop.ClassAdvisor; 36 import org.jboss.aop.classpool.AOPClassPool; 37 38 44 public class OptimizedMethodInvocations extends OptimizedBehaviourInvocations 45 { 46 static String getOptimizedInvocationClassName(CtClass clazz, CtMethod method) 47 { 48 long hash = org.jboss.aop.util.JavassistMethodHashing.methodHash(method); 49 StringBuffer sb = new StringBuffer (clazz.getName()); 50 sb.append(".") 51 .append(method.getName()) 52 .append("_") 53 .append(Long.toString(hash).replace('-', 'N')); 54 return sb.toString(); 55 } 56 57 public static String getOptimizedInvocationClassName(Method method) throws Exception 58 { 59 long hash = org.jboss.aop.util.MethodHashing.methodHash(method); 60 StringBuffer sb = new StringBuffer (method.getDeclaringClass().getName()); 61 sb.append(".") 62 .append(method.getName()) 63 .append("_") 64 .append(Long.toString(hash).replace('-', 'N')); 65 return sb.toString(); 66 } 67 68 protected static String createOptimizedInvocationClass(Instrumentor instrumentor, CtClass clazz, CtMethod method) throws NotFoundException, CannotCompileException 69 { 70 String wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), 71 method.getName()); 72 AOPClassPool pool = (AOPClassPool) instrumentor.getClassPool(); 73 CtClass methodInvocation = pool.get("org.jboss.aop.joinpoint.MethodInvocation"); 74 75 String className = getOptimizedInvocationClassName(clazz, method); 76 boolean makeInnerClass = true; 78 CtClass invocation = makeInvocationClass(pool, makeInnerClass, clazz, className, methodInvocation); 79 CtClass[] params = method.getParameterTypes(); 80 addArgumentFieldsToInvocation(invocation, params); 81 82 boolean isStatic = javassist.Modifier.isStatic(method.getModifiers()); 83 if (!isStatic) 84 { 85 CtField target = new CtField(method.getDeclaringClass(), "typedTargetObject", invocation); 86 target.setModifiers(Modifier.PUBLIC); 87 invocation.addField(target); 88 } 89 90 CtMethod in = methodInvocation.getDeclaredMethod("invokeTarget"); 91 92 String code = "{"; 93 94 String returnStr = (method.getReturnType().equals(CtClass.voidType)) ? "" : "return ($w)"; 95 if (isStatic) 96 { 97 code += 98 " " + returnStr + " " + method.getDeclaringClass().getName() + "."; 99 } 100 else 101 { 102 code += 103 " " + returnStr + " typedTargetObject."; 104 } 105 code += wrappedName + "("; 106 for (int i = 0; i < params.length; i++) 107 { 108 if (i > 0) code += ", "; 109 code += "arg" + i; 110 } 111 code += "); "; 112 if (method.getReturnType().equals(CtClass.voidType)) 113 { 114 code += " return null; "; 115 } 116 code += "}"; 117 118 CtMethod invokeTarget = null; 119 try 120 { 121 invokeTarget = CtNewMethod.make(in.getReturnType(), "invokeTarget", in.getParameterTypes(), in.getExceptionTypes(), code, invocation); 122 } 123 catch (CannotCompileException e) 124 { 125 System.out.println(code); 126 throw e; 127 } 128 invokeTarget.setModifiers(in.getModifiers()); 129 invocation.addMethod(invokeTarget); 130 addSetArguments(pool, invocation, method.getParameterTypes()); 131 addGetArguments(pool, invocation, method.getParameterTypes(), true); 132 addCopy(pool, invocation, method.getParameterTypes(), isStatic); 133 134 TransformerCommon.compileOrLoadClass(method.getDeclaringClass(), invocation); 135 136 return invocation.getName(); 138 } 139 140 static void addCopy(ClassPool pool, CtClass invocation, CtClass[] params, boolean isStatic) throws NotFoundException, CannotCompileException 141 { 142 CtClass methodInvocation = pool.get("org.jboss.aop.joinpoint.MethodInvocation"); 143 CtMethod template = methodInvocation.getDeclaredMethod("copy"); 144 145 StringBuffer code = new StringBuffer ("{"); 146 code.append(" ").append(invocation.getName()).append(" wrapper = new ").append(invocation.getName()).append("(this.interceptors, methodHash, advisedMethod, unadvisedMethod, advisor); ") 147 .append(" wrapper.arguments = this.arguments; ") 148 .append(" wrapper.metadata = this.metadata; ") 149 .append(" wrapper.currentInterceptor = this.currentInterceptor; ") 150 .append(" wrapper.instanceResolver = this.instanceResolver; "); 151 if (!isStatic) 152 { 153 code.append(" wrapper.typedTargetObject = this.typedTargetObject; "); 154 code.append(" wrapper.targetObject = this.targetObject; "); 155 } 156 157 for (int i = 0; i < params.length; i++) 158 { 159 code.append(" wrapper.arg").append(i).append(" = this.arg").append(i).append("; "); 160 } 161 code.append(" return wrapper; }"); 162 163 CtMethod copy = CtNewMethod.make(template.getReturnType(), "copy", template.getParameterTypes(), template.getExceptionTypes(), code.toString(), invocation); 164 copy.setModifiers(template.getModifiers()); 165 invocation.addMethod(copy); 166 167 } 168 169 } 170 | Popular Tags |