KickJava   Java API By Example, From Geeks To Geeks.

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


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.reflect.Field JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import org.jboss.aop.advice.AdviceBinding;
31 import org.jboss.aop.advice.AspectDefinition;
32 import org.jboss.aop.advice.InterceptorFactory;
33 import org.jboss.aop.advice.GeneratedAdvisorInterceptor;
34 import org.jboss.aop.advice.PrecedenceSorter;
35 import org.jboss.aop.instrument.ConByConJoinPointGenerator;
36 import org.jboss.aop.instrument.ConByMethodJoinPointGenerator;
37 import org.jboss.aop.instrument.ConstructionJoinPointGenerator;
38 import org.jboss.aop.instrument.ConstructorJoinPointGenerator;
39 import org.jboss.aop.instrument.FieldJoinPointGenerator;
40 import org.jboss.aop.instrument.JoinPointGenerator;
41 import org.jboss.aop.instrument.MethodByConJoinPointGenerator;
42 import org.jboss.aop.instrument.MethodByMethodJoinPointGenerator;
43 import org.jboss.aop.instrument.MethodJoinPointGenerator;
44 import org.jboss.aop.joinpoint.Joinpoint;
45 import org.jboss.aop.joinpoint.MethodJoinpoint;
46 import org.jboss.aop.pointcut.PointcutMethodMatch;
47
48 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
49
50 import gnu.trove.TLongObjectHashMap;
51
52 /**
53  * Comment
54  *
55  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
56  * @version $Revision$
57  */

