KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > AspectManager


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aop;
23
24 import java.lang.ref.WeakReference JavaDoc;
25 import java.lang.reflect.Field JavaDoc;
26 import java.security.AccessController JavaDoc;
27 import java.security.PrivilegedAction JavaDoc;
28 import java.security.ProtectionDomain JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Hashtable JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.LinkedHashMap JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.StringTokenizer JavaDoc;
39 import java.util.WeakHashMap JavaDoc;
40 import java.util.List JavaDoc;
41
42 import org.jboss.aop.advice.AdviceBinding;
43 import org.jboss.aop.advice.AdviceStack;
44 import org.jboss.aop.advice.AspectDefinition;
45 import org.jboss.aop.advice.AspectFactory;
46 import org.jboss.aop.advice.AspectFactoryWithClassLoader;
47 import org.jboss.aop.advice.DynamicCFlowDefinition;
48 import org.jboss.aop.advice.InterceptorFactory;
49 import org.jboss.aop.advice.PrecedenceDef;
50 import org.jboss.aop.advice.PrecedenceDefEntry;
51 import org.jboss.aop.advice.PrecedenceSorter;
52 import org.jboss.aop.advice.Scope;
53 import org.jboss.aop.classpool.AOPClassPoolRepository;
54 import org.jboss.aop.classpool.AOPScopedClassLoaderHelper;
55 import org.jboss.aop.instrument.GeneratedAdvisorInstrumentor;
56 import org.jboss.aop.instrument.Instrumentor;
57 import org.jboss.aop.instrument.InstrumentorFactory;
58 import org.jboss.aop.instrument.TransformerCommon;
59 import org.jboss.aop.introduction.AnnotationIntroduction;
60 import org.jboss.aop.introduction.InterfaceIntroduction;
61 import org.jboss.aop.metadata.ClassMetaDataBinding;
62 import org.jboss.aop.metadata.ClassMetaDataLoader;
63 import org.jboss.aop.metadata.SimpleClassMetaDataLoader;
64 import org.jboss.aop.pointcut.CFlowStack;
65 import org.jboss.aop.pointcut.DeclareDef;
66 import org.jboss.aop.pointcut.DynamicCFlow;
67 import org.jboss.aop.pointcut.Pointcut;
68 import org.jboss.aop.pointcut.PointcutExpression;
69 import org.jboss.aop.pointcut.PointcutInfo;
70 import org.jboss.aop.pointcut.PointcutStats;
71 import org.jboss.aop.pointcut.Typedef;
72 import org.jboss.aop.pointcut.ast.ClassExpression;
73 import org.jboss.util.loading.Translatable;
74 import org.jboss.util.loading.Translator;
75 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
76 import javassist.ClassPool;
77 import javassist.CtClass;
78 import javassist.scopedpool.ScopedClassPool;
79 import javassist.scopedpool.ScopedClassPoolFactory;
80
81 /**
82  * This singleton class manages all pointcuts and metadata.
83  * Coders can access it via the AspectManager.instance() method.
84  * <p/>
85  * It is also the middle man between the ClassLoader and
86  * the actual class instrumentation as well.
87  * <p/>
88  * App Developers that want to create and apply, interceptors,
89  * pointcuts, or metadata at runtime can also use this object
90  * to do that.
91  *
92  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
93  * @version $Revision: 56777 $
94  */

