1 22 package org.jboss.aop.instrument; 23 24 import org.jboss.aop.ClassAdvisor; 25 import org.jboss.aop.util.JavassistMethodHashing; 26 27 import javassist.CannotCompileException; 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 41 public class GeneratedAdvisorMethodExecutionTransformer extends 42 MethodExecutionTransformer 43 { 44 public GeneratedAdvisorMethodExecutionTransformer(GeneratedAdvisorInstrumentor instrumentor) 45 { 46 super(instrumentor); 47 } 48 49 private String addMethodInfoFieldToGenAdvisor(MethodTransformation trans)throws NotFoundException, CannotCompileException 50 { 51 GeneratedAdvisorInstrumentor instrumentor = (GeneratedAdvisorInstrumentor)trans.getInstrumentor(); 52 CtClass genadvisor = instrumentor.getGenadvisor(); 53 String miname = addMethodInfoField( 54 Modifier.PROTECTED, 55 genadvisor, 56 trans); 57 58 addJoinpoint(miname, trans); 59 60 instrumentor.initaliseMethodInfo(miname, trans.getHash(), JavassistMethodHashing.methodHash(trans.getMethod())); 61 return miname; 62 } 63 64 protected boolean addInfoAsWeakReference() 65 { 66 return false; 67 } 68 69 public static String getJoinPointFieldName(MethodTransformation trans) 70 { 71 return MethodJoinPointGenerator.getInfoFieldName(trans.getOriginalName(), trans.getHash()); 72 } 73 74 public static String getJoinPointGeneratorFieldName(MethodTransformation trans) 75 { 76 return MethodJoinPointGenerator.getJoinPointGeneratorFieldName(trans.getOriginalName(), trans.getHash()); 77 } 78 79 private void addJoinpoint(String miname, MethodTransformation trans)throws CannotCompileException, NotFoundException 80 { 81 CtClass joinpoint = createJoinpointClass(miname, trans); 82 CtClass genadvisor = ((GeneratedAdvisorInstrumentor)trans.getInstrumentor()).getGenadvisor(); 83 CtField field = new CtField( 84 joinpoint, 85 getJoinPointFieldName(trans), 86 genadvisor); 87 field.setModifiers(Modifier.PROTECTED); 88 genadvisor.addField(field); 89 } 90 91 private CtClass createJoinpointClass(String miname, MethodTransformation trans) throws CannotCompileException, NotFoundException 92 { 93 return MethodJoinPointGenerator.createJoinpointBaseClass( 94 (GeneratedAdvisorInstrumentor)trans.getInstrumentor(), 95 trans.getClazz(), 96 trans.getMethod(), 97 miname, 98 trans.getOriginalName(), 99 trans.getWrappedName(), 100 trans.getHash()); 101 } 102 103 public CtMethod addMixinWrappersAndInfo( 104 GeneratedAdvisorInstrumentor instrumentor, 105 CtClass clazz, 106 CtClass mixinClass, 107 String initializer, 108 CtClass genadvisor, 109 CtMethod mixinMethod) throws CannotCompileException, NotFoundException 110 { 111 String originalName = mixinMethod.getName(); 112 String originalBody = 113 "{" + 114 " " + getReturnStr(mixinMethod) + " " + Instrumentor.mixinFieldName(mixinClass) + "." + mixinMethod.getName() + "($$);" + 115 "}"; 116 117 CtMethod original = CtNewMethod.make( 118 Modifier.PUBLIC, 119 mixinMethod.getReturnType(), 120 mixinMethod.getName(), 121 mixinMethod.getParameterTypes(), 122 mixinMethod.getExceptionTypes(), 123 originalBody, 124 clazz); 125 clazz.addMethod(original); 126 long hash = JavassistMethodHashing.methodHash(original); 127 copyAnnotations(mixinMethod, original); 128 129 String wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), originalName); 130 CtMethod wmethod = CtNewMethod.copy(original, clazz, null); 131 132 wmethod.setName(wrappedName); 133 clazz.addMethod(wmethod); 134 copyAnnotations(original, wmethod); 135 136 original.setName(wrappedName); 137 wmethod.setName(originalName); 138 139 MethodTransformation trans = new MethodTransformation(instrumentor, clazz, original, originalName, wmethod, wrappedName, hash); 140 141 String methodInfoField = addMethodInfoFieldToGenAdvisor(trans); 142 addMethodToGeneratedAdvisor(trans, methodInfoField); 143 144 String wrapperBody = 145 "{" + 146 " if (" + Instrumentor.mixinFieldName(mixinClass) + " == null)" + 147 " {" + 148 " " + Instrumentor.mixinFieldName(mixinClass) + " = " + initializer + ";" + 149 " }" + 150 " " + getReturnStr(trans.getMethod()) + " ((" + GeneratedAdvisorInstrumentor.getAdvisorFQN(trans.getClazz()) + ")" + GeneratedAdvisorInstrumentor.GET_CURRENT_ADVISOR + ")." + getAdvisorMethodName(trans) + "(this,$$);" + 151 "}"; 152 wmethod.setBody(wrapperBody); 153 return wmethod; 154 } 155 156 protected void transformMethod(MethodTransformation trans, boolean wrap) 157 throws CannotCompileException, NotFoundException 158 { 159 String wrappedName = ClassAdvisor.notAdvisedMethodName(trans.getClazzName(), 161 trans.getMethod().getName()); 162 CtMethod wmethod = CtNewMethod.copy(trans.getMethod(), trans.getClazz(), null); 163 164 String originalName = trans.getOriginalName(); 165 wmethod.setName(wrappedName); 166 trans.getClazz().addMethod(wmethod); 167 copyAnnotations(trans.getMethod(), wmethod); 168 trans.getMethod().setName(wrappedName); 169 wmethod.setName(originalName); 170 171 trans.setWMethod(wmethod, wrappedName); 172 173 String methodInfoField = addMethodInfoFieldToGenAdvisor(trans); 174 addMethodToGeneratedAdvisor(trans, methodInfoField); 175 176 getWrapper().prepareForWrapping(wmethod, WrapperTransformer.SINGLE_TRANSFORMATION_INDEX); 178 179 180 if (wrap) 181 { 182 getWrapper().wrap(wmethod, WrapperTransformer.SINGLE_TRANSFORMATION_INDEX); 184 185 setWrapperBody(trans, methodInfoField); 187 } 188 } 189 190 protected void doWrap(MethodTransformation trans, String methodInfoFieldName) throws NotFoundException, 191 Exception 192 { 193 195 } 196 197 private void setWrapperBody(MethodTransformation trans, String methodInfoField) throws NotFoundException 198 { 199 String code = null; 200 final String className = 201 GeneratedAdvisorInstrumentor.getAdvisorFQN(trans.getClazz()); 202 203 try 204 { 205 if (Modifier.isStatic(trans.getMethod().getModifiers())) 206 { 207 code = 208 "{" + 209 " " + getReturnStr(trans.getMethod()) + " ((" + className + ")" + Instrumentor.HELPER_FIELD_NAME + ")." + getAdvisorMethodName(trans) + "($$);" + 210 "}"; 211 trans.setWMethodBody(code); 212 } 213 else 214 { 215 code = 216 "{" + 217 " " + getReturnStr(trans.getMethod()) + " ((" + className + ")" + GeneratedAdvisorInstrumentor.GET_CURRENT_ADVISOR + ")." + getAdvisorMethodName(trans) + "(this,$$);" + 218 "}"; 219 220 trans.setWMethodBody(code); 221 } 222 } 223 catch (CannotCompileException e) 224 { 225 e.printStackTrace(); 226 throw new RuntimeException ("code was: " + code + " for method " + trans.getOriginalName()); 227 } 228 } 229 230 protected static CtClass[] addTargetToParamsForNonStaticMethod(CtClass outer, CtMethod method)throws NotFoundException 231 { 232 CtClass[] params = method.getParameterTypes(); 233 234 if (!Modifier.isStatic(method.getModifiers())) 235 { 236 CtClass[] tempParams = params; 237 params = new CtClass[params.length + 1]; 238 params[0] = outer; 239 System.arraycopy(tempParams, 0, params, 1, tempParams.length); 240 } 241 242 return params; 243 } 244 245 251 private String getAdvisorMethodName(MethodTransformation trans) 252 { 253 if (trans.getHash() >= 0) 254 { 255 return trans.getOriginalName() + trans.getHash(); 256 } 257 else 258 { 259 return trans.getOriginalName() + "_N_" + Math.abs(trans.getHash()); 260 } 261 } 262 263 private void addMethodToGeneratedAdvisor(MethodTransformation trans, String methodInfoField)throws CannotCompileException, NotFoundException 264 { 265 CtClass genadvisor = ((GeneratedAdvisorInstrumentor)trans.getInstrumentor()).getGenadvisor(); 266 267 CtClass[] params = addTargetToParamsForNonStaticMethod(trans.getClazz(), trans.getWMethod()); 268 269 String code = createAdvisorMethodBody(trans, genadvisor); 270 try 271 { 272 CtMethod advisorMethod = CtNewMethod.make( 273 Modifier.PROTECTED, 274 trans.getWMethod().getReturnType(), 275 getAdvisorMethodName(trans), 276 params, 277 trans.getWMethod().getExceptionTypes(), 278 code, 279 genadvisor); 280 281 genadvisor.addMethod(advisorMethod); 282 advisorMethod.setModifiers(Modifier.setProtected(advisorMethod.getModifiers())); 283 } 284 catch (CannotCompileException e) 285 { 286 throw new RuntimeException ("code was: " + code + " for method " + getAdvisorMethodName(trans), e); 287 } 288 } 289 290 private String createAdvisorMethodBody(MethodTransformation trans, CtClass ga)throws NotFoundException 291 { 292 if (Modifier.isStatic(trans.getWMethod().getModifiers())) 293 { 294 return createStaticAdvisorMethodBody(trans); 295 } 296 else 297 { 298 return createNonStaticAdvisorMethodBody(trans, ga); 299 } 300 } 301 302 private String createStaticAdvisorMethodBody(MethodTransformation trans)throws NotFoundException 303 { 304 String infoName = getJoinPointFieldName(trans); 305 String generatorName = getJoinPointGeneratorFieldName(trans); 306 String code = 307 "{" + 308 " if (" + infoName + " == null && " + generatorName + " != null)" + 309 " {" + 310 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 311 " }" + 312 " if (" + infoName + " == null)" + 313 " { " + 314 " " + getReturnStr(trans.getWMethod()) + trans.getClazzName() + "." + trans.getWrappedName() +"($$);" + 315 " }" + 316 " else" + 317 " {" + 318 " " + getAopReturnStr(trans.getWMethod()) + infoName + "." + JoinPointGenerator.INVOKE_JOINPOINT + "($$);" + 319 " }" + 320 "}"; 321 322 return code; 323 } 324 325 private String createNonStaticAdvisorMethodBody(MethodTransformation trans, CtClass ga)throws NotFoundException 326 { 327 String infoName = getJoinPointFieldName(trans); 328 String generatorName = getJoinPointGeneratorFieldName(trans); 329 String code = 330 "{" + 331 " if (" + infoName + " == null && " + generatorName + " != null)" + 332 " {" + 333 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 334 " }" + 335 " if (" + infoName + " == null)" + 336 " { " + 337 " " + getAopReturnStr(trans.getWMethod()) + "$1." + trans.getWrappedName() + "(" + getNonStaticJavasistParamString(trans.getWMethod().getParameterTypes().length) + ");" + 338 " }" + 339 " else" + 340 " {" + 341 " " + getAopReturnStr(trans.getWMethod()) + infoName + "." + MethodJoinPointGenerator.INVOKE_JOINPOINT + "($$);" + 342 " }" + 343 "}"; 344 345 return code; 346 } 347 348 public static String getNonStaticJavasistParamString(long parameterLength)throws NotFoundException 349 { 350 StringBuffer str = new StringBuffer (); 351 352 for (int i = 0 ; i < parameterLength ; i++) 353 { 354 if (i > 0) 355 { 356 str.append(", "); 357 } 358 str.append("$" + (i + 2)); 359 } 360 361 return str.toString(); 362 } 363 } 364 | Popular Tags |