58 public class GeneratedClassAdvisor extends ClassAdvisor
59 {
60    public static final String JavaDoc ADD_METHOD_INFO = "addMethodInfo";
61    public static final String JavaDoc ADD_CONSTRUCTOR_INFO = "addConstructorInfo";
62    public static final String JavaDoc ADD_CONSTRUCTION_INFO = "addConstructionInfo";
63    public static final String JavaDoc ADD_FIELD_READ_INFO = "addFieldReadInfo";
64    public static final String JavaDoc ADD_FIELD_WRITE_INFO = "addFieldWriteInfo";
65    public static final String JavaDoc GET_PARENT_ADVISOR = "getParentAdvisor";
66
67    MethodInterceptors methodInfos = new MethodInterceptors(this);
68    ArrayList JavaDoc constructorInfos = new ArrayList JavaDoc();
69    ArrayList JavaDoc constructionInfos = new ArrayList JavaDoc();
70    ArrayList JavaDoc fieldReadInfos = new ArrayList JavaDoc();
71    ArrayList JavaDoc fieldWriteInfos = new ArrayList JavaDoc();
72    /** Super class methods that have been overrridden - these need special handling in this weaving mode */
73    ArrayList JavaDoc overriddenMethods = new ArrayList JavaDoc();
74
75    ConcurrentReaderHashMap constructorJoinPoinGenerators = new ConcurrentReaderHashMap();
76    ConcurrentReaderHashMap constructionJoinPoinGenerators = new ConcurrentReaderHashMap();
77    ConcurrentReaderHashMap fieldReadJoinPoinGenerators = new ConcurrentReaderHashMap();
78    ConcurrentReaderHashMap fieldWriteJoinPoinGenerators = new ConcurrentReaderHashMap();
79    ConcurrentReaderHashMap methodJoinPoinGenerators = new ConcurrentReaderHashMap();
80    ConcurrentReaderHashMap methodByConJoinPoinGenerators = new ConcurrentReaderHashMap();
81    ConcurrentReaderHashMap methodByMethodJoinPoinGenerators = new ConcurrentReaderHashMap();
82    ConcurrentReaderHashMap conByConJoinPoinGenerators = new ConcurrentReaderHashMap();
83    ConcurrentReaderHashMap conByMethodJoinPoinGenerators = new ConcurrentReaderHashMap();
84
85    boolean initialisedSuperClasses;
86
87    protected GeneratedClassAdvisor(String JavaDoc classname)
88    {
89       //Generated advisors will not pass in an aspectmanager
90
//This will be passed in via the initialise() method
91
super(classname, null);
92    }
93
94    protected void initialise(Class JavaDoc clazz, AspectManager manager)
95    {
96       super.setManager(manager);
97
98       //Make sure that we copy across per class and per joinpoint aspects from the old advisor if it exists
99
//Generated advisors get created when the class is first accessed (not loaded), meaning that there could be an exisiting advisor
100
//used for mathcing already when setting up the microcontainer.
101
Advisor existing = AspectManager.instance().getAnyAdvisorIfAdvised(clazz);
102       if (existing != null)
103       {
104          this.aspects = existing.aspects;
105          if (existing instanceof GeneratedClassAdvisor)
106          {
107             this.perClassJoinpointAspectDefinitions = ((GeneratedClassAdvisor)existing).perClassJoinpointAspectDefinitions;
108          }
109       }
110       
111       manager.initialiseClassAdvisor(clazz, this);
112    }
113    
114    protected void handleOverriddenMethods(AdviceBinding binding)
115    {
116       if (overriddenMethods != null && overriddenMethods.size() > 0)
117       {
118          for (Iterator JavaDoc it = overriddenMethods.iterator() ; it.hasNext() ; )
119          {
120             MethodInfo info = (MethodInfo)it.next();
121             Method JavaDoc method = info.getAdvisedMethod();
122             PointcutMethodMatch match = binding.getPointcut().matchesExecution(this, method);
123             
124             if (match != null && match.isMatch())
125             {
126                adviceBindings.add(binding);
127                if (AspectManager.verbose)
128                {
129                   System.err.println("method matched binding " + binding.getPointcut().getExpr() + " " + method.toString());
130                }
131                binding.addAdvisor(this);
132                pointcutResolved(info, binding, new MethodJoinpoint(method));
133             }
134          }
135       }
136    }
137
138    protected void resolveMethodPointcut(MethodInterceptors newMethodInterceptors, AdviceBinding binding)
139    {
140       super.resolveMethodPointcut(newMethodInterceptors, binding);
141       handleOverriddenMethods(binding);
142    }
143
144    
145    protected void addMethodInfo(MethodInfo mi)
146    {
147       MethodInfo old = methodInfos.getMethodInfo(mi.getHash());
148       if (old != null)
149       {
150          overriddenMethods.add(old);
151       }
152       methodInfos.put(mi.getHash(), mi);
153       //If we do dynamic invokes the method will need to be accessible via reflection if private/protected
154
SecurityActions.setAccessible(mi.getAdvisedMethod());
155    }
156
157    protected MethodInterceptors initializeMethodChain()
158    {
159       //We have all the advised methods here, need to get all the others here too
160

161       long[] keys = advisedMethods.keys();
162       for (int i = 0; i < keys.length; i++)
163       {
164          MethodMatchInfo matchInfo = methodInfos.getMatchInfo(keys[i]);
165
166          if (super.initialized && matchInfo != null)
167          {
168             matchInfo.clear();
169          }
170
171          if (matchInfo == null)
172          {
173             MethodInfo info = new MethodInfo();
174             Method JavaDoc amethod = (Method JavaDoc) advisedMethods.get(keys[i]);
175             info.setAdvisedMethod(amethod);
176             info.setUnadvisedMethod(amethod);
177             info.setHash(keys[i]);
178             info.setAdvisor(this);
179             methodInfos.put(keys[i], info);
180          }
181       }
182
183       return methodInfos;
184    }
185
186
187    protected void addConstructorInfo(ConstructorInfo ci)
188    {
189       constructorInfos.add(ci);
190       //If we do dynamic invokes the constructor will need to be accessible via reflection
191
SecurityActions.setAccessible(ci.getConstructor());
192    }
193
194    protected ArrayList JavaDoc initializeConstructorChain()
195    {
196       if (super.initialized)
197       {
198          for (Iterator JavaDoc it = constructorInfos.iterator() ; it.hasNext() ; )
199          {
200             ((ConstructorInfo)it.next()).clear();
201          }
202       }
203       return constructorInfos;
204    }
205
206    protected void addConstructionInfo(ConstructionInfo ci)
207    {
208       constructionInfos.add(ci);
209    }
210
211    protected ArrayList JavaDoc initializeConstructionChain()
212    {
213       if (super.initialized)
214       {
215          for (Iterator JavaDoc it = constructionInfos.iterator() ; it.hasNext() ; )
216          {
217             ((ConstructionInfo)it.next()).clear();
218          }
219       }
220       return constructionInfos;
221    }
222
223    protected void addFieldReadInfo(FieldInfo fi)
224    {
225       fieldReadInfos.add(fi);
226       //If we do dynamic invokes the field will need to be accessible via reflection
227
SecurityActions.setAccessible(fi.getAdvisedField());
228    }
229
230    protected ArrayList JavaDoc initializeFieldReadChain()
231    {
232       return mergeFieldInfos(fieldReadInfos);
233    }
234
235    protected void addFieldWriteInfo(FieldInfo fi)
236    {
237       fieldWriteInfos.add(fi);
238       //If we do dynamic invokes the field will need to be accessible via reflection
239
SecurityActions.setAccessible(fi.getAdvisedField());
240    }
241
242    protected ArrayList JavaDoc initializeFieldWriteChain()
243    {
244       return mergeFieldInfos(fieldWriteInfos);
245    }
246
247    /* Creates a full list of field infos for all fields, using the ones added by
248     * generated advisor for advised fields.
249     */

250    private ArrayList JavaDoc mergeFieldInfos(ArrayList JavaDoc advisedInfos)
251    {
252       ArrayList JavaDoc newInfos = new ArrayList JavaDoc(advisedFields.length);
253
254       FieldInfo nextFieldInfo = null;
255       Iterator JavaDoc it = advisedInfos.iterator();
256       if (it.hasNext())
257       {
258          nextFieldInfo = (FieldInfo)it.next();
259       }
260
261       for (int i = 0 ; i < advisedFields.length ; i++)
262       {
263          if (nextFieldInfo != null && nextFieldInfo.getIndex() == i)
264          {
265             if (super.initialized)
266             {
267                nextFieldInfo.clear();
268             }
269
270             newInfos.add(nextFieldInfo);
271             if (it.hasNext())
272             {
273                nextFieldInfo = (FieldInfo)it.next();
274             }
275             else
276             {
277                nextFieldInfo = null;
278             }
279          }
280          else
281          {
282             FieldInfo info = new FieldInfo();
283             info.setAdvisedField(advisedFields[i]);
284             info.setAdvisor(this);
285             info.setIndex(i);
286             newInfos.add(info);
287          }
288       }
289
290       return newInfos;
291    }
292
293    protected void finalizeMethodChain(MethodInterceptors newMethodInterceptors)
294    {
295       TLongObjectHashMap newMethodInfos = new TLongObjectHashMap();
296
297       long[] keys = newMethodInterceptors.keys();
298       for (int i = 0; i < keys.length; i++)
299       {
300          MethodMatchInfo matchInfo = newMethodInterceptors.getMatchInfo(keys[i]);
301          matchInfo.populateBindings();
302
303          MethodInfo info = matchInfo.getInfo();
304          newMethodInfos.put(keys[i], info);
305
306          MethodJoinPointGenerator generator = getJoinPointGenerator(info);
307          finalizeChainAndRebindJoinPoint(info, generator);
308       }
309       methodInterceptors = newMethodInfos;
310       
311       //Handle the overridden methods
312
if (overriddenMethods != null && overriddenMethods.size() > 0)
313       {
314          for (Iterator JavaDoc it = overriddenMethods.iterator() ; it.hasNext() ; )
315          {
316             MethodInfo info = (MethodInfo)it.next();
317
318             MethodJoinPointGenerator generator = getJoinPointGenerator(info);
319             finalizeChainAndRebindJoinPoint(info, generator);
320          }
321       }
322
323       
324    }
325
326    protected void finalizeFieldReadChain(ArrayList JavaDoc newFieldInfos)
327    {
328       for (int i = 0; i < newFieldInfos.size(); i++)
329       {
330          FieldInfo info = (FieldInfo)newFieldInfos.get(i);
331          FieldJoinPointGenerator generator = getJoinPointGenerator(info);
332          finalizeChainAndRebindJoinPoint(info, generator);
333       }
334    }
335
336    protected void finalizeFieldWriteChain(ArrayList JavaDoc newFieldInfos)
337    {
338       for (int i = 0; i < newFieldInfos.size(); i++)
339       {
340          FieldInfo info = (FieldInfo)newFieldInfos.get(i);
341          FieldJoinPointGenerator generator = getJoinPointGenerator(info);
342          finalizeChainAndRebindJoinPoint(info, generator);
343       }
344    }
345
346
347    protected void finalizeConstructorChain(ArrayList JavaDoc newConstructorInfos)
348    {
349       for (int i = 0; i < newConstructorInfos.size(); i++)
350       {
351          ConstructorInfo info = (ConstructorInfo) newConstructorInfos.get(i);
352          ConstructorJoinPointGenerator generator = getJoinPointGenerator(info);
353          finalizeChainAndRebindJoinPoint(info, generator);
354       }
355    }
356
357    protected void finalizeConstructionChain(ArrayList JavaDoc newConstructionInfos)
358    {
359       for (int i = 0; i < newConstructionInfos.size(); i++)
360       {
361          ConstructionInfo info = (ConstructionInfo) newConstructionInfos.get(i);
362          ConstructionJoinPointGenerator generator = getJoinPointGenerator(info);
363          finalizeChainAndRebindJoinPoint(info, generator);
364       }
365    }
366
367    protected void finalizeMethodCalledByMethodInterceptorChain(MethodByMethodInfo info)
368    {
369       MethodByMethodJoinPointGenerator generator = getJoinPointGenerator(info);
370       finalizeChainAndRebindJoinPoint(info, generator);
371    }
372
373    protected void finalizeConCalledByMethodInterceptorChain(ConByMethodInfo info)
374    {
375       ConByMethodJoinPointGenerator generator = getJoinPointGenerator(info);
376       finalizeChainAndRebindJoinPoint(info, generator);
377    }
378
379    protected void finalizeConCalledByConInterceptorChain(ConByConInfo info)
380    {
381       ConByConJoinPointGenerator generator = getJoinPointGenerator(info);
382       finalizeChainAndRebindJoinPoint(info, generator);
383    }
384
385
386    protected void finalizeMethodCalledByConInterceptorChain(MethodByConInfo info)
387    {
388       //An extra level of indirection since we distinguish between callers of method depending on
389
//where the called method is defined (sub/super interfaces)
390
ConcurrentReaderHashMap map = (ConcurrentReaderHashMap)methodByConJoinPoinGenerators.get(info.getJoinpoint());
391       if (map == null)
392       {
393          map = new ConcurrentReaderHashMap();
394          methodByConJoinPoinGenerators.put(info.getJoinpoint(), map);
395          map = (ConcurrentReaderHashMap)methodByConJoinPoinGenerators.get(info.getJoinpoint());
396       }
397
398       MethodByConJoinPointGenerator generator = getJoinPointGenerator(info);
399       finalizeChainAndRebindJoinPoint(info, generator);
400    }
401
402    protected MethodJoinPointGenerator getJoinPointGenerator(MethodInfo info)
403    {
404       MethodJoinPointGenerator generator = (MethodJoinPointGenerator)methodJoinPoinGenerators.get(info.getJoinpoint());
405       if (generator == null)
406       {
407          generator = new MethodJoinPointGenerator(this, info);
408          methodJoinPoinGenerators.put(info.getJoinpoint(), generator);
409       }
410       return generator;
411    }
412
413    protected FieldJoinPointGenerator getJoinPointGenerator(FieldInfo info)
414    {
415       if (info.isRead())
416       {
417          FieldJoinPointGenerator generator = (FieldJoinPointGenerator)fieldReadJoinPoinGenerators.get(info.getJoinpoint());
418          if (generator == null)
419          {
420             generator = new FieldJoinPointGenerator(this, info);
421             fieldReadJoinPoinGenerators.put(info.getJoinpoint(), generator);
422          }
423          return generator;
424       }
425       else
426       {
427          FieldJoinPointGenerator generator = (FieldJoinPointGenerator)fieldWriteJoinPoinGenerators.get(info.getJoinpoint());
428          if (generator == null)
429          {
430             generator = new FieldJoinPointGenerator(this, info);
431             fieldWriteJoinPoinGenerators.put(info.getJoinpoint(), generator);
432          }
433          return generator;
434       }
435    }
436
437    protected void test123()
438    {
439
440    }
441
442    protected ConstructorJoinPointGenerator getJoinPointGenerator(ConstructorInfo info)
443    {
444       ConstructorJoinPointGenerator generator = (ConstructorJoinPointGenerator)constructorJoinPoinGenerators.get(info.getJoinpoint());
445       if (generator == null)
446       {
447          generator = new ConstructorJoinPointGenerator(this, info);
448          constructorJoinPoinGenerators.put(info.getJoinpoint(), generator);
449       }
450       return generator;
451    }
452
453    protected ConstructionJoinPointGenerator getJoinPointGenerator(ConstructionInfo info)
454    {
455       ConstructionJoinPointGenerator generator = (ConstructionJoinPointGenerator)constructionJoinPoinGenerators.get(info.getJoinpoint());
456       if (generator == null)
457       {
458          generator = new ConstructionJoinPointGenerator(this, info);
459          constructionJoinPoinGenerators.put(info.getJoinpoint(), generator);
460       }
461       return generator;
462    }
463
464    protected MethodByMethodJoinPointGenerator getJoinPointGenerator(MethodByMethodInfo info)
465    {
466       //An extra level of indirection since we distinguish between callers of method depending on
467
//where the called method is defined (sub/super interfaces)
468
ConcurrentReaderHashMap map = (ConcurrentReaderHashMap)methodByMethodJoinPoinGenerators.get(info.getJoinpoint());
469       if (map == null)
470       {
471          map = new ConcurrentReaderHashMap();
472          methodByMethodJoinPoinGenerators.put(info.getJoinpoint(), map);
473          map = (ConcurrentReaderHashMap)methodByMethodJoinPoinGenerators.get(info.getJoinpoint());
474       }
475
476       MethodByMethodJoinPointGenerator generator = (MethodByMethodJoinPointGenerator)map.get(info.getCalledClass());
477       if (generator == null)
478       {
479          generator = new MethodByMethodJoinPointGenerator(this, info);
480          map.put(info.getCalledClass(), generator);
481          generator = (MethodByMethodJoinPointGenerator)map.get(info.getCalledClass());
482       }
483       return generator;
484    }
485
486    protected ConByMethodJoinPointGenerator getJoinPointGenerator(ConByMethodInfo info)
487    {
488       ConByMethodJoinPointGenerator generator = (ConByMethodJoinPointGenerator)conByMethodJoinPoinGenerators.get(info.getJoinpoint());
489       if (generator == null)
490       {
491          generator = new ConByMethodJoinPointGenerator(this, info);
492          conByMethodJoinPoinGenerators.put(info.getJoinpoint(), generator);
493       }
494       return generator;
495    }
496
497    protected ConByConJoinPointGenerator getJoinPointGenerator(ConByConInfo info)
498    {
499       ConByConJoinPointGenerator generator = (ConByConJoinPointGenerator)conByConJoinPoinGenerators.get(info.getJoinpoint());
500       if (generator == null)
501       {
502          generator = new ConByConJoinPointGenerator(this, info);
503          conByConJoinPoinGenerators.put(info.getJoinpoint(), generator);
504       }
505       return generator;
506    }
507
508    protected MethodByConJoinPointGenerator getJoinPointGenerator(MethodByConInfo info)
509    {
510       //An extra level of indirection since we distinguish between callers of method depending on
511
//where the called method is defined (sub/super interfaces)
512
ConcurrentReaderHashMap map = (ConcurrentReaderHashMap)methodByConJoinPoinGenerators.get(info.getJoinpoint());
513       if (map == null)
514       {
515          map = new ConcurrentReaderHashMap();
516          methodByConJoinPoinGenerators.put(info.getJoinpoint(), map);
517          map = (ConcurrentReaderHashMap)methodByConJoinPoinGenerators.get(info.getJoinpoint());
518       }
519
520       MethodByConJoinPointGenerator generator = (MethodByConJoinPointGenerator)map.get(info.getCalledClass());
521       if (generator == null)
522       {
523          generator = new MethodByConJoinPointGenerator(this, info);
524          map.put(info.getCalledClass(), generator);
525          generator = (MethodByConJoinPointGenerator)map.get(info.getCalledClass());
526       }
527       return generator;
528    }
529
530    /**
531     * Override default behaviour of when a pointcut is matched, populate the factories since this
532     * is what is needed for generating the optimized invocation method
533     */

534    protected void pointcutResolved(JoinPointInfo info, AdviceBinding binding, Joinpoint joinpoint)
535    {
536       ArrayList JavaDoc curr = info.getInterceptorChain();
537       if (binding.getCFlow() != null)
538       {
539          //TODO Handle CFlow
540
InterceptorFactory[] factories = binding.getInterceptorFactories();
541          for (int i = 0 ; i < factories.length ; i++)
542          {
543             curr.add(new GeneratedAdvisorInterceptor(factories[i], this, joinpoint, binding.getCFlowString(), binding.getCFlow()));
544          }
545       }
546       else
547       {
548          InterceptorFactory[] factories = binding.getInterceptorFactories();
549          for (int i = 0 ; i < factories.length ; i++)
550          {
551             curr.add(new GeneratedAdvisorInterceptor(factories[i], this, joinpoint));
552          }
553       }
554    }
555
556    private void finalizeChainAndRebindJoinPoint(JoinPointInfo info, JoinPointGenerator generator)
557    {
558       ArrayList JavaDoc list = info.getInterceptorChain();
559       GeneratedAdvisorInterceptor[] factories = null;
560       if (list.size() > 0)
561       {
562          factories = applyPrecedence((GeneratedAdvisorInterceptor[]) list.toArray(new GeneratedAdvisorInterceptor[list.size()]));
563       }
564       info.setInterceptors(factories);
565
566       generator.rebindJoinpoint(info);
567    }
568
569    public String JavaDoc toString()
570    {
571       Class JavaDoc clazz = this.getClass();
572       StringBuffer JavaDoc sb = new StringBuffer JavaDoc("CLASS: " + clazz.getName());
573
574       Field JavaDoc[] fields = clazz.getFields();
575       for (int i = 0 ; i < fields.length ; i++)
576       {
577          sb.append("\n\t" + fields[i]);
578       }
579       return sb.toString();
580    }
581
582    GeneratedAdvisorInterceptor[] applyPrecedence(GeneratedAdvisorInterceptor[] interceptors)
583    {
584       return PrecedenceSorter.applyPrecedence(interceptors, manager);
585    }
586
587    GeneratedClassAdvisor parent;
588    /**
589     * Generated InstanceAdvisors will set this
590     */

591    protected void setParentAdvisor(GeneratedClassAdvisor parent)
592    {
593       this.parent = parent;
594    }
595
596    /**
597     * Generated instance advisors will override this and return the parent class advisor
598     */

599    protected GeneratedClassAdvisor getParentAdvisor()
600    {
601       return parent;
602    }
603
604    /**
605     * If this is an instance advisor, will check with parent class advisor if the aspect
606     * is already registered. If so, we should use the one from the parent advisor
607     */

608    public Object JavaDoc getPerClassAspect(AspectDefinition def)
609    {
610       ClassAdvisor parentAdvisor = getParentAdvisor();
611
612       if (parentAdvisor != null)
613       {
614          Object JavaDoc aspect = parentAdvisor.getPerClassAspect(def);
615          if (aspect != null) return aspect;
616       }
617
618       return super.getPerClassAspect(def);
619    }
620
621    /**
622     * Generated ClassAdvisors and InstanceAdvisors will be different instances,
623     * so keep track of what per_class_joinpoint aspects have been added where
624     */

625    ConcurrentReaderHashMap perClassJoinpointAspectDefinitions = new ConcurrentReaderHashMap();
626
627    /**
628     * If this is an instance advisor, will check with parent class advisor if the aspect
629     * is already registered. If so, we should use the one from the parent advisor
630     */

631    public Object JavaDoc getPerClassJoinpointAspect(AspectDefinition def, Joinpoint joinpoint)
632    {
633       GeneratedClassAdvisor parentAdvisor = getParentAdvisor();
634
635       if (parentAdvisor != null)
636       {
637          Object JavaDoc aspect = parentAdvisor.getPerClassJoinpointAspect(def, joinpoint);
638          if (aspect != null)return aspect;
639       }
640
641       Map JavaDoc joinpoints = (Map JavaDoc) perClassJoinpointAspectDefinitions.get(def);
642       if (joinpoints != null)
643       {
644          return joinpoints.get(joinpoint);
645       }
646       return null;
647    }
648
649    public synchronized void addPerClassJoinpointAspect(AspectDefinition def, Joinpoint joinpoint)
650    {
651       Map JavaDoc joinpoints = (Map JavaDoc)perClassJoinpointAspectDefinitions.get(def);
652       if (joinpoints == null)
653       {
654          joinpoints = new ConcurrentReaderHashMap();
655          perClassJoinpointAspectDefinitions.put(def, joinpoints);
656       }
657
658       if (joinpoints.get(joinpoint) == null)
659       {
660          joinpoints.put(joinpoint, def.getFactory().createPerJoinpoint(this, joinpoint));
661       }
662    }
663
664    /**
665     * @see Advisor#chainOverridingForInheritedMethods()
666     */

667    public boolean chainOverridingForInheritedMethods()
668    {
669       return true;
670    }
671 }
672
Popular Tags