1 22 package org.jboss.aop.instrument; 23 24 import org.jboss.aop.classpool.AOPClassPool; 25 import org.jboss.aop.util.JavassistToReflect; 26 27 import javassist.CannotCompileException; 28 import javassist.ClassPool; 29 import javassist.CtClass; 30 import javassist.CtField; 31 import javassist.CtMethod; 32 import javassist.CtNewMethod; 33 import javassist.Modifier; 34 import javassist.NotFoundException; 35 36 42 public class OptimizedFieldInvocations extends OptimizedInvocations 43 { 44 45 protected static String getOptimizedInvocationClassName(CtClass clazz, CtField field, boolean get) throws Exception 46 { 47 StringBuffer sb = new StringBuffer (clazz.getName()); 48 sb.append(".") 49 .append(field.getName()); 50 51 if (get) 52 { 53 sb.append("_Get"); 54 } 55 else 56 { 57 sb.append("_Set"); 58 } 59 60 return sb.toString(); 61 } 62 63 protected static void addCopy(ClassPool pool, CtClass invocation, boolean isStatic, boolean isGet) throws Exception 64 { 65 CtClass fieldInvocation = 66 isGet 67 ? pool.get("org.jboss.aop.joinpoint.FieldReadInvocation") 68 : pool.get("org.jboss.aop.joinpoint.FieldWriteInvocation"); 69 CtMethod template = fieldInvocation.getDeclaredMethod("copy"); 70 71 String newExpr = 72 (isGet) 73 ? invocation.getName() 74 + " wrapper = new " 75 + invocation.getName() 76 + "(this.field, this.index, this.interceptors); " 77 : invocation.getName() 78 + " wrapper = new " 79 + invocation.getName() 80 + "(this.field, this.index, this.value, this.interceptors); "; 81 82 String code = 83 "{ " 84 + " " 85 + newExpr 86 + " wrapper.metadata = this.metadata; " 87 + " wrapper.currentInterceptor = this.currentInterceptor; " 88 + " wrapper.instanceResolver = this.instanceResolver; "; 89 if (!isStatic) 90 { 91 code += " wrapper.typedTargetObject = this.typedTargetObject; "; 92 code += " wrapper.targetObject = this.targetObject; "; 93 } 94 95 code += " return wrapper; }"; 96 97 CtMethod copy = 98 CtNewMethod.make(template.getReturnType(), 99 "copy", 100 template.getParameterTypes(), 101 template.getExceptionTypes(), 102 code, 103 invocation); 104 copy.setModifiers(template.getModifiers()); 105 invocation.addMethod(copy); 106 107 } 108 109 protected static String createOptimizedInvocationClass(Instrumentor instrumentor, CtClass clazz, CtField field, boolean get) throws Exception 110 { 111 AOPClassPool pool = (AOPClassPool) instrumentor.getClassPool(); 112 CtClass fieldInvocation = 113 get 114 ? pool.get("org.jboss.aop.joinpoint.FieldReadInvocation") 115 : pool.get("org.jboss.aop.joinpoint.FieldWriteInvocation"); 116 117 String className = getOptimizedInvocationClassName(clazz, field, get); 118 boolean makeInnerClass = true; 120 try 121 { 122 CtClass existing = pool.get(className); 125 if (existing.isFrozen()) 126 { 127 existing.defrost(); 128 } 129 } 130 catch (NotFoundException e) 131 { 132 } 134 135 CtClass invocation = makeInvocationClass(pool, makeInnerClass, clazz, className, fieldInvocation); 136 invocation.stopPruning(true); 137 138 boolean isStatic = javassist.Modifier.isStatic(field.getModifiers()); 139 if (!isStatic) 140 { 141 CtField target = new CtField(field.getDeclaringClass(), "typedTargetObject", invocation); 142 target.setModifiers(Modifier.PUBLIC); 143 invocation.addField(target); 144 } 145 addCopy(pool, invocation, isStatic, get); 146 147 setInvocationInvokeCode(invocation, field, get); 148 149 TransformerCommon.compileOrLoadClass(field.getDeclaringClass(), invocation); 150 151 return invocation.getName(); 153 } 154 155 163 private static void setInvocationInvokeCode(CtClass invocation, CtField field, boolean get) throws CannotCompileException, NotFoundException 164 { 165 CtMethod in = invocation.getSuperclass().getDeclaredMethod("invokeTarget"); 166 167 String code = "{"; 168 169 String ref = Modifier.isStatic(field.getModifiers()) ? field.getDeclaringClass().getName() + "." : " typedTargetObject."; 170 171 if (get) 172 { 173 code += "return ($w) " + ref + field.getName() + ";"; 174 } 175 else 176 { 177 CtClass type = field.getType(); 179 code += ref + field.getName() + " = " + JavassistToReflect.castInvocationValueToTypeString(type) + " return null;"; 180 } 181 182 code += "}"; 183 CtMethod invokeTarget = 184 CtNewMethod.make(in.getReturnType(), 185 in.getName(), 186 in.getParameterTypes(), 187 in.getExceptionTypes(), 188 code, 189 invocation); 190 invokeTarget.setModifiers(in.getModifiers()); 191 invocation.addMethod(invokeTarget); 192 } 193 194 195 } 196 | Popular Tags |