1 22 package org.jboss.aop; 23 24 import gnu.trove.TLongObjectHashMap; 25 26 import java.lang.ref.WeakReference ; 27 import java.lang.reflect.Constructor ; 28 import java.lang.reflect.Field ; 29 import java.lang.reflect.Method ; 30 import java.security.AccessController ; 31 import java.security.PrivilegedActionException ; 32 import java.security.PrivilegedExceptionAction ; 33 import java.util.ArrayList ; 34 import java.util.HashMap ; 35 import java.util.HashSet ; 36 import java.util.List ; 37 import java.util.Map ; 38 import java.util.Set ; 39 40 import javassist.CtClass; 41 import javassist.CtConstructor; 42 import javassist.CtField; 43 import javassist.CtMethod; 44 45 import org.jboss.aop.ClassAdvisor.RebuildInterceptorsAction; 46 import org.jboss.aop.advice.AdviceBinding; 47 import org.jboss.aop.advice.AspectDefinition; 48 import org.jboss.aop.advice.CFlowInterceptor; 49 import org.jboss.aop.advice.GeneratedOnly; 50 import org.jboss.aop.advice.Interceptor; 51 import org.jboss.aop.advice.InterceptorFactory; 52 import org.jboss.aop.advice.PrecedenceSorter; 53 import org.jboss.aop.annotation.AnnotationElement; 54 import org.jboss.aop.annotation.AnnotationRepository; 55 import org.jboss.aop.instrument.ConstructionTransformer; 56 import org.jboss.aop.instrument.ConstructorExecutionTransformer; 57 import org.jboss.aop.instrument.FieldAccessTransformer; 58 import org.jboss.aop.introduction.AnnotationIntroduction; 59 import org.jboss.aop.introduction.InterfaceIntroduction; 60 import org.jboss.aop.joinpoint.ConstructorJoinpoint; 61 import org.jboss.aop.joinpoint.Invocation; 62 import org.jboss.aop.joinpoint.InvocationResponse; 63 import org.jboss.aop.joinpoint.Joinpoint; 64 import org.jboss.aop.joinpoint.MethodInvocation; 65 import org.jboss.aop.joinpoint.MethodJoinpoint; 66 import org.jboss.aop.metadata.ClassMetaDataBinding; 67 import org.jboss.aop.metadata.ConstructorMetaData; 68 import org.jboss.aop.metadata.FieldMetaData; 69 import org.jboss.aop.metadata.MethodMetaData; 70 import org.jboss.aop.metadata.SimpleMetaData; 71 import org.jboss.aop.pointcut.PointcutMethodMatch; 72 import org.jboss.repository.spi.MetaDataContext; 73 import org.jboss.util.NestedRuntimeException; 74 75 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; 76 import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArraySet; 77 78 82 public abstract class Advisor 83 { 84 public MethodInfo getMethodInfo(long hash) 85 { 86 return (MethodInfo)methodInterceptors.get(hash); 87 } 88 89 private class AdviceInterceptorKey 90 { 91 private String adviceName; 92 private Joinpoint joinpoint; 93 private int hash; 94 95 public AdviceInterceptorKey(String adviceName, Joinpoint joinpoint) 96 { 97 this.adviceName = adviceName; 98 this.joinpoint = joinpoint; 99 hash = adviceName.hashCode(); 100 hash = 29 * hash + (joinpoint != null ? joinpoint.hashCode() : 0); 101 } 102 103 public boolean equals(Object o) 104 { 105 if (this == o) return true; 106 if (!(o instanceof AdviceInterceptorKey)) return false; 107 108 final AdviceInterceptorKey adviceInterceptorKey = (AdviceInterceptorKey) o; 109 110 if (!adviceName.equals(adviceInterceptorKey.adviceName)) return false; 111 if (joinpoint != null ? !joinpoint.equals(adviceInterceptorKey.joinpoint) : adviceInterceptorKey.joinpoint != null) return false; 112 113 return true; 114 } 115 116 public int hashCode() 117 { 118 return hash; 119 } 120 } 121 122 123 protected HashSet adviceBindings = new HashSet (); 124 protected ArrayList interfaceIntroductions = new ArrayList (); 125 protected ArrayList classMetaDataBindings = new ArrayList (); 126 protected SimpleMetaData defaultMetaData = new SimpleMetaData(); 127 protected MethodMetaData methodMetaData = new MethodMetaData(); 128 protected FieldMetaData fieldMetaData = new FieldMetaData(); 129 protected SimpleMetaData classMetaData = new SimpleMetaData(); 130 protected ConstructorMetaData constructorMetaData = new ConstructorMetaData(); 131 protected HashMap classAnnotations = new HashMap(); 132 protected AnnotationRepository annotations = new AnnotationRepository(); 133 protected boolean doesHaveAspects = false; 134 135 protected String name; 136 protected ConcurrentReaderHashMap aspects = new ConcurrentReaderHashMap(); 137 protected HashMap adviceInterceptors = new HashMap(); 138 protected CopyOnWriteArraySet perInstanceAspectDefinitions = new CopyOnWriteArraySet(); 139 protected ConcurrentReaderHashMap perInstanceJoinpointAspectDefinitions = new ConcurrentReaderHashMap(); 140 141 static Class cl = java.lang.String .class; 142 protected TLongObjectHashMap advisedMethods = new TLongObjectHashMap(); 143 protected TLongObjectHashMap methodInterceptors = new TLongObjectHashMap(); 146 protected AspectManager manager; 147 protected Class clazz = null; 148 protected Constructor [] constructors; 149 150 151 protected Interceptor[][] constructorInterceptors; 152 protected ConstructorInfo[] constructorInfos; 154 155 protected Interceptor[][] constructionInterceptors; 156 protected ConstructionInfo[] constructionInfos; 157 158 159 MetaDataContext metadataContext; 161 162 public Advisor(String name, AspectManager manager) 163 { 164 this.name = name; 165 this.manager = manager; 166 } 167 168 public Constructor [] getConstructors() 169 { 170 return constructors; 171 } 172 173 174 public Interceptor[][] getConstructorInterceptors() 175 { 176 return constructorInterceptors; 177 } 178 179 public ConstructorInfo[] getConstructorInfos() 180 { 181 return constructorInfos; 182 } 183 184 185 public Interceptor[][] getConstructionInterceptors() 186 { 187 return constructionInterceptors; 188 } 189 190 public ConstructionInfo[] getConstructionInfos() 191 { 192 return constructionInfos; 193 } 194 195 200 public Method [] getAllMethods() 201 { 202 return null; 203 } 204 205 public AspectManager getManager() 206 { 207 return manager; 208 } 209 210 214 protected void setManager(AspectManager manager) 215 { 216 this.manager = manager; 217 } 218 219 220 public List getClassMetadataBindings() 221 { 222 return classMetaDataBindings; 223 } 224 225 public SimpleMetaData getClassMetaData() 226 { 227 return classMetaData; 228 } 229 230 public SimpleMetaData getDefaultMetaData() 231 { 232 return defaultMetaData; 233 } 234 235 public MethodMetaData getMethodMetaData() 236 { 237 return methodMetaData; 238 } 239 240 public FieldMetaData getFieldMetaData() 241 { 242 return fieldMetaData; 243 } 244 245 public ConstructorMetaData getConstructorMetaData() 246 { 247 return constructorMetaData; 248 } 249 250 253 public void deployAnnotationOverrides() 254 { 255 List annotationOverrides = getManager().getAnnotationOverrides(); 256 if (annotationOverrides != null) 257 { 258 for (int i = 0; i < annotationOverrides.size(); ++i) 259 { 260 AnnotationIntroduction introduction = (AnnotationIntroduction) annotationOverrides.get(i); 261 deployAnnotationOverride(introduction); 262 } 263 } 264 } 265 266 public void deployAnnotationOverride(AnnotationIntroduction introduction) 267 { 268 if (System.getSecurityManager() == null) 269 { 270 DeployAnnotationOverrideAction.NON_PRIVILEGED.deploy(this, introduction); 271 } 272 else 273 { 274 DeployAnnotationOverrideAction.PRIVILEGED.deploy(this, introduction); 275 } 276 } 277 278 public void doDeployAnnotationOverride(AnnotationIntroduction introduction) 279 { 280 if (introduction.matches(this, clazz)) 281 { 282 annotations.addClassAnnotation(introduction.getAnnotation().getIdentifier(), introduction.getOriginalAnnotationExpr()); 283 } 284 285 Class theClass = clazz; 286 287 deployMethodAnnotationOverrides(theClass, introduction); 288 Field [] fields = theClass.getDeclaredFields(); 289 for (int i = 0; i < fields.length; i++) 290 { 291 if (introduction.matches(this, fields[i])) 292 { 293 annotations.addAnnotation(fields[i], introduction.getAnnotation().getIdentifier(), introduction.getOriginalAnnotationExpr()); 294 } 295 } 296 Constructor [] cons = theClass.getDeclaredConstructors(); 297 for (int i = 0; i < cons.length; i++) 298 { 299 if (introduction.matches(this, cons[i])) 300 { 301 annotations.addAnnotation(cons[i], introduction.getAnnotation().getIdentifier(), introduction.getOriginalAnnotationExpr()); 302 } 303 } 304 } 305 306 protected void initializeInterfaceIntroductions(Class theClass) 307 { 308 manager.applyInterfaceIntroductions(this, theClass); 309 } 310 311 protected void deployMethodAnnotationOverrides(Class theClass, AnnotationIntroduction introduction) 312 { 313 if (theClass.getSuperclass() != null) 314 { 315 deployMethodAnnotationOverrides(theClass.getSuperclass(), introduction); 316 } 317 Method [] methods = theClass.getDeclaredMethods(); 318 for (int i = 0; i < methods.length; i++) 319 { 320 if (introduction.matches(this, methods[i])) 321 { 322 annotations.addAnnotation(methods[i], introduction.getAnnotation().getIdentifier(), introduction.getOriginalAnnotationExpr()); 323 } 324 } 325 } 326 327 328 public AnnotationRepository getAnnotations() 329 { 330 return annotations; 331 } 332 333 public Object resolveAnnotation(Class annotation) 334 { 335 if (metadataContext != null) 336 { 337 Object value = metadataContext.getAnnotation(annotation); 338 if (value != null) return value; 339 } 340 341 if (annotations.isDisabled(annotation)) 342 return null; 343 344 Object value = annotations.resolveClassAnnotation(annotation); 345 if (clazz == null) return null; 346 if (value == null) value = AnnotationElement.getVisibleAnnotation(clazz, annotation); 347 return value; 348 } 349 350 public boolean hasAnnotation(String annotation) 351 { 352 return hasAnnotation(clazz, annotation); 353 } 354 355 public boolean hasAnnotation(Class tgt, String annotation) 356 { 357 if (metadataContext != null) 358 { 359 if (metadataContext.hasAnnotation(annotation)) return true; 360 } 361 if (annotations.hasClassAnnotation(annotation)) return true; 362 if (tgt == null) return false; 363 try 364 { 365 return AnnotationElement.isAnyAnnotationPresent(tgt, annotation); 366 } 367 catch (Exception e) 368 { 369 throw new RuntimeException (e); } 371 } 372 373 public Object resolveAnnotation(Method m, Class annotation) 374 { 375 if (metadataContext != null) 376 { 377 Object val = metadataContext.getAnnotation(m, annotation); 378 if (val != null) return val; 379 } 380 381 if (annotations.isDisabled(m,annotation)) 382 return null; 383 384 Object value = annotations.resolveAnnotation(m, annotation); 385 if (value == null) value = AnnotationElement.getVisibleAnnotation(m, annotation); 386 return value; 387 } 388 389 public Object resolveAnnotation(Method m, Class [] annotationChoices) 390 { 391 Object value = null; 392 int i = 0; 393 while (value == null && i < annotationChoices.length){ 394 value = annotations.resolveAnnotation(m, annotationChoices[i++]); 395 } 396 397 i = 0; 398 while (value == null && i < annotationChoices.length){ 399 value = AnnotationElement.getVisibleAnnotation(m, annotationChoices[i++]); 400 } 401 return value; 402 } 403 404 public Object resolveAnnotation(Field f, Class annotation) 405 { 406 Object value = annotations.resolveAnnotation(f, annotation); 407 if (value == null) value = AnnotationElement.getVisibleAnnotation(f, annotation); 408 return value; 409 } 410 411 public Object resolveAnnotation(Constructor c, Class annotation) 412 { 413 Object value = annotations.resolveAnnotation(c, annotation); 414 if (value == null) value = AnnotationElement.getVisibleAnnotation(c, annotation); 415 return value; 416 } 417 418 public boolean hasAnnotation(Method m, String annotation) 419 { 420 if (metadataContext != null) 421 { 422 if (metadataContext.hasAnnotation(m, annotation)) return true; 423 } 424 425 if (annotations.hasAnnotation(m, annotation)) return true; 426 try 427 { 428 return AnnotationElement.isAnyAnnotationPresent(m, annotation); 429 } 430 catch (Exception e) 431 { 432 throw new RuntimeException (e); } 434 } 435 436 public boolean hasAnnotation(Field m, String annotation) 437 { 438 if (annotations.hasAnnotation(m, annotation)) return true; 439 try 440 { 441 return AnnotationElement.isAnyAnnotationPresent(m, annotation); 442 } 443 catch (Exception e) 444 { 445 throw new RuntimeException (e); } 447 } 448 449 public boolean hasAnnotation(Constructor m, String annotation) 450 { 451 if (annotations.hasAnnotation(m, annotation)) return true; 452 try 453 { 454 return AnnotationElement.isAnyAnnotationPresent(m, annotation); 455 } 456 catch (Exception e) 457 { 458 throw new RuntimeException (e); } 460 } 461 462 public boolean hasAnnotation(CtClass clazz, String annotation) 463 { 464 if (annotations.hasClassAnnotation(annotation)) return true; 465 try 466 { 467 return AnnotationElement.isAnyAnnotationPresent(clazz, annotation); 468 } 469 catch (Exception e) 470 { 471 throw new RuntimeException (e); } 473 } 474 475 public boolean hasAnnotation(CtMethod member, String annotation) 476 { 477 if (annotations.hasAnnotation(member, annotation)) return true; 479 return AnnotationElement.isAnyAnnotationPresent(member, annotation); 480 } 481 482 public boolean hasAnnotation(CtField member, String annotation) 483 { 484 if (annotations.hasAnnotation(member, annotation)) return true; 486 return AnnotationElement.isAnyAnnotationPresent(member, annotation); 487 } 488 489 public boolean hasAnnotation(CtConstructor member, String annotation) 490 { 491 if (annotations.hasAnnotation(member, annotation)) return true; 493 return AnnotationElement.isAnyAnnotationPresent(member, annotation); 494 } 495 496 public MetaDataContext getMetadataContext() 497 { 498 return metadataContext; 499 } 500 501 public void setMetadataContext( Object metadataContext) 502 { 503 this.metadataContext = (MetaDataContext)metadataContext; 504 } 505 506 public String getName() 507 { 508 return name; 509 } 510 511 public final boolean hasAspects() 512 { 513 return doesHaveAspects; 514 } 515 516 public synchronized void removeAdviceBinding(AdviceBinding binding) 517 { 518 adviceBindings.remove(binding); 519 rebuildInterceptors(); 520 doesHaveAspects = adviceBindings.size() > 0; 521 } 522 523 public synchronized void removeAdviceBindings(ArrayList bindings) 524 { 525 adviceBindings.removeAll(bindings); 526 rebuildInterceptors(); 527 doesHaveAspects = adviceBindings.size() > 0; 528 } 529 530 533 public synchronized void newBindingAdded() 534 { 535 rebuildInterceptors(); 536 doesHaveAspects = adviceBindings.size() > 0; 537 } 538 539 public ArrayList getInterfaceIntroductions() 540 { 541 return interfaceIntroductions; 542 } 543 544 public synchronized void addInterfaceIntroduction(InterfaceIntroduction pointcut) 545 { 546 interfaceIntroductions.add(pointcut); 547 } 548 549 public synchronized void removeInterfaceIntroduction(InterfaceIntroduction pointcut) 550 { 551 interfaceIntroductions.remove(pointcut); 552 } 553 554 protected abstract void rebuildInterceptors(); 555 556 560 public abstract void addClassMetaData(ClassMetaDataBinding data); 561 562 public abstract void removeClassMetaData(ClassMetaDataBinding data); 563 564 566 public void addPerInstanceAspect(AspectDefinition def) 567 { 568 perInstanceAspectDefinitions.add(def); 569 } 570 571 public void removePerInstanceAspect(AspectDefinition def) 572 { 573 perInstanceAspectDefinitions.remove(def); 574 } 575 576 public Set getPerInstanceAspectDefinitions() 577 { 578 return perInstanceAspectDefinitions; 579 } 580 581 583 public void addPerInstanceJoinpointAspect(Joinpoint joinpoint, AspectDefinition def) 584 { 585 Set joinpoints = (Set ) perInstanceJoinpointAspectDefinitions.get(def); 586 if (joinpoints == null) 587 { 588 joinpoints = new CopyOnWriteArraySet(); 589 perInstanceJoinpointAspectDefinitions.put(def, joinpoints); 590 } 591 joinpoints.add(joinpoint); 592 } 593 594 public void removePerInstanceJoinpointAspect(AspectDefinition def) 595 { 596 perInstanceJoinpointAspectDefinitions.remove(def); 597 } 598 599 public Map getPerInstanceJoinpointAspectDefinitions() 600 { 601 return perInstanceJoinpointAspectDefinitions; 602 } 603 604 public Object getPerClassAspect(AspectDefinition def) 605 { 606 return aspects.get(def.getName()); 607 } 608 609 public Object getPerClassAspect(String def) 610 { 611 return aspects.get(def); 612 } 613 614 public void addPerClassAspect(AspectDefinition def) 615 { 616 if (aspects.containsKey(def.getName())) return; 617 Object aspect = def.getFactory().createPerClass(this); 618 aspects.put(def.getName(), aspect); 619 } 620 621 public void removePerClassAspect(AspectDefinition def) 622 { 623 aspects.remove(def.getName()); 624 adviceInterceptors.remove(def); 625 } 626 627 public Interceptor getAdviceInterceptor(AspectDefinition def, String adviceName, Joinpoint joinpoint) 628 { 629 AdviceInterceptorKey key = new AdviceInterceptorKey(adviceName, joinpoint); 630 synchronized (adviceInterceptors) 631 { 632 Map map = null; 633 map = (Map) adviceInterceptors.get(def); 634 if (map != null) 635 { 636 return (Interceptor) map.get(key); 637 } 638 } 639 return null; 640 } 641 642 public void addAdviceInterceptor(AspectDefinition def, String adviceName, Interceptor interceptor, Joinpoint joinpoint) 643 { 644 synchronized (adviceInterceptors) 645 { 646 Map map = (Map) adviceInterceptors.get(def); 647 if (map == null) 648 { 649 map = new HashMap(); 650 adviceInterceptors.put(def, map); 651 } 652 map.put(adviceName, interceptor); 653 } 654 } 655 656 657 protected void createInterceptorChain(InterceptorFactory[] factories, ArrayList newinterceptors, Joinpoint joinpoint) 658 { 659 for (int i = 0; i < factories.length; i++) 660 { 661 if (factories[i] instanceof GeneratedOnly) 662 { 663 throw new RuntimeException ("Before/After/Throwing is only supported for Generated Advisors"); 664 } 665 if (factories[i].isDeployed()) newinterceptors.add(factories[i].create(this, joinpoint)); 666 } 667 } 668 669 protected void resolveMethodPointcut(MethodInterceptors newMethodInterceptors, AdviceBinding binding) 670 { 671 long[] keys = advisedMethods.keys(); 672 for (int i = 0; i < keys.length; i++) 673 { 674 Method method = (Method ) advisedMethods.get(keys[i]); 675 PointcutMethodMatch match = binding.getPointcut().matchesExecution(this, method); 676 677 if (match != null && match.isMatch()) 678 { 679 adviceBindings.add(binding); 680 if (AspectManager.verbose) 681 { 682 693 System.err.println("method matched binding " + binding.getPointcut().getExpr() + " " + method.toString()); 694 695 } 696 binding.addAdvisor(this); 697 MethodMatchInfo info = newMethodInterceptors.getMatchInfo(keys[i]); 698 info.addMatchedBinding(binding, match); 699 } 700 } 701 } 702 703 protected void finalizeMethodChain(MethodInterceptors newMethodInterceptors) 704 { 705 TLongObjectHashMap newMethodInfos = new TLongObjectHashMap(); 706 707 long[] keys = newMethodInterceptors.keys(); 708 for (int i = 0; i < keys.length; i++) 709 { 710 MethodMatchInfo matchInfo = newMethodInterceptors.getMatchInfo(keys[i]); 711 matchInfo.populateBindings(); 712 713 MethodInfo info = matchInfo.getInfo(); 714 newMethodInfos.put(keys[i], info); 715 716 ArrayList list = info.getInterceptorChain(); 717 Interceptor[] interceptors = null; 718 if (list.size() > 0) 719 { 720 interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()])); 721 } 722 info.setInterceptors(interceptors); 723 } 724 methodInterceptors = newMethodInfos; 725 } 726 727 public InvocationResponse dynamicInvoke(Object target, Invocation invocation) 728 throws Throwable 729 { 730 if (invocation instanceof MethodInvocation) 732 { 733 Interceptor[] aspects = null; 734 MethodInvocation methodInvocation = (MethodInvocation) invocation; 735 long hash = methodInvocation.getMethodHash(); 736 MethodInfo info = (MethodInfo) methodInterceptors.get(hash); 737 aspects = info.getInterceptors(); 738 if (aspects == null) aspects = new Interceptor[0]; 739 if (target != null && target instanceof Advised) 740 { 741 InstanceAdvised advised = (InstanceAdvised) target; 742 aspects = advised._getInstanceAdvisor().getInterceptors(aspects); 743 } 744 MethodInvocation nextInvocation = new MethodInvocation(info, aspects); 745 nextInvocation.setMetaData(invocation.getMetaData()); 746 nextInvocation.setTargetObject(target); 747 nextInvocation.setArguments(methodInvocation.getArguments()); 748 nextInvocation.setAdvisor(this); 749 InvocationResponse response = new InvocationResponse(nextInvocation.invokeNext()); 750 response.setContextInfo(nextInvocation.getResponseContextInfo()); 751 return response; 752 } 753 throw new RuntimeException ("dynamic field invocations not supported yet!"); 754 } 755 756 public Class getClazz() 757 { 758 return clazz; 759 } 760 761 void setClazz(Class clazz) 762 { 763 this.clazz = clazz; 764 } 765 766 public static String getSimpleName(Class clazz) 767 { 768 String name = clazz.getName(); 769 int lastIndex = name.lastIndexOf('.'); 770 if (lastIndex < 0) 771 { 772 return name; 773 } 774 775 return name.substring(lastIndex + 1); 776 } 777 778 protected ArrayList initializeConstructorChain() 779 { 780 if (clazz != null && constructors == null) 781 { 782 constructors = clazz.getDeclaredConstructors(); 783 } 784 785 ArrayList newInfos = new ArrayList (constructors.length); 786 for (int i = 0; i < constructors.length; i++) 787 { 788 final ConstructorInfo info = new ConstructorInfo(); 789 info.setConstructor(constructors[i]); 790 info.setIndex(i); 791 try 792 { 793 final String name = ConstructorExecutionTransformer.constructorFactory(getSimpleName(clazz)); 794 final Class [] types = constructors[i].getParameterTypes(); 795 Method method = (Method ) AccessController.doPrivileged(new PrivilegedExceptionAction () 796 { 797 public Object run() throws Exception 798 { 799 return clazz.getDeclaredMethod(name, types); 800 } 801 }); 802 info.setWrapper(method); 803 } 804 catch (PrivilegedActionException e1) 805 { 806 Exception e = e1.getException(); 807 if (e instanceof NoSuchMethodException == false) 808 throw new NestedRuntimeException(e); 809 } 810 811 info.setAdvisor(this); 812 newInfos.add(info); 813 814 try 815 { 816 final String name = ConstructorExecutionTransformer.getConstructorInfoFieldName(getSimpleName(clazz), i); 817 AccessController.doPrivileged(new PrivilegedExceptionAction () 818 { 819 public Object run() throws Exception 820 { 821 Field infoField = clazz.getDeclaredField(name); 822 infoField.setAccessible(true); 823 infoField.set(null, new WeakReference (info)); 824 return null; 825 } 826 }); 827 } 828 catch (PrivilegedActionException e1) 829 { 830 Exception e = e1.getException(); 831 if (e instanceof NoSuchFieldException == false) 832 throw new NestedRuntimeException(e); 833 } 834 } 835 836 return newInfos; 837 } 838 839 protected ArrayList initializeConstructionChain() 840 { 841 ArrayList newInfos = new ArrayList (constructors.length); 842 for (int i = 0; i < constructors.length; i++) 843 { 844 ConstructionInfo info = new ConstructionInfo(); 845 info.setConstructor(constructors[i]); 846 info.setIndex(i); 847 info.setAdvisor(this); 848 newInfos.add(info); 849 850 try 851 { 852 Field infoField = clazz.getDeclaredField(ConstructionTransformer.getConstructionInfoFieldName(getSimpleName(clazz), i)); 853 infoField.setAccessible(true); 854 infoField.set(null, new WeakReference (info)); 855 } 856 catch (NoSuchFieldException e) 857 { 858 } 860 catch (IllegalAccessException e) 861 { 862 throw new RuntimeException (e); 863 } 864 865 } 866 return newInfos; 867 } 868 869 protected void finalizeConstructorChain(ArrayList newConstructorInfos) 870 { 871 for (int i = 0; i < newConstructorInfos.size(); i++) 872 { 873 ConstructorInfo info = (ConstructorInfo) newConstructorInfos.get(i); 874 ArrayList list = info.getInterceptorChain(); 875 Interceptor[] interceptors = null; 876 if (list.size() > 0) 877 { 878 interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()])); 879 } 880 info.setInterceptors(interceptors); 881 } 882 } 883 884 protected void finalizeConstructionChain(ArrayList newConstructionInfos) 885 { 886 for (int i = 0; i < newConstructionInfos.size(); i++) 887 { 888 ConstructionInfo info = (ConstructionInfo) newConstructionInfos.get(i); 889 ArrayList list = info.getInterceptorChain(); 890 Interceptor[] interceptors = null; 891 if (list.size() > 0) 892 { 893 interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()])); 894 } 895 info.setInterceptors(interceptors); 896 } 897 } 898 899 protected void resolveConstructorPointcut(ArrayList newConstructorInfos, AdviceBinding binding) 900 { 901 for (int i = 0; i < constructors.length; i++) 902 { 903 Constructor constructor = constructors[i]; 904 if (binding.getPointcut().matchesExecution(this, constructor)) 905 { 906 if (AspectManager.verbose) System.err.println(constructor + " matched binding " + binding.getName() + " " + binding.getPointcut().getExpr()); 907 adviceBindings.add(binding); 908 binding.addAdvisor(this); 909 ConstructorInfo info = (ConstructorInfo)newConstructorInfos.get(i); 910 pointcutResolved(info, binding, new ConstructorJoinpoint(constructor)); 911 } 912 } 913 } 914 915 protected void resolveConstructionPointcut(ArrayList newConstructionInfos, AdviceBinding binding) 916 { 917 for (int i = 0; i < constructors.length; i++) 918 { 919 Constructor constructor = constructors[i]; 920 if (binding.getPointcut().matchesConstruction(this, constructor)) 921 { 922 if (AspectManager.verbose) System.err.println(constructor + " matched binding " + binding.getName() + " " + binding.getPointcut().getExpr()); 923 adviceBindings.add(binding); 924 binding.addAdvisor(this); 925 ConstructionInfo info = (ConstructionInfo) newConstructionInfos.get(i); 926 pointcutResolved(info, binding, new ConstructorJoinpoint(constructor)); 927 } 928 } 929 } 930 931 932 protected void populateInterceptorsFromInfos() 933 { 934 constructorInterceptors = new Interceptor[constructorInfos.length][]; 935 for (int i = 0 ; i < constructorInfos.length ; i++) 936 { 937 constructorInterceptors[i] = constructorInfos[i].getInterceptors(); 938 } 939 } 940 941 945 protected void pointcutResolved(JoinPointInfo info, AdviceBinding binding, Joinpoint joinpoint) 946 { 947 ArrayList curr = info.getInterceptorChain(); 948 if (binding.getCFlow() != null) 949 { 950 ArrayList cflowChain = new ArrayList (); 951 createInterceptorChain(binding.getInterceptorFactories(), cflowChain, joinpoint); 952 Interceptor[] cflowInterceptors = (Interceptor[]) cflowChain.toArray(new Interceptor[cflowChain.size()]); 953 curr.add(new CFlowInterceptor(binding.getCFlowString(), binding.getCFlow(), cflowInterceptors)); 954 } 955 else 956 { 957 createInterceptorChain(binding.getInterceptorFactories(), curr, joinpoint); 958 } 959 } 960 961 Interceptor[] applyPrecedence(Interceptor[] interceptors) 962 { 963 return PrecedenceSorter.applyPrecedence(interceptors, manager); 964 } 965 966 991 public boolean chainOverridingForInheritedMethods() 992 { 993 return false; 994 } 995 996 interface DeployAnnotationOverrideAction 997 { 998 void deploy(Advisor advisor, AnnotationIntroduction introduction); 999 1000 DeployAnnotationOverrideAction PRIVILEGED = new DeployAnnotationOverrideAction() 1001 { 1002 public void deploy(final Advisor advisor, final AnnotationIntroduction introduction) 1003 { 1004 try 1005 { 1006 AccessController.doPrivileged(new PrivilegedExceptionAction () 1007 { 1008 public Object run() 1009 { 1010 advisor.doDeployAnnotationOverride(introduction); 1011 return null; 1012 } 1013 }); 1014 } 1015 catch (PrivilegedActionException e) 1016 { 1017 Exception ex = e.getException(); 1018 if (ex instanceof RuntimeException ) 1019 { 1020 throw (RuntimeException )ex; 1021 } 1022 throw new RuntimeException (ex); 1023 } 1024 } 1025 }; 1026 1027 DeployAnnotationOverrideAction NON_PRIVILEGED = new DeployAnnotationOverrideAction() 1028 { 1029 public void deploy(Advisor advisor, AnnotationIntroduction introduction) 1030 { 1031 advisor.doDeployAnnotationOverride(introduction); 1032 } 1033 }; 1034 } 1035} | Popular Tags |