1 22 package org.jboss.aop.instrument; 23 24 import javassist.CannotCompileException; 25 import javassist.CtClass; 26 import javassist.CtConstructor; 27 import javassist.CtField; 28 import javassist.CtMethod; 29 import javassist.CtNewConstructor; 30 import javassist.CtNewMethod; 31 import javassist.Modifier; 32 import javassist.NotFoundException; 33 34 import org.jboss.aop.AspectManager; 35 import org.jboss.aop.ClassAdvisor; 36 import org.jboss.aop.ConByMethodInfo; 37 import org.jboss.aop.FieldInfo; 38 import org.jboss.aop.GeneratedClassAdvisor; 39 import org.jboss.aop.JoinPointInfo; 40 import org.jboss.aop.MethodByMethodInfo; 41 import org.jboss.aop.MethodInfo; 42 import org.jboss.aop.classpool.AOPClassPool; 43 44 50 public class GeneratedAdvisorInstrumentor extends Instrumentor 51 { 52 private static final String CURRENT_ADVISOR = "currentAdvisor$aop"; 54 private static final String INSTANCE_ADVISOR = "instanceAdvisor$aop"; 55 private static final String GET_CURRENT_ADVISOR_NAME = "getCurrentAdvisor$aop"; 56 public static final String GET_CURRENT_ADVISOR = GET_CURRENT_ADVISOR_NAME + "()"; 57 58 private static final String DOMAIN = "domain"; 61 private static final String VERSION = "version"; 62 private static final String CHECK_VERSION = "checkVersion"; 63 private static final String ADVICES_UPDATED = "advicesUpdated"; 64 private static final String INSTANCE_ADVISOR_MIXIN = "instanceAdvisorMixin"; 65 66 private static final String CREATE_INSTANCE_ADVISOR = "createInstanceAdvisor"; 68 private static final String INITIALISE_CALLERS = "initialiseCallers"; 69 private static final String INITIALISE_FIELD_WRITES = "initialiseFieldWrites"; 70 private static final String INITIALISE_FIELD_READS = "initialiseFieldReads"; 71 private static final String INITIALISE_CONSTRUCTIONS = "initialiseConstructions"; 72 private static final String INITIALISE_CONSTRUCTORS = "initialiseConstructors"; 73 private static final String INITIALISE_METHODS = "initialiseMethods"; 74 public static final String GET_CLASS_ADVISOR = "_getClassAdvisor"; 75 76 private static final String DECLARING_CLASS = "this.getClass().getDeclaringClass()"; 77 private static final String CONTAINER_CLASS = "this.getClass().getDeclaringClass()"; 78 79 80 private static final CtClass[] EMPTY_EXCEPTIONS = new CtClass[0]; 81 private static final CtClass[] EMPTY_SIG = new CtClass[0]; 82 83 CtClass clazz; 84 CtClass genadvisor; 85 CtClass genInstanceAdvisor; 86 87 88 public GeneratedAdvisorInstrumentor(AOPClassPool pool, AspectManager manager, JoinpointClassifier joinpointClassifier, DynamicTransformationObserver observer) 89 { 90 super(pool, manager, joinpointClassifier, observer); 91 } 92 93 public GeneratedAdvisorInstrumentor(AspectManager manager, JoinpointClassifier joinpointClassifier) 94 { 95 super(manager, joinpointClassifier); 96 } 97 98 protected CtClass getGenadvisor() 99 { 100 return genadvisor; 101 } 102 103 protected CtClass getGenInstanceadvisor() 104 { 105 return genInstanceAdvisor; 106 } 107 108 public boolean transform(CtClass clazz, ClassAdvisor advisor) 109 { 110 try 111 { 112 this.clazz = clazz; 113 super.transform(clazz, advisor); 114 115 if (genadvisor != null) 116 { 117 addInstanceAdvisorWrappers(clazz); 118 TransformerCommon.compileOrLoadClass(clazz, genadvisor); 119 TransformerCommon.compileOrLoadClass(clazz, genInstanceAdvisor); 120 } 121 return true; 122 } 123 catch (Throwable e) 124 { 125 if (AspectManager.suppressTransformationErrors) 126 { 127 System.err.println("[warn] AOP Instrumentor failed to transform " + clazz.getName()); 128 e.printStackTrace(); 129 return false; 130 } 131 else 132 { 133 if (e instanceof TransformationException) 134 { 135 throw ((TransformationException) e); 136 } 137 else 138 { 139 e.printStackTrace(); 140 throw new RuntimeException ("failed to transform: " + clazz.getName(), e); 141 } 142 } 143 144 } 145 } 146 147 protected void intitialiseTransformers() 148 { 149 callerTransformer = new GeneratedAdvisorCallerTransformer(this, manager); 150 fieldAccessTransformer = new GeneratedAdvisorFieldAccessTransformer(this); 151 constructorExecutionTransformer = new GeneratedAdvisorConstructorExecutionTransformer(this); 152 constructionTransformer = new GeneratedAdvisorConstructionTransformer(this); 153 methodExecutionTransformer = new GeneratedAdvisorMethodExecutionTransformer(this); 154 } 155 156 protected CtMethod createMixinInvokeMethod(CtClass clazz, CtClass mixinClass, String initializer, CtMethod method, long hash) 157 throws CannotCompileException, NotFoundException, Exception 158 { 159 return ((GeneratedAdvisorMethodExecutionTransformer)methodExecutionTransformer).addMixinWrappersAndInfo(this, clazz, mixinClass, initializer, genadvisor, method); 160 } 161 162 protected static String getAdvisorName(CtClass clazz) 163 { 164 String className = clazz.getName(); 166 return className.substring(className.lastIndexOf('.') + 1) + "Advisor"; 167 } 168 169 protected static String getInstanceAdvisorName(CtClass clazz) 170 { 171 String className = clazz.getName(); 173 return className.substring(className.lastIndexOf('.') + 1) + "InstanceAdvisor"; 174 } 175 176 protected static String getAdvisorFQN(CtClass clazz) 177 { 178 return clazz.getName() + "$" + getAdvisorName(clazz); 179 } 180 181 protected static String getInstanceAdvisorFQN(CtClass clazz) 182 { 183 return clazz.getName() + "$" + getInstanceAdvisorName(clazz); 184 } 185 186 protected CtClass createAdvisorClass(CtClass clazz) throws NotFoundException, CannotCompileException 187 { 188 String innerClassName = getAdvisorName(clazz); 189 190 final boolean classStatic = true; 192 genadvisor = TransformerCommon.makeNestedClass(clazz, innerClassName, classStatic); 193 196 final CtClass superAdvisor = getSuperClassAdvisor(clazz.getSuperclass()); 198 if (superAdvisor == null) 199 { 200 genadvisor.setSuperclass(forName(GeneratedClassAdvisor.class.getName())); 201 } 202 else 203 { 204 genadvisor.setSuperclass(superAdvisor); 205 } 206 207 final CtClass untransformable = getClassPool().get("org.jboss.aop.instrument.Untransformable"); 209 genadvisor.addInterface(untransformable); 210 211 CtField version = new CtField(CtClass.intType, VERSION, genadvisor); 213 genadvisor.addField(version); 214 215 CtField domain = new CtField(forName("org.jboss.aop.Domain"), DOMAIN, genadvisor); 217 domain.setModifiers(Modifier.PROTECTED); 218 genadvisor.addField(domain); 219 CtMethod getter = CtNewMethod.getter("getDomain", domain); 220 genadvisor.addMethod(getter); 221 222 if (isBaseClass(clazz)) 223 { 224 CtMethod rebuildInterceptors = CtNewMethod.make( 225 Modifier.PROTECTED, 226 CtClass.voidType, 227 "rebuildInterceptors", 228 EMPTY_SIG, 229 EMPTY_EXCEPTIONS, 230 "{" + VERSION + "++;super.rebuildInterceptors();}", 231 genadvisor); 232 genadvisor.addMethod(rebuildInterceptors); 233 234 CtMethod internalRebuildInterceptors = CtNewMethod.make( 236 Modifier.PROTECTED, 237 CtClass.voidType, 238 "internalRebuildInterceptors", 239 EMPTY_SIG, 240 EMPTY_EXCEPTIONS, 241 "{super.rebuildInterceptors();}", 242 genadvisor); 243 genadvisor.addMethod(internalRebuildInterceptors); 244 } 245 246 CtMethod initialiseMethods = CtNewMethod.make( 247 Modifier.PROTECTED, 248 CtClass.voidType, 249 INITIALISE_METHODS, 250 EMPTY_SIG, 251 EMPTY_EXCEPTIONS, 252 (isBaseClass(clazz)) ? 253 null : "{super." + INITIALISE_METHODS + "();}", 254 genadvisor); 255 genadvisor.addMethod(initialiseMethods); 256 257 CtMethod initialiseConstructors = CtNewMethod.make( 258 Modifier.PROTECTED, 259 CtClass.voidType, 260 INITIALISE_CONSTRUCTORS, 261 EMPTY_SIG, 262 EMPTY_EXCEPTIONS, 263 null, 264 genadvisor); 265 genadvisor.addMethod(initialiseConstructors); 266 267 CtMethod initialiseConstructions = CtNewMethod.make( 268 Modifier.PROTECTED, 269 CtClass.voidType, 270 INITIALISE_CONSTRUCTIONS, 271 EMPTY_SIG, 272 EMPTY_EXCEPTIONS, 273 (isBaseClass(clazz)) ? 274 null : "{super." + INITIALISE_CONSTRUCTIONS + "();}", 275 genadvisor); 276 genadvisor.addMethod(initialiseConstructions); 277 278 CtMethod initialiseFieldReads = CtNewMethod.make( 279 Modifier.PROTECTED, 280 CtClass.voidType, 281 INITIALISE_FIELD_READS, 282 EMPTY_SIG, 283 EMPTY_EXCEPTIONS, 284 (isBaseClass(clazz)) ? 285 null : "{super." + INITIALISE_FIELD_READS + "();}", 286 genadvisor); 287 genadvisor.addMethod(initialiseFieldReads); 288 289 CtMethod initialiseFieldWrites = CtNewMethod.make( 290 Modifier.PROTECTED, 291 CtClass.voidType, 292 INITIALISE_FIELD_WRITES, 293 EMPTY_SIG, 294 EMPTY_EXCEPTIONS, 295 (isBaseClass(clazz)) ? 296 null : "{super." + INITIALISE_FIELD_WRITES + "();}", 297 genadvisor); 298 genadvisor.addMethod(initialiseFieldWrites); 299 300 CtMethod initialiseCallers = CtNewMethod.make( 301 Modifier.PROTECTED, 302 CtClass.voidType, 303 INITIALISE_CALLERS, 304 EMPTY_SIG, 305 EMPTY_EXCEPTIONS, 306 null, genadvisor); 308 genadvisor.addMethod(initialiseCallers); 309 310 createAdvisorCtors(clazz); 311 312 return genadvisor; 313 } 314 315 protected CtClass createInstanceAdvisorClass(CtClass clazz) throws NotFoundException, CannotCompileException 316 { 317 String innerClassName = getInstanceAdvisorName(clazz); 318 319 final boolean classStatic = true; 321 genInstanceAdvisor = TransformerCommon.makeNestedClass(clazz, innerClassName, classStatic); 322 genInstanceAdvisor.setModifiers(Modifier.setPublic(genInstanceAdvisor.getModifiers())); 324 325 genInstanceAdvisor.setSuperclass(getGenadvisor()); 327 328 final CtClass untransformable = getClassPool().get("org.jboss.aop.instrument.Untransformable"); 330 genInstanceAdvisor.addInterface(untransformable); 331 332 CtField classAdvisor = new CtField(genadvisor, "classAdvisor", genInstanceAdvisor); 334 genInstanceAdvisor.addField(classAdvisor); 335 336 CtMethod advicesUpdated = CtNewMethod.make( 337 Modifier.PROTECTED, 338 CtClass.voidType, 339 ADVICES_UPDATED, 340 EMPTY_SIG, 341 EMPTY_EXCEPTIONS, 342 null, 343 genInstanceAdvisor); 344 genInstanceAdvisor.addMethod(advicesUpdated); 345 346 implementInstanceAdvisorMethods(); 347 348 String cvBody = 349 "{" + 350 " if (classAdvisor." + VERSION + " != super." + VERSION + ") " + 351 " { " + 352 " super." + VERSION + " = classAdvisor." + VERSION +";" + 353 " internalRebuildInterceptors(); " + 354 " if (" + INSTANCE_ADVISOR_MIXIN + ".hasInterceptors())" + 355 " {" + 356 " " + ADVICES_UPDATED + "();" + 357 " }" + 358 " } " + 359 "}"; 360 CtMethod checkVersion = CtNewMethod.make( 361 Modifier.PROTECTED, 362 CtClass.voidType, 363 CHECK_VERSION, 364 EMPTY_SIG, 365 EMPTY_EXCEPTIONS, 366 cvBody, 367 genInstanceAdvisor); 368 genInstanceAdvisor.addMethod(checkVersion); 369 370 String body = 371 "{" + 372 " super($2);" + 373 " " + INSTANCE_ADVISOR_MIXIN + " = new org.jboss.aop.GeneratedInstanceAdvisorMixin($1, $2);" + 374 " this.classAdvisor = $2;" + 375 " super." + VERSION + " = classAdvisor." + VERSION + ";" + 376 "}"; 377 CtConstructor ctor = CtNewConstructor.make(new CtClass[]{forName("java.lang.Object"), genadvisor}, new CtClass[0], body, genInstanceAdvisor); 378 genInstanceAdvisor.addConstructor(ctor); 379 380 return genInstanceAdvisor; 381 } 382 383 protected void createAdvisorCtors(CtClass clazz)throws CannotCompileException, NotFoundException 384 { 385 String initBody = 386 "{" + 387 " " + DOMAIN + "= new org.jboss.aop.GeneratedAdvisorDomain($1, " + DECLARING_CLASS + ", false); " + 388 " ((org.jboss.aop.Domain)" + DOMAIN + ").setInheritsBindings(true); " + 389 " " + INITIALISE_METHODS + "();" + 390 " " + INITIALISE_CONSTRUCTORS + "();" + 391 " " + INITIALISE_CONSTRUCTIONS + "();" + 392 " " + INITIALISE_FIELD_READS + "();" + 393 " " + INITIALISE_FIELD_WRITES + "();" + 394 " super.initialise(" + DECLARING_CLASS + ", " + DOMAIN + ");" + 395 " " + INITIALISE_CALLERS + "();" + 396 "}"; 397 398 CtMethod initialise = CtNewMethod.make( 399 Modifier.PROTECTED, 400 CtClass.voidType, 401 "initialise", 402 new CtClass[]{forName("org.jboss.aop.AspectManager")}, 403 EMPTY_EXCEPTIONS, 404 initBody, 405 genadvisor); 406 genadvisor.addMethod(initialise); 407 408 409 CtConstructor ctor = CtNewConstructor.defaultConstructor(genadvisor); 411 ctor.setBody( 412 "{" + 413 " super(\"" + clazz.getName() + "\"); " + 414 " initialise(org.jboss.aop.AspectManager.instance(this.getClass().getClassLoader()));" + "}"); 416 genadvisor.addConstructor(ctor); 417 418 String instanceBody = 420 "{" + 421 " super(\"" + clazz.getName() + "\"); " + 422 " super.setParentAdvisor($1);" + 423 " initialise($1.getDomain());" + 424 "}"; 425 CtConstructor ctorWithParentAdvisor = CtNewConstructor.make(new CtClass[]{genadvisor}, EMPTY_EXCEPTIONS, instanceBody, genadvisor); 426 genadvisor.addConstructor(ctorWithParentAdvisor); 427 428 429 CtConstructor ctorForSubAdvisors = CtNewConstructor.make(new CtClass[]{forName("java.lang.String")}, new CtClass[0], "{super($1);}", genadvisor); 431 genadvisor.addConstructor(ctorForSubAdvisors); 432 ctorForSubAdvisors.setModifiers(Modifier.PROTECTED); 433 } 434 435 protected CtClass getSuperClassAdvisor(CtClass superclass)throws NotFoundException 436 { 437 if (superclass != null) 438 { 439 try 440 { 441 if (isAdvised(superclass)) 442 { 443 return forName(superclass.getClassPool(), getAdvisorFQN(superclass)); 444 } 445 } 446 catch (NotFoundException e) 447 { 448 } 449 450 return getSuperClassAdvisor(superclass.getSuperclass()); 451 } 452 return null; 453 454 } 455 456 protected void implementInstanceAdvisorMethods() throws NotFoundException, CannotCompileException 457 { 458 final CtClass instanceAdvisor = getClassPool().get("org.jboss.aop.InstanceAdvisor"); 459 genInstanceAdvisor.addInterface(instanceAdvisor); 460 461 CtField instanceAdvisorMixin = new CtField( 462 getClassPool().get("org.jboss.aop.GeneratedInstanceAdvisorMixin"), 463 INSTANCE_ADVISOR_MIXIN, 464 genInstanceAdvisor); 465 genInstanceAdvisor.addField(instanceAdvisorMixin); 466 467 CtMethod[] instanceAdvisorMethods = instanceAdvisor.getDeclaredMethods(); 468 for (int i = 0 ; i < instanceAdvisorMethods.length ; i++) 469 { 470 final String name = instanceAdvisorMethods[i].getName(); 471 if (name.equals("hasAspects")) 472 { 473 continue; 475 } 476 else if (name.equals("getDomain")) 477 { 478 continue; 480 } 481 482 String ret = (instanceAdvisorMethods[i].getReturnType().equals(CtClass.voidType)) ? "" : "return "; 483 StringBuffer delegatingBody = new StringBuffer (); 484 delegatingBody.append("{"); 485 if (name.startsWith("insertInterceptor") || name.startsWith("removeInterceptor") || name.startsWith("appendInterceptor")) 486 { 487 delegatingBody.append(ADVICES_UPDATED + "();"); 488 } 489 if (!instanceAdvisorMethods[i].getReturnType().equals(CtClass.voidType)) 490 { 491 delegatingBody.append("return "); 492 } 493 delegatingBody.append(INSTANCE_ADVISOR_MIXIN + "." + instanceAdvisorMethods[i].getName() + "($$);}"); 494 495 CtMethod m = CtNewMethod.make( 496 Modifier.PUBLIC, 497 instanceAdvisorMethods[i].getReturnType(), 498 instanceAdvisorMethods[i].getName(), 499 instanceAdvisorMethods[i].getParameterTypes(), 500 instanceAdvisorMethods[i].getExceptionTypes(), 501 delegatingBody.toString(), 502 genInstanceAdvisor); 503 genInstanceAdvisor.addMethod(m); 504 } 505 } 506 507 private void addCreateInstanceAdvisorToGenAdvisor(CtClass clazz) throws NotFoundException, CannotCompileException 508 { 509 CtMethod createInstanceAdvisor = CtNewMethod.make( 510 Modifier.PUBLIC, 511 forName("org.jboss.aop.Advisor"), 512 CREATE_INSTANCE_ADVISOR, 513 new CtClass[]{forName("java.lang.Object")}, 514 EMPTY_EXCEPTIONS, 515 "{return new " + getInstanceAdvisorFQN(clazz) + "($1, this);}", 516 genadvisor); 517 genadvisor.addMethod(createInstanceAdvisor); 518 } 519 520 protected void doSetupBasics(CtClass clazz) throws CannotCompileException, NotFoundException 521 { 522 createAdvisorClass(clazz); 523 createInstanceAdvisorClass(clazz); 524 addCreateInstanceAdvisorToGenAdvisor(clazz); 525 createAdvisorFieldsAndGetter(clazz); 526 } 527 528 private void createAdvisorFieldsAndGetter(CtClass clazz)throws NotFoundException, CannotCompileException 529 { 530 CtField classAdvisor = new CtField( 531 forName("org.jboss.aop.Advisor"), 532 Instrumentor.HELPER_FIELD_NAME, 533 clazz); 534 classAdvisor.setModifiers(Modifier.PRIVATE | Modifier.STATIC | Modifier.TRANSIENT); 535 clazz.addField(classAdvisor, CtField.Initializer.byExpr("new " + getAdvisorFQN(clazz) + "()")); 536 538 CtMethod getAdvisor = CtNewMethod.getter("_getAdvisor", classAdvisor); 539 getAdvisor.setModifiers(Modifier.PUBLIC); 540 clazz.addMethod(getAdvisor); 541 542 CtMethod getClassAdvisor = CtNewMethod.getter(GET_CLASS_ADVISOR, classAdvisor); 543 getClassAdvisor.setModifiers(Modifier.PUBLIC | Modifier.STATIC); 544 clazz.addMethod(getClassAdvisor); 545 546 if (isBaseClass(clazz)) 547 { 548 CtField currentAdvisor = new CtField( 549 forName("org.jboss.aop.Advisor"), 550 CURRENT_ADVISOR, 551 clazz); 552 currentAdvisor.setModifiers(Modifier.VOLATILE | Modifier.PROTECTED | Modifier.TRANSIENT); 553 clazz.addField(currentAdvisor, CtField.Initializer.byExpr("_getAdvisor()")); 554 555 String body = 556 "{" + 557 " if (" + CURRENT_ADVISOR + " == null)" + 558 " {" + 559 " " + CURRENT_ADVISOR + " = _getAdvisor();" + 560 " }" + 561 " return " + CURRENT_ADVISOR + ";"+ 562 "}"; 563 CtMethod getCurrentAdvisor = CtNewMethod.make( 564 Modifier.PROTECTED, 565 forName("org.jboss.aop.Advisor"), 566 GET_CURRENT_ADVISOR_NAME, 567 EMPTY_SIG, 568 EMPTY_EXCEPTIONS, 569 body, 570 clazz); 571 clazz.addMethod(getCurrentAdvisor); 572 573 CtField instanceAdvisor = new CtField( 574 forName("org.jboss.aop.InstanceAdvisor"), 575 INSTANCE_ADVISOR, 576 clazz); 577 instanceAdvisor.setModifiers(Modifier.PROTECTED | Modifier.TRANSIENT); 578 clazz.addField(instanceAdvisor); 579 } 580 581 String body = 583 "{ " + 584 " if (" + INSTANCE_ADVISOR + " == null) " + 585 " { " + 586 " synchronized(this) " + 587 " { " + 588 " if (" + INSTANCE_ADVISOR + " == null) " + 589 " { " + 590 " org.jboss.aop.Advisor advisor = ((" + getAdvisorFQN(clazz) + ")" + Instrumentor.HELPER_FIELD_NAME + ").createInstanceAdvisor(this); " + 591 " " + CURRENT_ADVISOR + " = advisor; " + 592 " " + INSTANCE_ADVISOR + " = (org.jboss.aop.InstanceAdvisor)advisor; " + 593 " } " + 594 " } " + 595 " } " + 596 " return " + INSTANCE_ADVISOR +";" + 597 "}"; 598 CtMethod getInstanceAdvisor = CtNewMethod.make( 599 forName("org.jboss.aop.InstanceAdvisor"), 600 "_getInstanceAdvisor", 601 new CtClass[0], 602 new CtClass[0], 603 body, 604 clazz); 605 clazz.addMethod(getInstanceAdvisor); 606 } 607 608 public static String updatedAdvicesName(String infoName) 609 { 610 return infoName + "_updated"; 611 } 612 613 614 616 private void addInstanceAdvisorWrappers(CtClass clazz)throws CannotCompileException, NotFoundException 617 { 618 CtClass superClass = clazz; 619 CtClass superAdvisor = genadvisor; 620 boolean isSuper = false; 621 622 StringBuffer advicesUpdatedCode = new StringBuffer (); 623 624 while (true) 625 { 626 CtField[] fields = superAdvisor.getDeclaredFields(); 627 628 for (int i = 0 ; i < fields.length ; i++) 629 { 630 if (Modifier.isStatic(fields[i].getModifiers())) continue; 631 632 GeneratedAdvisorNameExtractor names = GeneratedAdvisorNameExtractor.extractNames(superAdvisor, fields[i]); 633 if (names == null) continue; 634 635 String infoName = fields[i].getName(); 637 String updatedJoinpointAdvicesName = addAdvicesUpdatedForJoinpointField(infoName); 638 advicesUpdatedCode.append(updatedJoinpointAdvicesName + " = true;"); 639 addWrapperDelegatorMethodToInstanceAdvisor(names, updatedJoinpointAdvicesName); 640 } 641 642 if (isBaseClass(superClass)) 643 { 644 break; 645 } 646 647 isSuper = true; 648 superClass = superClass.getSuperclass(); 649 superAdvisor = superAdvisor.getSuperclass(); 650 } 651 652 CtMethod advicesUpdated = genInstanceAdvisor.getDeclaredMethod(ADVICES_UPDATED); 653 advicesUpdated.insertAfter(advicesUpdatedCode.toString()); 654 } 655 656 private String addAdvicesUpdatedForJoinpointField(String infoName) throws NotFoundException, CannotCompileException 657 { 658 String updatedAdvicesName = updatedAdvicesName(infoName); 659 try 660 { 661 genInstanceAdvisor.getDeclaredField(updatedAdvicesName); 662 } 663 catch(NotFoundException e) 664 { 665 CtField updatedAdvice = new CtField(CtClass.booleanType, updatedAdvicesName, genInstanceAdvisor); 667 updatedAdvice.setModifiers(Modifier.PROTECTED); 668 genInstanceAdvisor.addField(updatedAdvice); 669 } 670 671 return updatedAdvicesName; 672 } 673 674 private void addWrapperDelegatorMethodToInstanceAdvisor(GeneratedAdvisorNameExtractor names, String updatedAdvicesFieldName) throws NotFoundException, CannotCompileException 675 { 676 try 677 { 678 genInstanceAdvisor.getDeclaredMethod(names.getWrapper().getName()); 679 } 680 catch(NotFoundException e) 681 { 682 CtMethod instanceAdvisorMethod = CtNewMethod.delegator(names.getWrapper(), genInstanceAdvisor); 684 String code = 685 CHECK_VERSION + "();" + 686 "if (" + updatedAdvicesFieldName + ")" + 687 "{ " + 688 " " + JoinPointInfo.class.getName() + " copy = " + names.getInfoFieldName() + ".copy();" + 689 " copy.setInterceptors( " + INSTANCE_ADVISOR_MIXIN + ".getWrappers(copy.getInterceptors()) );" + 690 " " + updatedAdvicesFieldName + " = false;" + 691 " " + names.getJoinPointField().getName() + " = null;" + 692 " if (" + names.getGeneratorField().getName() + " == null)" + 693 " {" + 694 " " + names.getGeneratorField().getName() + " = super.getJoinPointGenerator(" + names.getInfoFieldName() + ");" + 695 " }" + 696 " " + names.getGeneratorField().getName() + ".rebindJoinpoint(copy);" + 697 "}"; 698 699 instanceAdvisorMethod.insertBefore(code); 700 genInstanceAdvisor.addMethod(instanceAdvisorMethod); 701 } 702 } 703 704 boolean initialisedMethods = false; 705 protected void initaliseMethodInfo(String infoName, long hash, long unadvisedHash)throws NotFoundException 706 { 707 String code = 708 infoName + " = new " + MethodExecutionTransformer.METHOD_INFO_CLASS_NAME + "(" + 709 "java.lang.Class.forName(\"" + clazz.getName() + "\")," + 710 hash + "L, " + 711 unadvisedHash + "L, this);" + 712 GeneratedClassAdvisor.ADD_METHOD_INFO + "(" + infoName + ");"; 713 714 addCodeToInitialiseMethod(code, INITIALISE_METHODS); 715 } 716 717 protected void initialiseFieldReadInfoField(String infoName, int index, String fieldName, long wrapperHash) throws NotFoundException 718 { 719 String code = 720 infoName + " = new " + FieldAccessTransformer.FIELD_INFO_CLASS_NAME + "(" + 721 "java.lang.Class.forName(\"" + clazz.getName() + "\")," + 722 index + ", " + 723 "\"" + fieldName + "\", " + 724 wrapperHash + "L, this, true);" + 725 GeneratedClassAdvisor.ADD_FIELD_READ_INFO + "(" + infoName + ");"; 726 727 addCodeToInitialiseMethod(code, INITIALISE_FIELD_READS); 728 } 729 730 protected void initialiseFieldWriteInfoField(String infoName, int index, String fieldName, long wrapperHash) throws NotFoundException 731 { 732 String code = 733 infoName + " = new " + FieldAccessTransformer.FIELD_INFO_CLASS_NAME + "(" + 734 "java.lang.Class.forName(\"" + clazz.getName() + "\")," + 735 index + ", " + 736 "\"" + fieldName + "\", " + 737 wrapperHash + "L, this, false);" + 738 GeneratedClassAdvisor.ADD_FIELD_WRITE_INFO + "(" + infoName + ");"; 739 740 addCodeToInitialiseMethod(code, INITIALISE_FIELD_WRITES); 741 } 742 743 protected void initialiseConstructorInfoField(String infoName, int index, long constructorHash, long wrapperHash) throws NotFoundException 744 { 745 String code = 746 infoName + " = new " + ConstructorExecutionTransformer.CONSTRUCTOR_INFO_CLASS_NAME + "(" + 747 "java.lang.Class.forName(\"" + clazz.getName() + "\")," + 748 index + ", " + 749 wrapperHash + "L, " + 750 constructorHash + "L, this);" + 751 GeneratedClassAdvisor.ADD_CONSTRUCTOR_INFO + "(" + infoName + ");"; 752 753 addCodeToInitialiseMethod(code, INITIALISE_CONSTRUCTORS); 754 } 755 756 protected void initialiseConstructionInfoField(String infoName, int index, long constructorHash) throws NotFoundException 757 { 758 String code = 759 infoName + " = new " + ConstructionTransformer.CONSTRUCTION_INFO_CLASS_NAME + "(" + 760 "java.lang.Class.forName(\"" + clazz.getName() + "\")," + 761 index + ", " + 762 constructorHash + "L, this);" + 763 GeneratedClassAdvisor.ADD_CONSTRUCTION_INFO + "(" + infoName + ");"; 764 765 addCodeToInitialiseMethod(code, INITIALISE_CONSTRUCTIONS); 766 767 } 768 769 protected void initialiseCallerInfoField(String infoName, String init)throws CannotCompileException, NotFoundException 770 { 771 addCodeToInitialiseMethod(infoName + " = " + init + ";", INITIALISE_CALLERS); 772 } 773 774 775 private void addCodeToInitialiseMethod(String code, String methodName) throws NotFoundException 776 { 777 CtMethod method = genadvisor.getDeclaredMethod(methodName); 778 try 779 { 780 method.insertAfter(code); 781 } 782 catch (CannotCompileException e) 783 { 784 e.printStackTrace(); 785 throw new RuntimeException ("code was: " + code + " for method " + method.getName()); 786 } 787 } 788 789 protected void addJoinPointGeneratorFieldToGenAdvisor(String name) throws CannotCompileException, NotFoundException 790 { 791 CtField field = new CtField(forName(JoinPointGenerator.class.getName()), name, genadvisor); 792 genadvisor.addField(field); 793 } 794 795 private static class GeneratedAdvisorNameExtractor 796 { 797 String infoName; 799 CtMethod wrapper; 800 CtField joinPointField; 801 CtField generatorField; 802 803 private GeneratedAdvisorNameExtractor(String infoName, CtMethod wrapper, CtField joinPointField, CtField generatorField) 804 { 805 this.infoName = infoName; 806 this.wrapper = wrapper; 807 this.joinPointField = joinPointField; 808 this.generatorField = generatorField; 809 } 810 811 private static GeneratedAdvisorNameExtractor extractNames(CtClass genadvisor, CtField infoField) throws NotFoundException 812 { 813 String infoName = infoField.getName(); 814 815 if (infoField.getType().getName().equals(FieldInfo.class.getName())) 816 { 817 boolean isWrite = infoName.startsWith("aop$FieldInfo_w_"); 818 if (!isWrite && !infoName.startsWith("aop$FieldInfo_r_")) 819 { 820 throw new RuntimeException ("Bad FieldInfo name: '" + infoName + "'"); 821 } 822 String fieldName = infoName.substring("aop$FieldInfo_w_".length()); 823 824 String wrapperName = (isWrite) ? 825 GeneratedAdvisorFieldAccessTransformer.advisorFieldWrite(genadvisor, fieldName) : 826 GeneratedAdvisorFieldAccessTransformer.advisorFieldRead(genadvisor, fieldName); 827 828 CtMethod wrapper = genadvisor.getDeclaredMethod(wrapperName); 829 830 String joinPointName = (isWrite) ? 831 FieldJoinPointGenerator.WRITE_JOINPOINT_FIELD_PREFIX + fieldName : 832 FieldJoinPointGenerator.READ_JOINPOINT_FIELD_PREFIX + fieldName; 833 CtField joinPointField = genadvisor.getDeclaredField(joinPointName); 834 835 String generatorName = 836 (isWrite) ? 837 FieldJoinPointGenerator.WRITE_GENERATOR_PREFIX + fieldName : 838 FieldJoinPointGenerator.READ_GENERATOR_PREFIX + fieldName; 839 CtField generatorField = genadvisor.getDeclaredField(generatorName); 840 841 return new GeneratedAdvisorNameExtractor(infoName, wrapper, joinPointField, generatorField); 842 } 843 else if (infoField.getType().getName().equals(MethodInfo.class.getName())) 844 { 845 if (!infoName.startsWith("aop$MethodInfo_")) 846 { 847 throw new RuntimeException ("Bad MethodInfo name: '" + infoName + "'"); 848 } 849 String methodNameHash = infoName.substring("aop$MethodInfo_".length()); 850 CtMethod wrapper = genadvisor.getDeclaredMethod(methodNameHash); 851 852 String joinPointName = JoinPointGenerator.JOINPOINT_FIELD_PREFIX + methodNameHash; 853 CtField joinPointField = genadvisor.getDeclaredField(joinPointName); 854 855 String generatorName = JoinPointGenerator.GENERATOR_PREFIX + methodNameHash; 856 CtField generatorField = genadvisor.getDeclaredField(generatorName); 857 858 return new GeneratedAdvisorNameExtractor(infoName, wrapper, joinPointField, generatorField); 859 } 860 else if (infoField.getType().getName().equals(ConByMethodInfo.class.getName())) 861 { 862 if (!infoName.startsWith("aop$constructorCall_")) 863 { 864 throw new RuntimeException ("Bad ConByMethodInfo name: '" + infoName + "'"); 865 } 866 867 CtMethod wrapper = genadvisor.getDeclaredMethod(infoName); 868 869 String joinPointName = ConByMethodJoinPointGenerator.JOINPOINT_FIELD_PREFIX + infoName.substring("aop$constructorCall_".length()); 870 CtField joinPointField = genadvisor.getDeclaredField(joinPointName); 871 872 String generatorName = ConByMethodJoinPointGenerator.GENERATOR_PREFIX + infoName.substring("aop$constructorCall_".length()); 873 CtField generatorField = genadvisor.getDeclaredField(generatorName); 874 875 return new GeneratedAdvisorNameExtractor(infoName, wrapper, joinPointField, generatorField); 876 } 877 else if (infoField.getType().getName().equals(MethodByMethodInfo.class.getName())) 878 { 879 if (!infoName.startsWith("aop$methodCall_")) 880 { 881 throw new RuntimeException ("Bad MethodByMethodInfo name: '" + infoName + "'"); 882 } 883 884 CtMethod wrapper = genadvisor.getDeclaredMethod(infoName); 885 886 String joinPointName = MethodByMethodJoinPointGenerator.JOINPOINT_FIELD_PREFIX + infoName.substring("aop$methodCall_".length()); 887 CtField joinPointField = genadvisor.getDeclaredField(joinPointName); 888 889 String generatorName = MethodByMethodJoinPointGenerator.GENERATOR_PREFIX + infoName.substring("aop$methodCall_".length()); 890 CtField generatorField = genadvisor.getDeclaredField(generatorName); 891 892 return new GeneratedAdvisorNameExtractor(infoName, wrapper, joinPointField, generatorField); 893 } 894 895 return null; 896 } 897 898 public CtField getJoinPointField() 899 { 900 return joinPointField; 901 } 902 903 public CtField getGeneratorField() 904 { 905 return generatorField; 906 } 907 908 public CtMethod getWrapper() 909 { 910 return wrapper; 911 } 912 913 public String getInfoFieldName() 914 { 915 return infoName; 916 } 917 } 918 } 919 | Popular Tags |