95 public class AspectManager
96         implements Translator
97 {
98
99    // Attributes ---------------------------------------------------
100
protected final WeakHashMap JavaDoc advisors = new WeakHashMap JavaDoc();
101    /** A map of domains by classloader, maintaned by the top level AspectManager */
102    protected final WeakHashMap JavaDoc scopedClassLoaderDomains = new WeakHashMap JavaDoc();
103
104    /** A map of domains by class, maintaned by the top level AspectManager */
105    protected final WeakHashMap JavaDoc subDomainsPerClass = new WeakHashMap JavaDoc();
106
107    /** Each domain may have sub domains interested in changes happening in this manager/domain */
108    protected final WeakHashMap JavaDoc subscribedSubDomains = new WeakHashMap JavaDoc();
109
110    /** A queue for adding new subscribed subdomains to */
111    protected final WeakHashMap JavaDoc subscribedSubDomainsQueue = new WeakHashMap JavaDoc();
112    protected int subscribedDomainQueueRef;
113
114    protected final LinkedHashMap JavaDoc interfaceIntroductions = new LinkedHashMap JavaDoc();
115    protected final LinkedHashMap JavaDoc annotationIntroductions = new LinkedHashMap JavaDoc();
116    protected final LinkedHashMap JavaDoc annotationOverrides = new LinkedHashMap JavaDoc();
117    protected final LinkedHashMap JavaDoc bindings = new LinkedHashMap JavaDoc();
118    protected final LinkedHashMap JavaDoc typedefs = new LinkedHashMap JavaDoc();
119    protected final HashMap JavaDoc interceptorFactories = new HashMap JavaDoc();
120    protected final Hashtable JavaDoc classMetaDataLoaders = new Hashtable JavaDoc();
121    protected final HashMap JavaDoc interceptorStacks = new HashMap JavaDoc();
122    protected final HashMap JavaDoc declares = new HashMap JavaDoc();
123    protected final ConcurrentReaderHashMap cflowStacks = new ConcurrentReaderHashMap();
124    protected final ConcurrentReaderHashMap dynamicCFlows = new ConcurrentReaderHashMap();
125    protected final ConcurrentReaderHashMap aspectDefinitions = new ConcurrentReaderHashMap();
126    protected final ConcurrentReaderHashMap perVMAspects = new ConcurrentReaderHashMap();
127
128    /** class name prefixes to explicitly exclude unless contained in include. Maintained by top-level AspectManager */
129    protected final ArrayList JavaDoc exclude = new ArrayList JavaDoc();
130
131    /** class name prefixes to explicitly include, this overrides whatever was set in exclude. Maintained by top-level AspectManager */
132    protected final ArrayList JavaDoc include = new ArrayList JavaDoc();
133
134    /** A set of wildcard enabled classnames that will be ignored no matter if they have been included. Maintained by top-level AspectManager */
135    protected final ArrayList JavaDoc ignore = new ArrayList JavaDoc();
136
137    /** ClassExpressions built from ignore. Maintained by top-level AspectManager */
138    protected ClassExpression[] ignoreExpressions = new ClassExpression[0];
139
140    protected final LinkedHashMap JavaDoc pointcuts = new LinkedHashMap JavaDoc();
141    // contains pointcuts-binding association info
142
protected final LinkedHashMap JavaDoc pointcutInfos = new LinkedHashMap JavaDoc();
143    // these fields represent whether there are certain pointcut types.
144
// for performance reasons the transformers and binders can make a lot of us of this.
145
protected boolean execution = false;
146    protected boolean construction = false;
147    protected boolean call = false;
148    protected boolean within = false;
149    protected boolean get = false;
150    protected boolean set = false;
151    protected boolean withincode = false;
152    public static boolean classicOrder = false;
153
154    protected final LinkedHashMap JavaDoc classMetaData = new LinkedHashMap JavaDoc();
155    protected final HashMap JavaDoc containers = new HashMap JavaDoc();
156    protected final LinkedHashMap JavaDoc precedenceDefs = new LinkedHashMap JavaDoc();
157    protected PrecedenceDefEntry[] sortedPrecedenceDefEntries;
158    protected WeavingStrategy weavingStrategy;
159
160    protected final ConcurrentReaderHashMap convertableReference = new ConcurrentReaderHashMap();
161    protected final ConcurrentReaderHashMap hasFieldInterception = new ConcurrentReaderHashMap();
162    protected final ConcurrentReaderHashMap hasConstructorInterception = new ConcurrentReaderHashMap();
163
164    protected final ConcurrentReaderHashMap skipConvertableReference = new ConcurrentReaderHashMap();
165    protected final ConcurrentReaderHashMap skipFieldInterception = new ConcurrentReaderHashMap();
166    protected final ConcurrentReaderHashMap skipConstructorInterception = new ConcurrentReaderHashMap();
167
168    protected DynamicAOPStrategy dynamicStrategy = new LoadInterceptedClassesStrategy();
169    // indicates that the transformation process has begun
170
protected boolean transformationStarted = false;
171
172    //This will be set by the AspectManagerService if running in JBoss
173
public static AOPScopedClassLoaderHelper scopedCLHelper;
174
175    public void addConstructionInterceptionMarker(String JavaDoc classname)
176    {
177       skipConstructorInterception.remove(classname);
178       skipConvertableReference.remove(classname);
179       hasConstructorInterception.put(classname, classname);
180       convertableReference.put(classname, classname);
181    }
182
183    public void addFieldInterceptionMarker(String JavaDoc classname)
184    {
185       skipFieldInterception.remove(classname);
186       skipConvertableReference.remove(classname);
187       hasFieldInterception.put(classname, classname);
188       convertableReference.put(classname, classname);
189    }
190
191    public void skipReference(String JavaDoc classname)
192    {
193       skipConvertableReference.put(classname, classname);
194    }
195
196    public boolean shouldSkipConstruction(String JavaDoc classname)
197    {
198       return !(hasConstructorInterception.containsKey(classname) || !skipConstructorInterception.containsKey(classname));
199       //return false;
200
}
201
202    public boolean shouldSkipFieldAccess(String JavaDoc classname)
203    {
204       return !(hasFieldInterception.containsKey(classname) || !skipFieldInterception.containsKey(classname));
205       //return false;
206
}
207
208    public void skipConstruction(String JavaDoc classname)
209    {
210       skipConstructorInterception.put(classname, classname);
211    }
212
213    public void skipFieldAccess(String JavaDoc classname)
214    {
215       skipFieldInterception.put(classname, classname);
216    }
217
218    public boolean convertReference(String JavaDoc classname)
219    {
220       return !skipConvertableReference.containsKey(classname) || convertableReference.containsKey(classname);
221       //return true;
222
}
223
224    // Static -------------------------------------------------------
225

226    protected static AspectManager manager;
227    public static boolean optimize = true;
228    public static boolean debugClasses;//If true, the generated advisor instrumentor will output the generated classes
229
public static ClassLoaderValidation classLoaderValidator;
230
231    /**
232     * logging switch. We don't use log4j to avoid another heavy library
233     */

234    public static boolean verbose = false;
235
236    public static synchronized AspectManager getTopLevelAspectManager()
237    {
238       if (scopedCLHelper != null)
239       {
240          //We are not running in jboss
241
return instance();
242       }
243       ClassLoader JavaDoc topUcl = scopedCLHelper.getTopLevelJBossClassLoader();
244       return instance(topUcl);
245
246    }
247
248    public static synchronized AspectManager instance()
249    {
250       return instance(Thread.currentThread().getContextClassLoader());
251    }
252
253    public static synchronized AspectManager instance(ClassLoader JavaDoc loadingClassLoader)
254    {
255       if (manager == null)
256       {
257          AccessController.doPrivileged(new PrivilegedAction JavaDoc()
258          {
259             public Object JavaDoc run()
260             {
261                String JavaDoc optimized = System.getProperty("jboss.aop.optimized", null);
262                if (optimized != null)
263                {
264                   optimize = (new Boolean JavaDoc(optimized)).booleanValue();
265                }
266                String JavaDoc pruneit = System.getProperty("jboss.aop.prune", null);
267                if (pruneit != null)
268                {
269                   AOPClassPoolRepository.getInstance().setPrune((new Boolean JavaDoc(pruneit)).booleanValue());
270                }
271                manager = new AspectManager();
272                AOPClassPoolRepository.getInstance().setAspectManager(manager);
273
274                if (!verbose)
275                {
276                   verbose = (new Boolean JavaDoc(System.getProperty("jboss.aop.verbose", "false"))).booleanValue();
277                }
278                String JavaDoc exclude = System.getProperty("jboss.aop.exclude", null);
279                if (exclude != null)
280                {
281                   ArrayList JavaDoc list = new ArrayList JavaDoc();
282                   StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(exclude, ",");
283                   while (tokenizer.hasMoreTokens())
284                   {
285                      list.add(tokenizer.nextToken().trim());
286                   }
287                   manager.setExclude(list);
288                }
289                String JavaDoc include = System.getProperty("jboss.aop.include", null);
290                if (include != null)
291                {
292                   ArrayList JavaDoc list = new ArrayList JavaDoc();
293                   StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(include, ",");
294                   while (tokenizer.hasMoreTokens())
295                   {
296                      list.add(tokenizer.nextToken().trim());
297                   }
298                   manager.setInclude(list);
299                }
300                String JavaDoc ignore = System.getProperty("jboss.aop.ignore", null);
301                if (ignore != null)
302                {
303                   ArrayList JavaDoc list = new ArrayList JavaDoc();
304                   StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(ignore, ",");
305                   while (tokenizer.hasMoreTokens())
306                   {
307                      list.add(tokenizer.nextToken().trim());
308                   }
309                   manager.setIgnore(list);
310                }
311
312                String JavaDoc instrument = System.getProperty("jboss.aop.instrumentor", null);
313                InstrumentorFactory.initialise(instrument);
314
315                String JavaDoc advisorName = System.getProperty("jboss.aop.advisor", null);
316                AdvisorFactory.initialise(advisorName);
317
318                String JavaDoc debugClass = System.getProperty("jboss.aop.debug.classes", null);
319                if (debugClass != null)
320                {
321                   debugClasses = (new Boolean JavaDoc(debugClass)).booleanValue();
322                }
323
324                String JavaDoc classic = System.getProperty("jboss.aop.classicorder", null);
325                if (classic != null)
326                {
327                   classicOrder = (new Boolean JavaDoc(classic)).booleanValue();
328                }
329
330
331                Deployment.deploy();
332                return null;
333             }
334          });
335       }
336
337       if (scopedCLHelper != null)
338       {
339          ClassLoader JavaDoc scopedClassLoader = scopedCLHelper.ifScopedDeploymentGetScopedParentUclForCL(loadingClassLoader);
340          if (scopedClassLoader != null)
341          {
342             Domain scopedManager = null;
343             synchronized (AOPClassPoolRepository.getInstance().getRegisteredCLs())
344             {
345                scopedManager = (Domain)manager.scopedClassLoaderDomains.get(scopedClassLoader);
346                if (scopedManager == null)
347                {
348                   scopedManager = scopedCLHelper.getScopedClassLoaderDomain(scopedClassLoader, manager);
349                   if (verbose)
350                   {
351                      System.out.println("Created domain " + scopedManager + " for scoped deployment on: " +
352                            loadingClassLoader + "; identifying scoped ucl: " + scopedClassLoader);
353                   }
354                   scopedManager.setInheritsBindings(true);
355                   scopedManager.setInheritsDeclarations(true);
356                   manager.scopedClassLoaderDomains.put(scopedClassLoader, scopedManager);
357                }
358             }
359             return scopedManager;
360          }
361       }
362       return manager;
363    }
364
365
366    public LinkedHashMap JavaDoc getPointcuts()
367    {
368       return pointcuts;
369    }
370
371    public LinkedHashMap JavaDoc getPointcutInfos()
372    {
373       return pointcutInfos;
374    }
375
376    public CFlowStack getCFlowStack(String JavaDoc name)
377    {
378       return (CFlowStack) cflowStacks.get(name);
379    }
380
381    public void addCFlowStack(CFlowStack stack)
382    {
383       cflowStacks.put(stack.getName(), stack);
384    }
385
386    public void removeCFlowStack(String JavaDoc name)
387    {
388       cflowStacks.remove(name);
389    }
390
391    public DynamicCFlow getDynamicCFlow(String JavaDoc name)
392    {
393       DynamicCFlowDefinition def = (DynamicCFlowDefinition) dynamicCFlows.get(name);
394
395       if (def != null)
396       {
397          return def.create();
398       }
399       return null;
400    }
401
402
403    /* (non-Javadoc)
404     * @see org.jboss.aop.Manager#addDynamicCFlow(java.lang.String, org.jboss.aop.advice.DynamicCFlowDefinition)
405     */

406    public void addDynamicCFlow(String JavaDoc name, DynamicCFlowDefinition cflow)
407    {
408       dynamicCFlows.put(name, cflow);
409    }
410
411    public void removeDynamicCFlow(String JavaDoc name)
412    {
413       dynamicCFlows.remove(name);
414    }
415
416    /**
417     * This is a callback object that receives events about
418     * new pointcuts, interceptors and metadata.
419     * The Aspect Management console hooks into this listener
420     */

421    public static AspectNotificationHandler notificationHandler = null;
422
423    public static boolean suppressTransformationErrors = false;
424
425
426    /**
427     * Suppress when a class cannot be found that a class references
428     * This may happen if code in a class references something and the
429     * class is not in the classpath.
430     */

431    public static boolean suppressReferenceErrors = true;
432
433    // Constructors -------------------------------------------------
434

435    /**
436     * Called by subclasses
437     */

438    public AspectManager()
439    {
440
441    }
442    /**
443     * Every &lt;class-metadata&gt; tag corresponds to
444     * a ClassMetaDataLoader. The ClassMetaDataLoader knows how to take
445     * arbitrary XML and apply it to SimpleMetaData.
446     * <p/>
447     * Given a group, return the loader for that group
448     */

449    public ClassMetaDataLoader findClassMetaDataLoader(String JavaDoc group)
450    {
451       ClassMetaDataLoader loader = (ClassMetaDataLoader) classMetaDataLoaders.get(group);
452       if (loader == null) loader = SimpleClassMetaDataLoader.singleton;
453       return loader;
454    }
455
456    /**
457     * Every &lt;class-metadata&gt; tag corresponds to
458     * a ClassMetaDataLoader. The ClassMetaDataLoader knows how to take
459     * arbitrary XML and apply it to SimpleMetaData.
460     * <p/>
461     * Add a loader for a given group
462     */

463    public void addClassMetaDataLoader(String JavaDoc group, ClassMetaDataLoader loader)
464    {
465       classMetaDataLoaders.put(group, loader);
466    }
467
468    /**
469     * Remove a loader for a given group
470     */

471    public void removeClassMetaDataLoader(String JavaDoc group)
472    {
473       classMetaDataLoaders.remove(group);
474    }
475
476    public Map JavaDoc getAdvisors()
477    {
478       return advisors;
479    }
480
481    public Advisor getAdvisor(String JavaDoc name)
482    {
483       /*
484       synchronized (advisors)
485       {
486          return (Advisor) advisors.get(name);
487       }
488       */

489       throw new RuntimeException JavaDoc("OPERATION NOT SUPPORTED ANYMORE");
490    }
491
492    public LinkedHashMap JavaDoc getBindings()
493    {
494       return bindings;
495    }
496
497    protected Map JavaDoc getSubDomainsPerClass()
498    {
499       return subDomainsPerClass;
500    }
501
502    public Advisor findAdvisor(Class JavaDoc clazz)
503    {
504       if (getSubDomainsPerClass().size() > 0)
505       {
506          //For generated advisors each advisor has its own domain
507
//This is primarily needed for the reflection aspect
508
Domain subDomain = null;
509          synchronized (getSubDomainsPerClass())
510          {
511             WeakReference JavaDoc ref = (WeakReference JavaDoc)getSubDomainsPerClass().get(clazz);
512             if (ref != null)
513             {
514                subDomain = (Domain)ref.get();
515             }
516          }
517
518          if (subDomain != null && subDomain != this)
519          {
520             Advisor advisor = subDomain.findAdvisor(clazz);
521             if (advisor != null)
522             {
523                return advisor;
524             }
525          }
526       }
527
528       synchronized (advisors)
529       {
530          WeakReference JavaDoc ref = (WeakReference JavaDoc) advisors.get(clazz);
531          if (ref == null) return null;
532          return (Advisor) ref.get();
533       }
534    }
535
536    public ClassAdvisor getAdvisorIfAdvised(Class JavaDoc clazz)
537    {
538       return (ClassAdvisor)getAnyAdvisorIfAdvised(clazz);
539    }
540
541    /**
542     * Take into account that an advisor may be a container
543     */

544    public Advisor getAnyAdvisorIfAdvised(Class JavaDoc clazz)
545    {
546       try
547       {
548          Advisor advisor;
549          advisor = findAdvisor(clazz);
550          if (advisor == null)
551          {
552             return null;
553          }
554          if (advisor.getClazz() == null && advisor instanceof ClassAdvisor)
555          {
556             ((ClassAdvisor)advisor).attachClass(clazz);
557             if (notificationHandler != null)
558             {
559                notificationHandler.attachClass(clazz.getName());
560             }
561          }
562          return advisor;
563       }
564       catch (RuntimeException JavaDoc ex)
565       {
566          ex.printStackTrace();
567          throw ex;
568       }
569    }
570
571    /**
572     * This method is called by the aspectized class when it is loaded
573     * This causes all initialization of interceptors for ClassAdvisor
574     *
575     * @param clazz
576     * @return
577     */

578    public ClassAdvisor getAdvisor(Class JavaDoc clazz)
579    {
580       ClassAdvisor advisor = null;
581       // See if one already exists
582
advisor = (ClassAdvisor)findAdvisor(clazz);
583       // if one does not
584
if (advisor == null)
585       {
586          advisor = AdvisorFactory.getClassAdvisor(clazz, this);
587          initialiseClassAdvisor(clazz, advisor);
588       }
589       return advisor;
590    }
591
592    public void initialiseClassAdvisor(Class JavaDoc clazz, ClassAdvisor advisor)
593    {
594       synchronized (advisors)
595       {
596          advisors.put(clazz, new WeakReference JavaDoc(advisor));
597       }
598
599       registerClass(clazz);
600       advisor.attachClass(clazz);
601       InterceptorChainObserver observer = dynamicStrategy.getInterceptorChainObserver(clazz);
602       advisor.setInterceptorChainObserver(observer);
603       if (notificationHandler != null)
604       {
605          notificationHandler.attachClass(clazz.getName());
606       }
607    }
608
609    // Public -------------------------------------------------------
610

611    public static Map JavaDoc getRegisteredCLs()
612    {
613       return AOPClassPoolRepository.getInstance().getRegisteredCLs();
614    }
615
616    /**
617     * This method will check to see if a register classloader has been undeployed (as in JBoss)
618     */

619    public static void clearUnregisteredClassLoaders()
620    {
621       AOPClassPoolRepository.getInstance().clearUnregisteredClassLoaders();
622    }
623
624    /**
625     * Checks to see if an Advisor represents a class that should have been undeployed.
626     *
627     * @param advisor
628     * @return
629     */

630    public boolean isAdvisorRegistered(Advisor advisor)
631    {
632       synchronized (getRegisteredCLs())
633       {
634          if (!advisors.containsKey(advisor.getClazz())) return false;
635          ScopedClassPool pool = (ScopedClassPool) getRegisteredClassPool(advisor.getClazz().getClassLoader());
636          if (pool == null) return false;
637          if (pool.isUnloadedClassLoader())
638          {
639             unregisterClassLoader(advisor.getClazz().getClassLoader());
640             return false;
641          }
642          else
643          {
644             return true;
645          }
646       }
647    }
648
649    public ClassPool findClassPool(ClassLoader JavaDoc cl)
650    {
651       if (!(cl instanceof Translatable))
652       {
653          // findClassPool has problems with boot and system classes.
654
return registerClassLoader(Thread.currentThread().getContextClassLoader());
655       }
656       return registerClassLoader(cl);
657    }
658
659    protected ClassPool getRegisteredClassPool(ClassLoader JavaDoc cl)
660    {
661       return (ClassPool)getRegisteredCLs().get(cl);
662    }
663
664    public ClassPool registerClassLoader(ClassLoader JavaDoc ucl)
665    {
666       return AOPClassPoolRepository.getInstance().registerClassLoader(ucl);
667    }
668
669    protected void registerClass(Class JavaDoc clazz)
670    {
671       AOPClassPoolRepository.getInstance().registerClass(clazz);
672    }
673
674    protected Map JavaDoc getScopedClassLoaderDomains()
675    {
676       return scopedClassLoaderDomains;
677    }
678
679    public void unregisterClassLoader(ClassLoader JavaDoc cl)
680    {
681       AOPClassPoolRepository.getInstance().unregisterClassLoader(cl);
682       //top-level only
683
getScopedClassLoaderDomains().remove(cl);
684    }
685
686    public ArrayList JavaDoc getExclude()
687    {
688       return exclude;
689    }
690
691    public void setExclude(ArrayList JavaDoc exclude)
692    {
693       this.exclude.clear();
694       this.exclude.addAll(exclude);
695    }
696
697    public ArrayList JavaDoc getInclude()
698    {
699       return include;
700    }
701
702    public void setInclude(ArrayList JavaDoc include)
703    {
704       this.include.clear();
705       this.include.addAll(include);
706    }
707
708    public ArrayList JavaDoc getIgnore()
709    {
710       return ignore;
711    }
712
713    public ClassExpression[] getIgnoreExpressions()
714    {
715       return ignoreExpressions;
716    }
717
718    public void setIgnore(ArrayList JavaDoc ignore)
719    {
720       this.ignore.clear();
721       this.ignore.addAll(ignore);
722       ignoreExpressions = new ClassExpression[ignore.size()];
723       for (int i = 0 ; i < ignore.size() ; i++)
724       {
725         String JavaDoc ex = (String JavaDoc)ignore.get(i);
726         ignoreExpressions[i] = new ClassExpression(ex);
727       }
728    }
729
730    public boolean ignoreClass(String JavaDoc classname)
731    {
732       ArrayList JavaDoc ignore = getIgnore();
733       if (ignore == null) return false;
734       for (int i = 0; i < ignoreExpressions.length; i++)
735       {
736          if(ignoreExpressions[i].matches(classname)) return true;
737       }
738       return false;
739    }
740
741    public boolean includeClass(String JavaDoc classname)
742    {
743       ArrayList JavaDoc include = getInclude();
744       if (include == null) return false;
745       for (int i = 0; i < include.size(); i++)
746       {
747          String JavaDoc str = (String JavaDoc) include.get(i);
748          if (classname.startsWith(str)) return true;
749       }
750       return false;
751    }
752
753    public boolean excludeClass(String JavaDoc classname)
754    {
755       ArrayList JavaDoc exclude = getExclude();
756       if (exclude == null) return false;
757       for (int i = 0; i < exclude.size(); i++)
758       {
759          String JavaDoc str = (String JavaDoc) exclude.get(i);
760          if (classname.startsWith(str)) return true;
761       }
762       return false;
763    }
764
765    public static boolean getPrune()
766    {
767       return AOPClassPoolRepository.getInstance().isPrune();
768    }
769
770    public static void setPrune(boolean prune)
771    {
772       AOPClassPoolRepository.getInstance().setPrune(prune);
773    }
774
775    public static void setClassPoolFactory(ScopedClassPoolFactory factory)
776    {
777       AOPClassPoolRepository.getInstance().setClassPoolFactory(factory);
778    }
779
780    public static ScopedClassPoolFactory getClassPoolFactory()
781    {
782       return AOPClassPoolRepository.getInstance().getClassPoolFactory();
783    }
784
785    public boolean isNonAdvisableClassName(String JavaDoc classname)
786    {
787       if (ignoreClass(classname)) return true;
788       if (includeClass(classname)) return false;
789       if (excludeClass(classname)) return true;
790       return (classname.startsWith("org.jboss.aop") ||
791               classname.endsWith("$aop") ||
792               classname.startsWith("javassist") ||
793               classname.startsWith("org.jboss.util.") ||
794               classname.startsWith("gnu.trove.") ||
795               classname.startsWith("EDU.oswego.cs.dl.util.concurrent.") ||
796       // System classes
797
classname.startsWith("org.apache.tools.ant") ||
798               classname.startsWith("org.apache.crimson") ||
799               classname.startsWith("org.apache.xalan") ||
800               classname.startsWith("org.apache.xml") ||
801               classname.startsWith("org.apache.xpath") ||
802               classname.startsWith("org.ietf.") ||
803               classname.startsWith("org.omg.") ||
804               classname.startsWith("org.w3c.") ||
805               classname.startsWith("org.xml.sax.") ||
806               classname.startsWith("sunw.") ||
807               classname.startsWith("sun.") ||
808               classname.startsWith("java.") ||
809               classname.startsWith("javax.") ||
810               classname.startsWith("com.sun.") ||
811               classname.startsWith("junit") ||
812               classname.startsWith("jrockit.") ||
813               classname.startsWith("com.bea.vm.")
814              );
815    }
816
817    /**
818     * This is the hook for ClassLoaders that want to instrument their classes with AOP
819     * <p/>
820     * This would be called during a findClass or loadClass call. The return value
821     * is used by defineClass to create the class from bytecode
822     */

823    public byte[] transform(ClassLoader JavaDoc loader,
824                            String JavaDoc className,
825                            Class JavaDoc classBeingRedefined,
826                            ProtectionDomain JavaDoc protectionDomain,
827                            byte[] classfileBuffer)
828            throws Exception JavaDoc
829    {
830       byte[] b = translate(className, loader, classfileBuffer);
831       return b;
832    }
833
834
835    /**
836     * This is to be backward compatible with JBoss 3.2.3 Translator interface
837     *
838     * @param className
839     * @param loader
840     * @return
841     * @throws Exception
842     */

843    public byte[] translate(String JavaDoc className, ClassLoader JavaDoc loader) throws Exception JavaDoc
844    {
845       return translate(className, loader, null);
846    }
847
848    /**
849     * This is to be backward compatible with JBoss 3.2.3 Translator interface
850     *
851     * @param className
852     * @param loader
853     * @return
854     * @throws Exception
855     */

856    public byte[] translate(String JavaDoc className, ClassLoader JavaDoc loader, byte[] classfileBuffer) throws Exception JavaDoc
857    {
858       try
859       {
860          if (isNonAdvisableClassName(className))
861          {
862             return null;
863          }
864          if (weavingStrategy == null)
865          {
866            synchronized (this)
867             {
868                if (TransformerCommon.isCompileTime() || classicOrder)
869                {
870                   weavingStrategy = new ClassicWeavingStrategy();
871                }
872                else if(InstrumentorFactory.getInstrumentor(this,dynamicStrategy.getJoinpointClassifier())
873                      instanceof GeneratedAdvisorInstrumentor)
874                {
875                   weavingStrategy = new SuperClassesFirstWeavingStrategy();
876                }
877                else
878                {
879                   weavingStrategy = new ClassicWeavingStrategy();
880                }
881             }
882          }
883
884          return weavingStrategy.translate(this, className, loader, classfileBuffer);
885       }
886       catch (Exception JavaDoc e)
887       {
888          // AutoGenerated
889
throw new RuntimeException JavaDoc(e);
890       }
891    }
892
893    /**
894     * Add an interceptor factory that can be referenced by name.
895     */

896    public void addInterceptorFactory(String JavaDoc name, InterceptorFactory factory)
897    {
898       synchronized (interceptorFactories)
899       {
900          interceptorFactories.put(name, factory);
901       }
902    }
903
904    /**
905     * Remove an interceptor factory that can be referenced by name.
906     */

907    public void removeInterceptorFactory(String JavaDoc name)
908    {
909       synchronized (interceptorFactories)
910       {
911          interceptorFactories.remove(name);
912       }
913    }
914
915    public Map JavaDoc getInterceptorFactories()
916    {
917       return interceptorFactories;
918    }
919
920    /**
921     * Find the interceptor factory that can be referenced by name.
922     */

923    public InterceptorFactory getInterceptorFactory(String JavaDoc name)
924    {
925       synchronized (interceptorFactories)
926       {
927          return (InterceptorFactory) interceptorFactories.get(name);
928       }
929    }
930
931
932    public void addPrecedence(PrecedenceDef precedenceDef)
933    {
934       synchronized (precedenceDefs)
935       {
936          precedenceDefs.put(precedenceDef.getName(), precedenceDef);
937       }
938       forceResortPrecedenceDefs();
939    }
940
941
942    public void removePrecedence(String JavaDoc name)
943    {
944       synchronized (precedenceDefs)
945       {
946          precedenceDefs.remove(name);
947       }
948
949       forceResortPrecedenceDefs();
950    }
951
952    protected void forceResortPrecedenceDefs()
953    {
954       synchronized (precedenceDefs)
955       {
956          sortedPrecedenceDefEntries = null;
957       }
958       synchronized (subscribedSubDomains)
959       {
960          copySubDomainsFromQueue(true);
961          boolean newSubscribers = true;
962          while (newSubscribers)
963          {
964             for (Iterator JavaDoc it = subscribedSubDomains.keySet().iterator() ; it.hasNext() ; )
965             {
966                Domain domain = (Domain)it.next();
967                domain.forceResortPrecedenceDefs();
968             }
969             newSubscribers = copySubDomainsFromQueue(false);
970          }
971       }
972    }
973
974    public LinkedHashMap JavaDoc getPrecedenceDefs()
975    {
976       return precedenceDefs;
977    }
978
979    public PrecedenceDefEntry[] getSortedPrecedenceDefEntries()
980    {
981       if (sortedPrecedenceDefEntries == null)
982       {
983          synchronized (precedenceDefs)
984          {
985             if (sortedPrecedenceDefEntries == null)
986             {
987                sortedPrecedenceDefEntries = PrecedenceSorter.createOverallPrecedence(this);
988             }
989          }
990       }
991       return sortedPrecedenceDefEntries;
992    }
993
994    /**
995     * Add a referencable InterceptorStack( &lt;stack&gt; )
996     */

997    public void addAdviceStack(AdviceStack stack)
998    {
999       synchronized (interceptorStacks)
1000      {
1001         interceptorStacks.put(stack.getName(), stack);
1002      }
1003   }
1004
1005   /**
1006    * Remove a referencable InterceptorStack( &lt;stack&gt; )
1007    */

1008   public void removeInterceptorStack(String JavaDoc name)
1009   {
1010      synchronized (interceptorStacks)
1011      {
1012         interceptorStacks.remove(name);
1013      }
1014   }
1015
1016   /**
1017    * Find an interceptor stack referenced by name ( &lt;stack&gt; )
1018    */

1019   public AdviceStack getAdviceStack(String JavaDoc name)
1020   {
1021      synchronized (interceptorStacks)
1022      {
1023         return (AdviceStack) interceptorStacks.get(name);
1024      }
1025   }
1026
1027
1028   protected boolean attachMetaData(ClassAdvisor advisor, CtClass clazz, boolean addAdvisor) throws Exception JavaDoc
1029   {
1030      boolean attached = false;
1031      synchronized (classMetaData)
1032      {
1033         Iterator JavaDoc it = classMetaData.values().iterator();
1034         while (it.hasNext())
1035         {
1036            ClassMetaDataBinding data = (ClassMetaDataBinding) it.next();
1037            if (data.matches(advisor, clazz))
1038            {
1039               attached = true;
1040               if (addAdvisor) data.addAdvisor(advisor);
1041               ClassMetaDataLoader loader = data.getLoader();
1042               loader.bind(advisor, data, clazz.getDeclaredMethods(), clazz.getDeclaredFields(), clazz.getDeclaredConstructors());
1043            }
1044         }
1045      }
1046      return attached;
1047   }
1048
1049   protected void attachMetaData(ClassAdvisor advisor, Class JavaDoc clazz)
1050   {
1051      synchronized (classMetaData)
1052      {
1053         Iterator JavaDoc it = classMetaData.values().iterator();
1054         while (it.hasNext())
1055         {
1056            ClassMetaDataBinding data = (ClassMetaDataBinding) it.next();
1057            addAdvisorToClassMetaDataBinding(data, clazz, advisor, clazz);
1058         }
1059      }
1060   }
1061
1062   public ClassAdvisor getTempClassAdvisor(CtClass clazz) throws Exception JavaDoc
1063   {
1064      String JavaDoc classname = clazz.getName();
1065      ClassAdvisor advisor = AdvisorFactory.getClassAdvisor(clazz, this);
1066      attachMetaData(advisor, clazz, false);
1067      applyInterfaceIntroductions(advisor, clazz);
1068      return advisor;
1069   }
1070
1071   public Advisor getTempClassAdvisorIfNotExist(Class JavaDoc clazz)
1072   {
1073      Advisor advisor = findAdvisor(clazz);
1074      if (advisor != null) return advisor;
1075      if (Advised.class.isAssignableFrom(clazz))
1076      {
1077
1078         Class JavaDoc superClass = clazz;
1079         try
1080         {
1081            while (superClass != null)
1082            {
1083               try
1084               {
1085                  Field JavaDoc field = superClass.getDeclaredField(Instrumentor.HELPER_FIELD_NAME);
1086                  SecurityActions.setAccessible(field);
1087                  return (ClassAdvisor) field.get(null);
1088               }
1089               catch (NoSuchFieldException JavaDoc e)
1090               {
1091                  superClass = clazz.getSuperclass();
1092               }
1093            }
1094         }
1095         catch (IllegalAccessException JavaDoc e)
1096         {
1097            throw new RuntimeException JavaDoc(e);
1098         }
1099      }
1100
1101      advisor = AdvisorFactory.getClassAdvisor(clazz, this);
1102      advisor.setClazz(clazz);
1103      return advisor;
1104   }
1105
1106
1107   public DomainDefinition getContainer(String JavaDoc name)
1108   {
1109      return (DomainDefinition) containers.get(name);
1110   }
1111
1112   public void addContainer(DomainDefinition def)
1113   {
1114      containers.put(def.getName(), def);
1115   }
1116
1117   public void removeContainer(String JavaDoc name)
1118   {
1119      containers.remove(name);
1120   }
1121
1122   /**
1123    * Find a pointcut of with a given name
1124    */

1125   public Pointcut getPointcut(String JavaDoc name)
1126   {
1127      synchronized (pointcuts)
1128      {
1129         return (Pointcut) pointcuts.get(name);
1130      }
1131   }
1132
1133   /**
1134    * Remove an interceptor pointcut with a given name
1135    */

1136   public void removePointcut(String JavaDoc name)
1137   {
1138      synchronized (pointcuts)
1139      {
1140         pointcuts.remove(name);
1141         pointcutInfos.remove(name);
1142      }
1143   }
1144
1145   /**
1146    * Add an interceptor pointcut with a given name
1147    */

1148   public synchronized void addPointcut(Pointcut pointcut)
1149   {
1150      removePointcut(pointcut.getName());
1151      synchronized (pointcuts)
1152      {
1153         pointcuts.put(pointcut.getName(), pointcut);
1154         pointcutInfos.put(pointcut.getName(), new PointcutInfo(pointcut, this.transformationStarted));
1155      }
1156      updatePointcutStats(pointcut);
1157   }
1158
1159   /**
1160    * THis method is used for performance reasons.
1161    *
1162    * @param pointcut
1163    */

1164   protected void updatePointcutStats(Pointcut pointcut)
1165   {
1166      // the following is for performance reasons.
1167
if (pointcut instanceof PointcutExpression)
1168      {
1169         PointcutExpression expr = (PointcutExpression) pointcut;
1170         expr.setManager(this);
1171         PointcutStats stats = expr.getStats();
1172         updateStats(stats);
1173      }
1174      else
1175      {
1176         // can't be sure so set all
1177
execution = true;
1178         construction = true;
1179         call = true;
1180         within = true;
1181         get = true;
1182         set = true;
1183         withincode = true;
1184      }
1185   }
1186
1187   protected void updateStats(PointcutStats stats)
1188   {
1189      if (stats != null)
1190      {
1191         construction |= stats.isConstruction();
1192         execution |= stats.isExecution();
1193         call |= stats.isCall();
1194         within |= stats.isWithin();
1195         get |= stats.isGet();
1196         set |= stats.isSet();
1197         withincode |= stats.isWithincode();
1198      }
1199      else
1200      {
1201         if (verbose) System.out.println("[debug] Setting all pointcut stats to true");
1202         // can't be sure so set all
1203
execution = true;
1204         construction = true;
1205         call = true;
1206         within = true;
1207         get = true;
1208         set = true;
1209         withincode = true;
1210      }
1211   }
1212
1213   public boolean isExecution()
1214   {
1215      return execution;
1216   }
1217
1218   public boolean isConstruction()
1219   {
1220      return construction;
1221   }
1222
1223   public boolean isCall()
1224   {
1225      return call;
1226   }
1227
1228   public boolean isWithin()
1229   {
1230      return within;
1231   }
1232
1233   public boolean isWithincode()
1234   {
1235      return withincode;
1236   }
1237
1238   public boolean isGet()
1239   {
1240      return get;
1241   }
1242
1243   public boolean isSet()
1244   {
1245      return set;
1246   }
1247
1248   /**
1249    * Remove an interceptor pointcut with a given name
1250    */

1251   public void removeBinding(String JavaDoc name)
1252   {
1253      AdviceBinding binding = internalRemoveBinding(name);
1254      if (binding != null)
1255      {
1256         binding.clearAdvisors();
1257         dynamicStrategy.interceptorChainsUpdated();
1258      }
1259   }
1260
1261   public void removeBindings(ArrayList JavaDoc binds)
1262   {
1263      clearUnregisteredClassLoaders();
1264
1265      HashSet JavaDoc bindingAdvisors = new HashSet JavaDoc();
1266      ArrayList JavaDoc removedBindings = new ArrayList JavaDoc();
1267      synchronized (bindings)
1268      {
1269         int bindSize = binds.size();
1270
1271         for (int i = 0; i < bindSize; i++)
1272         {
1273
1274            AdviceBinding binding = (AdviceBinding) bindings.get(binds.get(i));
1275            if (binding == null)
1276            {
1277               System.out.println("[warn] AspectManager.removeBindings() no binding found with name " + binds.get(i));
1278               continue;
1279            }
1280            ArrayList JavaDoc ads = binding.getAdvisors();
1281            bindingAdvisors.addAll(ads);
1282            bindings.remove(binding.getName());
1283            Pointcut pointcut = binding.getPointcut();
1284            this.removePointcut(pointcut.getName());
1285            removedBindings.add(binding);
1286         }
1287      }
1288      Iterator JavaDoc it = bindingAdvisors.iterator();
1289      while (it.hasNext())
1290      {
1291         Advisor advisor = (Advisor) it.next();
1292         if (!isAdvisorRegistered(advisor))
1293         {
1294            //Check sub domains in case of generated advisors
1295

1296            WeakReference JavaDoc ref = (WeakReference JavaDoc)getSubDomainsPerClass().get(advisor.getClazz());
1297            Domain domain = null;
1298            if (ref != null) domain = (Domain)ref.get();
1299            if (domain != null)
1300            {
1301               if (subscribedSubDomains.containsKey(domain))
1302               {
1303                  if (!domain.isAdvisorRegistered(advisor))continue;
1304               }
1305            }
1306         }
1307         advisor.removeAdviceBindings(removedBindings);
1308      }
1309      dynamicStrategy.interceptorChainsUpdated();
1310   }
1311
1312   /**
1313    * Add an interceptor pointcut with a given name
1314    */

1315   public synchronized void addBinding(AdviceBinding binding)
1316   {
1317      AdviceBinding removedBinding = internalRemoveBinding(binding.getName());
1318      Set JavaDoc affectedAdvisors = removedBinding == null? new HashSet JavaDoc(): new HashSet JavaDoc(removedBinding.getAdvisors());
1319      synchronized (bindings)
1320      {
1321         bindings.put(binding.getName(), binding);
1322      }
1323      synchronized (pointcuts)
1324      {
1325         Pointcut pointcut = binding.getPointcut();
1326         pointcuts.put(pointcut.getName(), pointcut);
1327         pointcutInfos.put(pointcut.getName(), new PointcutInfo(pointcut, binding, this.transformationStarted));
1328         updatePointcutStats(pointcut);
1329      }
1330
1331      synchronized (advisors)
1332      {
1333         updateAdvisorsForAddedBinding(binding);
1334
1335         for (Iterator JavaDoc i = affectedAdvisors.iterator(); i.hasNext(); )
1336         {
1337            Advisor advisor = (Advisor) i.next();
1338            if (isAdvisorRegistered(advisor))
1339               advisor.removeAdviceBinding(removedBinding);
1340         }
1341      }
1342      this.dynamicStrategy.interceptorChainsUpdated();
1343   }
1344
1345
1346   public void updateAdvisorsForAddedBinding(AdviceBinding binding)
1347   {
1348      synchronized (advisors)
1349      {
1350         //System.out.println("******* addBinding to possibly this many advisors: " + advisors.size());
1351
Collection JavaDoc keys = advisors.keySet();
1352         if (keys.size() > 0)
1353         {
1354            Iterator JavaDoc it = keys.iterator();
1355            while (it.hasNext())
1356            {
1357               Advisor advisor = getAdvisorFromAdvisorsKeySetIterator(it);
1358               if (advisor == null) continue;
1359
1360               if (binding.getPointcut().softMatch(advisor))
1361               {
1362                  if (AspectManager.verbose)
1363                     System.out.println("[debug] softmatch succeeded for : " + advisor.getName() + " " + binding + " " + binding.getPointcut().getExpr());
1364                  advisor.newBindingAdded();
1365                  //affectedAdvisors.remove(advisor);
1366
}
1367               else
1368               {
1369                  if (AspectManager.verbose)
1370                     System.out.println("[debug] softmatch failed for : " + advisor.getName() + " " + binding + " " + binding.getPointcut().getExpr());
1371               }
1372            }
1373         }
1374      }
1375      synchronized (subscribedSubDomains)
1376      {
1377         copySubDomainsFromQueue(true);
1378         boolean newSubscribers = true;
1379         while (newSubscribers)
1380         {
1381            Collection JavaDoc keys = subscribedSubDomains.keySet();
1382            if (keys.size() > 0)
1383            {
1384               //When interceptors are installed as beans in the microcontainer, creating the interceptor instances
1385
for (Iterator JavaDoc it = keys.iterator() ; it.hasNext() ; )
1386               {
1387                  Domain domain = (Domain)it.next();
1388                  domain.updateAdvisorsForAddedBinding(binding);
1389               }
1390            }
1391            newSubscribers = copySubDomainsFromQueue(false);
1392         }
1393      }
1394   }
1395
1396   public void removeClassMetaData(String JavaDoc name)
1397   {
1398      synchronized (classMetaData)
1399      {
1400         ClassMetaDataBinding meta = (ClassMetaDataBinding) classMetaData.remove(name);
1401         if (meta == null) return;
1402         meta.clearAdvisors();
1403      }
1404   }
1405
1406   public void addClassMetaData(ClassMetaDataBinding meta)
1407   {
1408      removeClassMetaData(meta.getName());
1409
1410      updateAdvisorsForAddedClassMetaData(meta);
1411
1412      synchronized (classMetaData)
1413      {
1414         classMetaData.put(meta.getName(), meta);
1415      }
1416   }
1417
1418   protected void updateAdvisorsForAddedClassMetaData(ClassMetaDataBinding meta)
1419   {
1420      synchronized (advisors)
1421      {
1422         Iterator JavaDoc it = advisors.keySet().iterator();
1423
1424         while (it.hasNext())
1425         {
1426            Advisor advisor = getAdvisorFromAdvisorsKeySetIterator(it);
1427            if (advisor == null) continue;
1428
1429            Class JavaDoc clazz = advisor.getClazz();
1430            addAdvisorToClassMetaDataBinding(meta, clazz, advisor, clazz);
1431         }
1432      }
1433
1434      synchronized (subscribedSubDomains)
1435      {
1436         copySubDomainsFromQueue(true);
1437         boolean newSubscribers = true;
1438         while (newSubscribers)
1439         {
1440            for (Iterator JavaDoc it = subscribedSubDomains.keySet().iterator() ; it.hasNext() ; )
1441            {
1442               Domain domain = (Domain)it.next();
1443               domain.updateAdvisorsForAddedClassMetaData(meta);
1444            }
1445            newSubscribers = copySubDomainsFromQueue(false);
1446         }
1447      }
1448   }
1449
1450   protected void addAdvisorToClassMetaDataBinding(ClassMetaDataBinding meta, Class JavaDoc clazz, Advisor advisor, Class JavaDoc advisedClass)
1451   {
1452      if (meta.matches(advisor, clazz))
1453      {
1454            meta.addAdvisor(advisor);
1455      }
1456      else if (advisor.chainOverridingForInheritedMethods())
1457      {
1458         //If advisor class does not match class metadata directly, try the superclasses so that methods can inherit
1459
//old skool weaving doesn't support metadata overriding for inherited methods, so only do this extra work for generated advisors
1460
Class JavaDoc superClass = clazz.getSuperclass();
1461         if (superClass != null && superClass != Object JavaDoc.class)
1462         {
1463            addAdvisorToClassMetaDataBinding(meta, superClass, advisor, advisedClass);
1464         }
1465      }
1466   }
1467
1468   //--- Introductions
1469

1470   /**
1471    * Retrieve an introduction pointcut of a certain name
1472    */

1473   public InterfaceIntroduction getInterfaceIntroduction(String JavaDoc name)
1474   {
1475      synchronized (interfaceIntroductions)
1476      {
1477         return (InterfaceIntroduction) interfaceIntroductions.get(name);
1478      }
1479   }
1480
1481   /**
1482    * Register an introduction pointcut
1483    */

1484   public synchronized void addInterfaceIntroduction(InterfaceIntroduction pointcut)
1485   {
1486      removeInterfaceIntroduction(pointcut.getName());
1487      synchronized (interfaceIntroductions)
1488      {
1489         interfaceIntroductions.put(pointcut.getName(), pointcut);
1490      }
1491   }
1492
1493   /**
1494    * remove an introduction pointcut of a certain name
1495    */

1496   public void removeInterfaceIntroduction(String JavaDoc name)
1497   {
1498      synchronized (interfaceIntroductions)
1499      {
1500         InterfaceIntroduction pointcut = (InterfaceIntroduction) interfaceIntroductions.remove(name);
1501         if (pointcut == null) return;
1502         pointcut.clearAdvisors();
1503      }
1504   }
1505
1506   /**
1507    * Register an annotation introduction
1508    */

1509   public synchronized void addAnnotationIntroduction(AnnotationIntroduction pointcut)
1510   {
1511      String JavaDoc name = pointcut.getOriginalAnnotationExpr() + pointcut.getOriginalExpression();
1512      removeAnnotationIntroduction(pointcut);
1513      synchronized (annotationIntroductions)
1514      {
1515         annotationIntroductions.put(name, pointcut);
1516      }
1517   }
1518
1519   /**
1520    * remove an annotation pointcut
1521    */

1522   public void removeAnnotationIntroduction(AnnotationIntroduction pointcut)
1523   {
1524      String JavaDoc name = pointcut.getOriginalAnnotationExpr() + pointcut.getOriginalExpression();
1525      synchronized (annotationIntroductions)
1526      {
1527         annotationIntroductions.remove(name);
1528      }
1529   }
1530
1531   public List JavaDoc getAnnotationIntroductions()
1532   {
1533      synchronized (annotationIntroductions)
1534      {
1535         return new ArrayList JavaDoc(annotationIntroductions.values());
1536      }
1537   }
1538
1539   public synchronized void addDeclare(DeclareDef declare)
1540   {
1541      removeDeclare(declare.getName());
1542      synchronized (declares)
1543      {
1544         declares.put(declare.getName(), declare);
1545      }
1546      if (declare.isPointcut())
1547      {
1548         PointcutStats stats;
1549         stats = new PointcutStats(declare.getAst(), manager);
1550         stats.matches();
1551         updateStats(stats);
1552      }
1553   }
1554
1555   public void removeDeclare(String JavaDoc name)
1556   {
1557      synchronized (declares)
1558      {
1559         declares.remove(name);
1560      }
1561   }
1562
1563   public Iterator JavaDoc getDeclares()
1564   {
1565      return declares.values().iterator();
1566   }
1567
1568   protected void applyInterfaceIntroductions(Advisor advisor, Class JavaDoc clazz)
1569   {
1570      Map JavaDoc interfaceIntroductions = getInterfaceIntroductions();
1571      if (interfaceIntroductions != null && interfaceIntroductions.size() > 0)
1572      {
1573         Iterator JavaDoc it = interfaceIntroductions.values().iterator();
1574         while (it.hasNext())
1575         {
1576            InterfaceIntroduction pointcut = (InterfaceIntroduction) it.next();
1577            if (pointcut.matches(advisor, clazz))
1578            {
1579               pointcut.addAdvisor(advisor);
1580            }
1581         }
1582      }
1583   }
1584
1585   protected void applyInterfaceIntroductions(ClassAdvisor advisor, CtClass clazz) throws Exception JavaDoc
1586   {
1587      Map JavaDoc interfaceIntroductions = getInterfaceIntroductions();
1588      if (interfaceIntroductions != null && interfaceIntroductions.size() > 0)
1589      {
1590         Iterator JavaDoc it = interfaceIntroductions.values().iterator();
1591         while (it.hasNext())
1592         {
1593            InterfaceIntroduction pointcut = (InterfaceIntroduction) it.next();
1594            if (pointcut.matches(advisor, clazz))
1595            {
1596               pointcut.addAdvisor(advisor);
1597            }
1598         }
1599      }
1600   }
1601
1602
1603   /**
1604    * Register an annotation introduction
1605    */

1606   public synchronized void addAnnotationOverride(AnnotationIntroduction pointcut)
1607   {
1608      String JavaDoc name = pointcut.getOriginalAnnotationExpr() + pointcut.getOriginalExpression();
1609      synchronized (annotationOverrides)
1610      {
1611         annotationOverrides.put(name, pointcut);
1612      }
1613      updateAdvisorsForAddedAnnotationOverride(pointcut);
1614   }
1615
1616   public void updateAdvisorsForAddedAnnotationOverride(AnnotationIntroduction introduction)
1617   {
1618      synchronized (advisors)
1619      {
1620         //System.out.println("******* addBinding to possibly this many advisors: " + advisors.size());
1621
Iterator JavaDoc it = advisors.keySet().iterator();
1622         while (it.hasNext())
1623         {
1624            Advisor advisor = getAdvisorFromAdvisorsKeySetIterator(it);
1625            if (advisor == null) continue;
1626
1627            advisor.deployAnnotationOverride(introduction);
1628         }
1629      }
1630      synchronized (subscribedSubDomains)
1631      {
1632         copySubDomainsFromQueue(true);
1633         boolean newSubscribers = true;
1634         while (newSubscribers)
1635         {
1636            for (Iterator JavaDoc it = subscribedSubDomains.keySet().iterator() ; it.hasNext() ; )
1637            {
1638               Domain domain = (Domain)it.next();
1639               domain.updateAdvisorsForAddedAnnotationOverride(introduction);
1640            }
1641            newSubscribers = copySubDomainsFromQueue(false);
1642         }
1643      }
1644   }
1645
1646
1647   /**
1648    * remove an annotation pointcut
1649    */

1650   public void removeAnnotationOverride(AnnotationIntroduction pointcut)
1651   {
1652      String JavaDoc name = pointcut.getOriginalAnnotationExpr() + pointcut.getOriginalExpression();
1653      synchronized (annotationOverrides)
1654      {
1655         annotationOverrides.remove(name);
1656      }
1657   }
1658
1659   public List JavaDoc getAnnotationOverrides()
1660   {
1661      synchronized (annotationOverrides)
1662      {
1663         return new ArrayList JavaDoc(annotationOverrides.values());
1664      }
1665   }
1666
1667   public Object JavaDoc getPerVMAspect(AspectDefinition def)
1668   {
1669      return getPerVMAspect(def.getName());
1670   }
1671
1672   public Object JavaDoc getPerVMAspect(String JavaDoc def)
1673   {
1674      Object JavaDoc aspect = perVMAspects.get(def);
1675      if (aspect instanceof AspectDefinition)
1676      {
1677         synchronized (aspect)
1678         {
1679            return createPerVmAspect(def, (AspectDefinition)aspect, null);
1680         }
1681      }
1682      return aspect;
1683   }
1684   
1685   protected Object JavaDoc createPerVmAspect(String JavaDoc def, AspectDefinition adef, ClassLoader JavaDoc scopedClassLoader)
1686   {
1687      Object JavaDoc instance = null;
1688      synchronized (adef)
1689      {
1690         try
1691         {
1692            if (scopedClassLoader != null && adef.getFactory() instanceof AspectFactoryWithClassLoader)
1693            {
1694               //If a scoped classloader with no parent delegation redefines the class, we need to make sure that that class is pushed on the stack
1695
((AspectFactoryWithClassLoader)adef.getFactory()).pushScopedClassLoader(scopedClassLoader);
1696            }
1697            instance = adef.getFactory().createPerVM();
1698            perVMAspects.put(def, instance);
1699         }
1700         finally
1701         {
1702            if (scopedClassLoader != null && adef.getFactory() instanceof AspectFactoryWithClassLoader)
1703            {
1704               ((AspectFactoryWithClassLoader)adef.getFactory()).popScopedClassLoader();
1705            }
1706         }
1707      }
1708      return instance;
1709   }
1710
1711   public void addAspectDefinition(AspectDefinition def)
1712   {
1713      removeAspectDefinition(def.getName());
1714      if (def.getScope() == Scope.PER_VM)
1715      {
1716         perVMAspects.put(def.getName(), def);
1717      }
1718      aspectDefinitions.put(def.getName(), def);
1719   }
1720
1721   public void removeAspectDefinition(String JavaDoc name)
1722   {
1723      AspectDefinition def = (AspectDefinition) aspectDefinitions.remove(name);
1724      if (def != null)
1725      {
1726         def.undeploy();
1727         if (def.getScope() == Scope.PER_VM) perVMAspects.remove(def.getName());
1728      }
1729   }
1730
1731   public Map JavaDoc getAspectDefinitions()
1732   {
1733      return aspectDefinitions;
1734   }
1735
1736   public AspectDefinition getAspectDefinition(String JavaDoc name)
1737   {
1738      return (AspectDefinition) aspectDefinitions.get(name);
1739   }
1740
1741   public synchronized void addTypedef(Typedef def) throws Exception JavaDoc
1742   {
1743      removeTypedef(def.getName());
1744      synchronized (typedefs)
1745      {
1746         typedefs.put(def.getName(), def);
1747      }
1748   }
1749
1750   public void removeTypedef(String JavaDoc name)
1751   {
1752      synchronized (typedefs)
1753      {
1754         typedefs.remove(name);
1755      }
1756   }
1757
1758   public Typedef getTypedef(String JavaDoc name)
1759   {
1760      synchronized (typedefs)
1761      {
1762         return (Typedef) typedefs.get(name);
1763      }
1764   }
1765
1766   public Map JavaDoc getInterfaceIntroductions()
1767   {
1768      return interfaceIntroductions;
1769   }
1770
1771   public Map JavaDoc getTypedefs()
1772   {
1773      return typedefs;
1774   }
1775
1776   public Map JavaDoc getInterceptorStacks()
1777   {
1778      return interceptorStacks;
1779   }
1780
1781   public Map JavaDoc getClassMetaDataLoaders()
1782   {
1783      return classMetaDataLoaders;
1784   }
1785
1786   public Map JavaDoc getCflowStacks()
1787   {
1788      return cflowStacks;
1789   }
1790
1791   public Map JavaDoc getDynamicCFlows()
1792   {
1793      return dynamicCFlows;
1794   }
1795
1796   public Map JavaDoc getPerVMAspects()
1797   {
1798      return perVMAspects;
1799   }
1800
1801   public Map JavaDoc getClassMetaData()
1802   {
1803      return classMetaData;
1804   }
1805
1806   /**
1807    * Returns the dynamic aop strategy to be used.
1808    */

1809   public DynamicAOPStrategy getDynamicAOPStrategy()
1810   {
1811      return this.dynamicStrategy;
1812   }
1813
1814   /**
1815    * Sets the dynamic aop strategy to be used.
1816    * Should be called only before any class is transformed.
1817    * @param strategy the new dynamic aop strategy.
1818    */

1819   public void setDynamicAOPStrategy(DynamicAOPStrategy strategy)
1820   {
1821      // avoid users calling this method in run time
1822
if (this.transformationStarted)
1823      {
1824         throw new RuntimeException JavaDoc("Dynamic AOP Strategy Update not allowed in run time");
1825      }
1826      this.dynamicStrategy = strategy;
1827   }
1828
1829   /**
1830    * Removes an AdviceBinding without notifying dynamic aop strategy.
1831    * @param name the binding to be removed.
1832    */

1833   private AdviceBinding internalRemoveBinding(String JavaDoc name)
1834   {
1835      synchronized (bindings)
1836      {
1837         AdviceBinding binding = (AdviceBinding) bindings.remove(name);
1838         if (binding == null)
1839         {
1840            return null;
1841         }
1842         Pointcut pointcut = binding.getPointcut();
1843         this.removePointcut(pointcut.getName());
1844         return binding;
1845      }
1846   }
1847
1848   public void setBindings(LinkedHashMap JavaDoc bindings)
1849   {
1850      this.bindings.clear();
1851      this.bindings.putAll(bindings);
1852   }
1853
1854   public void addSubDomainPerClass(Class JavaDoc clazz, Domain domain)
1855   {
1856      synchronized (getSubDomainsPerClass())
1857      {
1858         getSubDomainsPerClass().put(clazz, new WeakReference JavaDoc(domain));
1859      }
1860   }
1861
1862   /**
1863    * Add subscriber to queue
1864    * @see AspectManager#copySubDomainsFromQueue(boolean)
1865    */

1866   public void subscribeSubDomain(Domain domain)
1867   {
1868      synchronized (subscribedSubDomains)
1869      {
1870         subscribedSubDomainsQueue.put(domain, "Contents do not matter");
1871      }
1872   }
1873
1874   public void unsubscribeSubDomain(Domain domain)
1875   {
1876      synchronized (subscribedSubDomains)
1877      {
1878         subscribedSubDomains.remove(domain);
1879      }
1880   }
1881
1882   private Advisor getAdvisorFromAdvisorsKeySetIterator(Iterator JavaDoc it)
1883   {
1884      Class JavaDoc clazz = (Class JavaDoc) it.next();
1885      if (classLoaderValidator != null && !classLoaderValidator.isValidClassLoader(clazz.getClassLoader()))
1886      {
1887         it.remove();
1888         return null;
1889      }
1890      WeakReference JavaDoc ref = (WeakReference JavaDoc) advisors.get(clazz);
1891      if (ref == null) return null;
1892      Advisor advisor = (Advisor) ref.get();
1893      if (advisor == null)
1894      {
1895         it.remove();
1896         return null;
1897      }
1898      return advisor;
1899   }
1900
1901   /**
1902    * When running in the microcontainer with aspects installed as beans, a ClassProxyContainer will be created per bean
1903    * to check if this bean needs interceptors, each container creates a sunscribed domain for matching. This subscribed
1904    * domain is added to a queue, which is checked when we need to iterate over the subscribed domains.
1905    */

1906   private boolean copySubDomainsFromQueue(boolean increment)
1907   {
1908      boolean copied = false;
1909      synchronized (subscribedSubDomains)
1910      {
1911         if (!increment && subscribedDomainQueueRef > 0) subscribedDomainQueueRef--;
1912
1913         if (subscribedDomainQueueRef == 0 && subscribedSubDomainsQueue.size() > 0){
1914            subscribedSubDomains.putAll(subscribedSubDomainsQueue);
1915            subscribedSubDomainsQueue.clear();
1916            copied = true;
1917         }
1918
1919         if (increment) subscribedDomainQueueRef++;
1920      }
1921      return copied;
1922   }
1923
1924/*
1925   public void dumpSubDomainsAndAdvisors(int indent)
1926   {
1927      indent(indent);
1928      System.out.println("Manager: " + this);
1929      indent++;
1930      indent(indent);
1931      System.out.println("<Advisors>");
1932      //indent(indent);
1933
1934      for (Iterator it = advisors.keySet().iterator() ; it.hasNext() ; )
1935      {
1936         Class clazz = (Class) it.next();
1937         Advisor advisor = null;
1938         WeakReference ref = (WeakReference) advisors.get(clazz);
1939         if (ref != null) advisor = (Advisor) ref.get();
1940         indent(indent);
1941         System.out.println(System.identityHashCode(advisor) + " " + advisor);
1942         indent(indent);
1943      }
1944      indent--;
1945      indent(indent);
1946      System.out.println("</Advisors>");
1947
1948      indent(indent);
1949      System.out.println("<Sub domains>");
1950      indent++;
1951      for (Iterator it = subscribedSubDomains.keySet().iterator(); it.hasNext() ; )
1952      {
1953         AspectManager manager = (AspectManager)it.next();
1954         manager.dumpSubDomainsAndAdvisors(indent);
1955      }
1956      indent--;
1957      indent(indent);
1958      System.out.println("</Sub domains>");
1959      indent--;
1960
1961   }
1962
1963   private void indent(int indent)
1964   {
1965      for (int i = 0 ; i < indent ; i++) System.out.print(" ");
1966   }
1967*/

1968}
1969
Popular Tags