1 22 package org.jboss.aop.instrument; 23 24 import javassist.CannotCompileException; 25 import javassist.CtClass; 26 import javassist.CtField; 27 import javassist.CtMethod; 28 import javassist.CtNewMethod; 29 import javassist.Modifier; 30 import javassist.NotFoundException; 31 import javassist.bytecode.AccessFlag; 32 33 import org.jboss.aop.AspectManager; 34 import org.jboss.aop.ClassAdvisor; 35 import org.jboss.aop.classpool.AOPClassPool; 36 37 43 public class ClassicInstrumentor extends Instrumentor 44 { 45 48 public static final String HELPER_CLASS_NAME = 49 Instrumentor.AOP_PACKAGE + ".ClassAdvisor"; 50 51 public ClassicInstrumentor(AOPClassPool pool, AspectManager manager, JoinpointClassifier joinpointClassifier, DynamicTransformationObserver observer) 52 { 53 super(pool, 54 manager, 55 joinpointClassifier, 56 observer); 57 } 58 59 public ClassicInstrumentor(AspectManager manager, JoinpointClassifier joinpointClassifier) 60 { 61 super(manager, joinpointClassifier); 62 } 63 64 protected void intitialiseTransformers() 65 { 66 67 if (AspectManager.optimize) 68 { 69 methodExecutionTransformer = new OptimizedMethodExecutionTransformer(this); 70 constructorExecutionTransformer = new OptimizedConstructorExecutionTransformer(this); 71 fieldAccessTransformer = new OptimizedFieldAccessTransformer(this); 72 constructionTransformer = new OptimizedConstructionTransformer(this); 73 callerTransformer = new OptimizedCallerTransformer(this, manager); 74 } 75 else 76 { 77 methodExecutionTransformer = new NonOptimizedMethodExecutionTransformer(this); 78 constructorExecutionTransformer = new NonOptimizedConstructorExecutionTransformer(this); 79 fieldAccessTransformer = new NonOptimizedFieldAccessTransformer(this); 80 constructionTransformer = new NonOptimizedConstructionTransformer(this); 81 callerTransformer = new NonOptimizedCallerTransformer(this, manager); 82 } 83 } 84 85 protected CtMethod createMixinInvokeMethod(CtClass clazz, CtClass mixinClass, String initializer, CtMethod method, long hash) 86 throws CannotCompileException, NotFoundException, Exception 87 { 88 String code = null; 89 String aopReturnStr = (method.getReturnType().equals(CtClass.voidType)) ? "" : "return ($r)"; 90 String returnStr = (method.getReturnType().equals(CtClass.voidType)) ? "" : "return "; 91 String args = "null"; 92 if (method.getParameterTypes().length > 0) args = "$args"; 93 112 113 114 code = 116 "{ " + 117 "" + returnStr + " " + mixinFieldName(mixinClass) + "." + method.getName() + "($$); " + 118 "}"; 119 String wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), method.getName()); 120 CtMethod nmethod = CtNewMethod.make(method.getReturnType(), wrappedName, method.getParameterTypes(), 121 method.getExceptionTypes(), code, clazz); 122 int modifier = method.getModifiers(); 123 if ((modifier & AccessFlag.ABSTRACT) == AccessFlag.ABSTRACT) 124 { 125 modifier &= ~AccessFlag.ABSTRACT; 126 } 127 nmethod.setModifiers(modifier); 128 clazz.addMethod(nmethod); 129 130 131 132 code = 134 "{ " + 135 " if (" + mixinFieldName(mixinClass) + " == null) { " + 136 " this." + mixinFieldName(mixinClass) + " = " + initializer + "; " + 137 " } " + 138 " org.jboss.aop.ClassInstanceAdvisor instAdv = (org.jboss.aop.ClassInstanceAdvisor)_getInstanceAdvisor();" + 139 " if (" + HELPER_FIELD_NAME + ".hasAspects() || (instAdv != null && instAdv.hasInstanceAspects)) " + 140 " { " + 141 " Object[] ags = " + args + "; " + 142 " " + aopReturnStr + HELPER_FIELD_NAME + ".invokeMethod(instAdv, this, " + hash + "L, ags); " + 143 " } " + 144 " else " + 145 " {" + 146 " " + returnStr + " " + mixinFieldName(mixinClass) + "." + method.getName() + "($$); " + 147 " }" + 148 "}"; 149 150 CtMethod wmethod = null; 151 try 152 { 153 wmethod = CtNewMethod.make(method.getReturnType(), method.getName(), method.getParameterTypes(), 154 method.getExceptionTypes(), code, clazz); 155 wmethod.setModifiers(modifier); 156 } 157 catch (CannotCompileException e) 158 { 159 throw new RuntimeException ("<mixin> construction may have syntax error: '" + initializer + "'", e); 160 } 161 clazz.addMethod(wmethod); 162 163 return wmethod; 164 165 } 166 167 protected void doSetupBasics(CtClass clazz) throws CannotCompileException, NotFoundException 168 { 169 addHelperClass(clazz); 171 172 if (isBaseClass(clazz)) 173 { 174 addBaseElements(clazz); 175 } 176 } 177 178 private void addHelperField(CtClass clazz) throws CannotCompileException, NotFoundException 179 { 180 addStaticField(clazz, 181 ClassicInstrumentor.HELPER_FIELD_NAME, 182 ClassicInstrumentor.HELPER_CLASS_NAME, 183 CtField.Initializer.byExpr(ASPECT_MANAGER_CLASS_NAME + ".instance().getAdvisor(java.lang.Class#forName(\"" + 184 clazz.getName() + "\"))")); 185 } 186 187 190 private void addHelperClass(CtClass clazz) 191 throws CannotCompileException, NotFoundException 192 { 193 addHelperField(clazz); 194 CtMethod getter = CtNewMethod.make("public org.jboss.aop.Advisor _getAdvisor()" + 196 "{ " + 197 " return " + ClassicInstrumentor.HELPER_FIELD_NAME + ";" + 198 "}", 199 clazz); 200 clazz.addMethod(getter); 201 } 202 203 private void addBaseElements(CtClass clazz) 204 throws NotFoundException, CannotCompileException 205 { 206 addProtectedField(clazz, 207 "_instanceAdvisor", 208 "org.jboss.aop.ClassInstanceAdvisor", null 209 ); 211 212 CtMethod getter = CtNewMethod.make("public org.jboss.aop.InstanceAdvisor _getInstanceAdvisor()" + 213 "{ " + 214 " synchronized(this) {" + 215 " if (_instanceAdvisor == null) { _instanceAdvisor = new org.jboss.aop.ClassInstanceAdvisor(this); }" + 216 " return _instanceAdvisor;" + 217 " } " + 218 "}", 219 clazz); 220 clazz.addMethod(getter); 221 222 CtMethod setter = CtNewMethod.make("public void _setInstanceAdvisor(org.jboss.aop.InstanceAdvisor newAdvisor)" + 223 "{ " + 224 " synchronized(this) {" + 225 " _instanceAdvisor = (org.jboss.aop.ClassInstanceAdvisor)newAdvisor;" + 226 " } " + 227 "}", 228 clazz); 229 clazz.addMethod(setter); 230 231 } 232 233 234 235 } 236 | Popular Tags |