KickJava   Java API By Example, From Geeks To Geeks.

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


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 gnu.trove.TLongObjectHashMap;
25
26 import java.lang.ref.WeakReference JavaDoc;
27 import java.lang.reflect.Constructor JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.lang.reflect.InvocationTargetException JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import java.lang.reflect.Modifier JavaDoc;
32 import java.security.AccessController JavaDoc;
33 import java.security.PrivilegedActionException JavaDoc;
34 import java.security.PrivilegedExceptionAction JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.Map JavaDoc;
41
42 import org.jboss.aop.advice.AdviceBinding;
43 import org.jboss.aop.advice.AspectDefinition;
44 import org.jboss.aop.advice.Interceptor;
45 import org.jboss.aop.instrument.ConstructorExecutionTransformer;
46 import org.jboss.aop.instrument.FieldAccessTransformer;
47 import org.jboss.aop.instrument.MethodExecutionTransformer;
48 import org.jboss.aop.introduction.InterfaceIntroduction;
49 import org.jboss.aop.joinpoint.ConstructorCalledByConstructorInvocation;
50 import org.jboss.aop.joinpoint.ConstructorCalledByConstructorJoinpoint;
51 import org.jboss.aop.joinpoint.ConstructorCalledByMethodInvocation;
52 import org.jboss.aop.joinpoint.ConstructorCalledByMethodJoinpoint;
53 import org.jboss.aop.joinpoint.ConstructorInvocation;
54 import org.jboss.aop.joinpoint.FieldJoinpoint;
55 import org.jboss.aop.joinpoint.FieldReadInvocation;
56 import org.jboss.aop.joinpoint.FieldWriteInvocation;
57 import org.jboss.aop.joinpoint.Invocation;
58 import org.jboss.aop.joinpoint.MethodCalledByConstructorInvocation;
59 import org.jboss.aop.joinpoint.MethodCalledByConstructorJoinpoint;
60 import org.jboss.aop.joinpoint.MethodCalledByMethodInvocation;
61 import org.jboss.aop.joinpoint.MethodCalledByMethodJoinpoint;
62 import org.jboss.aop.joinpoint.MethodInvocation;
63 import org.jboss.aop.metadata.ClassMetaDataBinding;
64 import org.jboss.aop.metadata.ClassMetaDataLoader;
65 import org.jboss.aop.util.Advisable;
66 import org.jboss.aop.util.ConstructorComparator;
67 import org.jboss.aop.util.FieldComparator;
68 import org.jboss.aop.util.MethodHashing;
69 import org.jboss.util.NotImplementedException;
70
71 /**
72  * Advises a class and provides access to the class's aspect chain.
73  * Each advisable class has an associated <code>Advisor</code> instance.
74  * References methods using <code>int</code> IDs rather than the actual
75  * instances for
76  * optimal performance. Provides ability to invoke methods on an advised
77  * object without advice (see
78  * <code>Advisor.invokeWithoutAdvisement()</code>).
79  *
80  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
81  * @version $Revision: 56933 $
82  */

83 public class ClassAdvisor extends Advisor
84 {
85    /**
86     * Suffix added to unadvised methods.
87     */

88    public static final String JavaDoc NOT_TRANSFORMABLE_SUFFIX = "$aop";
89
90    protected TLongObjectHashMap unadvisedMethods = new TLongObjectHashMap();
91
92
93    // caller pointcut support for methods calling methods only
94
protected TLongObjectHashMap methodCalledByMethodBindings = new TLongObjectHashMap();
95    protected HashMap backrefMethodCalledByMethodBindings = new HashMap();
96    protected TLongObjectHashMap methodCalledByMethodInterceptors = new TLongObjectHashMap();
97
98    // constructor caller pointcut support for methods calling methods only
99
protected TLongObjectHashMap conCalledByMethodBindings = new TLongObjectHashMap();
100    protected HashMap backrefConCalledByMethodBindings = new HashMap();
101    protected TLongObjectHashMap conCalledByMethodInterceptors = new TLongObjectHashMap();
102
103    // caller pointcut support for constructors calling methods
104
protected HashMap[] methodCalledByConBindings;
105    protected HashMap[] methodCalledByConInterceptors;
106    protected HashMap backrefMethodCalledByConstructorBindings = new HashMap();
107
108    // caller pointcut support for constructors calling methods
109
protected HashMap[] conCalledByConBindings;
110    protected HashMap[] conCalledByConInterceptors;
111    protected HashMap backrefConCalledByConstructorBindings = new HashMap();
112
113    // Used by instrumentor to access separate interceptor chains for read and write access
114
/** @deprecated Use fieldReadInfos instead*/
115    private Interceptor[][] fieldReadInterceptors;
116    private FieldInfo[] fieldReadInfos;
117    /** @deprecated Use fieldWriteInfos instead */
118    private Interceptor[][] fieldWriteInterceptors;
119    private FieldInfo[] fieldWriteInfos;
120    
121    
122    protected Field JavaDoc[] advisedFields;
123    //PER_JOINPOINT aspects for static fields or PER_CLASS_JOINPOINT aspects
124
//all apply to fields, and we need this since the same aspect should be used for
125
//read and write
126
private HashMap fieldAspectsWithNoInstance = new HashMap();
127
128    protected boolean initialized = false;
129
130    public ClassAdvisor(String JavaDoc classname, AspectManager manager)
131    {
132       super(classname, manager);
133    }
134
135    public ClassAdvisor(Class JavaDoc clazz, AspectManager manager)
136    {
137       this(clazz.getName(), manager);
138       this.clazz = clazz;
139    }
140
141
142    /**
143     * This method is to support PER_JOINPOINT scoping of Aspects for static fields
144     * Fields are special in that a get and set do not create separate aspect instances.
145     *
146     * Also used to support PER_CLASS_JOINPOINT, since that behaves similarly to static fields
147     *
148     * @param joinpoint
149     * @param def
150     * @return
151     */

152    public Object JavaDoc getFieldAspect(FieldJoinpoint joinpoint, AspectDefinition def)
153    {
154       HashMap map = (HashMap)fieldAspectsWithNoInstance.get(def);
155       if (map == null)
156       {
157          synchronized (fieldAspectsWithNoInstance)
158          {
159             map = (HashMap)fieldAspectsWithNoInstance.get(def);
160             if (map == null)
161             {
162                map = new HashMap();
163                fieldAspectsWithNoInstance.put(def, map);
164             }
165          }
166       }
167       
168       Object JavaDoc aspect = map.get(joinpoint);
169       if (aspect == null)
170       {
171          synchronized (map)
172          {
173             aspect = map.get(joinpoint);
174             if (aspect == null)
175             {
176                aspect = def.getFactory().createPerJoinpoint(this, joinpoint);
177                map.put(joinpoint, aspect);
178             }
179          }
180       }
181       
182       return aspect;
183    }
184
185    public Field JavaDoc[] getAdvisedFields()
186    {
187       return advisedFields;
188    }
189
190    public TLongObjectHashMap getAdvisedMethods()
191    {
192       return advisedMethods;
193    }
194
195    protected TLongObjectHashMap getUnadvisedMethods()
196    {
197       return unadvisedMethods;
198    }
199
200    public Constructor JavaDoc[] getConstructors()
201    {
202       return constructors;
203    }
204
205    public TLongObjectHashMap getMethodCalledByMethodInterceptors()
206    {
207       return methodCalledByMethodInterceptors;
208    }
209
210    public HashMap[] getMethodCalledByConInterceptors()
211    {
212       return methodCalledByConInterceptors;
213    }
214
215    public HashMap[] getConCalledByConInterceptors()
216    {
217       return conCalledByConInterceptors;
218    }
219
220    public TLongObjectHashMap getConCalledByMethodInterceptors()
221    {
222       return conCalledByMethodInterceptors;
223    }
224
225    public TLongObjectHashMap getMethodCalledByMethodBindings()
226    {
227       return methodCalledByMethodBindings;
228    }
229
230    /** @deprecated use getFieldReadInfos instead */
231    public Interceptor[][] getFieldReadInterceptors()
232    {
233       throw new NotImplementedException("Use getFieldReadInfos");
234    }
235
236    public FieldInfo[] getFieldReadInfos()
237    {
238       return fieldReadInfos;
239    }
240
241    /** @deprecated use getFieldWriteInfos instead */
242    public Interceptor[][] getFieldWriteInterceptors()
243    {
244       throw new NotImplementedException("Use getFieldWriteInfos");
245    }
246
247    public FieldInfo[] getFieldWriteInfos()
248    {
249       return fieldWriteInfos;
250    }
251    
252    public TLongObjectHashMap getMethodInterceptors()
253    {
254       return methodInterceptors;
255    }
256
257    
258    /**
259     * Constructs a new helper.
260     */

261    public synchronized void attachClass(final Class JavaDoc clazz)
262    {
263       if (initialized) return;
264       try
265       {
266          //long start = System.currentTimeMillis();
267

268          final ClassAdvisor THIS = this;
269          final AspectManager theManager = manager;
270          //register class loader: necessary when clazz was precompiled through aopc
271
manager.registerClassLoader(clazz.getClassLoader());
272          AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
273          {
274             public Object JavaDoc run() throws Exception JavaDoc
275             {
276                theManager.attachMetaData(THIS, clazz);
277                interfaceIntroductions.clear();
278                // metadata should always come before creation of interceptor chain
279
// so that the interceptor factories have access to metadata.
280
// and so that metadata joinpoints can be checked
281
//
282

283                THIS.clazz = clazz;
284
285                // Also metadata needs to be applied before applyIntroductionPointcuts because
286
// an annotation may be triggered by XML metadata as well as
287
// after populateMixinMethods so that proper metadata is applied to added methods
288
rebindClassMetaData();
289                theManager.applyInterfaceIntroductions(THIS, clazz);
290                createFieldTable();
291                createMethodTables();
292                createConstructorTables();
293                populateMixinMethods();
294                // metadata should always come before creation of interceptor chain
295
// so that the interceptor factories have access to metadata.
296
// and so that metadata joinpoints can be checked
297
//
298
// Also metadata needs to be applied before applyIntroductionPointcuts because
299
// an annotation may be triggered by XML metadata as well as
300
// after populateMixinMethods so that proper metadata is applied to added methods
301
rebindClassMetaData();
302                createInterceptorChains();
303                initialized = true;
304                return null;
305             }
306          });
307          /*
308          System.out.println("******************");
309          System.out.println("attachClass: " + clazz.getName() + " took " + (System.currentTimeMillis() - start));
310          System.out.println("******************");
311          */

312       }
313       catch (PrivilegedActionException JavaDoc e)
314       {
315          throw new RuntimeException JavaDoc(e.getException());
316       }
317    }
318
319    /**
320     * Get method from clazz .If method not found,get the method
321     * from the clazz's parent.
322     */

323    static private Method JavaDoc getMethod(Class JavaDoc clazz, Method JavaDoc method) throws NoSuchMethodException JavaDoc
324    {
325
326       if ((clazz == null) || (clazz.equals(Object JavaDoc.class))) throw new NoSuchMethodException JavaDoc(method.getName());
327       try
328       {
329          String JavaDoc wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), method.getName());
330          return clazz.getMethod(wrappedName, method.getParameterTypes());
331       }
332       catch (NoSuchMethodException JavaDoc e)
333       {
334          return getMethod(clazz.getSuperclass(), method);
335       }
336    }
337
338    /**
339     * Get a constructor's index in the class. Returns -1 if not there
340     */

341    public int getConstructorIndex(Constructor JavaDoc constructor)
342    {
343       for (int i = 0; i < constructors.length; i++)
344       {
345          if (constructor.equals(constructors[i]))
346          {
347             return i;
348          }
349       }
350
351       return -1;
352    }
353
354    /**
355     * Get a field's index in the class. Returns -1 if not there
356     */

357    public int getFieldIndex(Field JavaDoc field)
358    {
359       for (int i = 0; i < advisedFields.length; i++)
360       {
361          if (field.equals(advisedFields[i]))
362          {
363             return i;
364          }
365       }
366
367       return -1;
368    }
369
370
371    /**
372     * Put mixin methods from mixin class into unadvisedMethods map so that
373     * they can be correctly invoked upon.
374     */

375    protected void populateMixinMethods() throws Exception JavaDoc
376    {
377       ArrayList JavaDoc pointcuts = getInterfaceIntroductions();
378       Iterator JavaDoc it = pointcuts.iterator();
379       while (it.hasNext())
380       {
381          InterfaceIntroduction pointcut = (InterfaceIntroduction) it.next();
382          ArrayList JavaDoc mixins = pointcut.getMixins();
383          for (int i = 0; i < mixins.size(); i++)
384          {
385             InterfaceIntroduction.Mixin mixin = (InterfaceIntroduction.Mixin) mixins.get(i);
386             Thread.currentThread().getContextClassLoader().loadClass(mixin.getClassName());
387             String JavaDoc[] interfaces = mixin.getInterfaces();
388             for (int j = 0; j < interfaces.length; j++)
389             {
390                Class JavaDoc intf = Thread.currentThread().getContextClassLoader().loadClass(interfaces[j]);
391                Method JavaDoc[] methods = intf.getMethods();
392                for (int k = 0; k < methods.length; k++)
393                {
394                   //Put wrapped method in the class itself into the unadvisedMethods map
395
// String wrappedName = ClassAdvisor.notAdvisedMethodName(clazz.getName(), methods[k].getName());
396
// Method method = clazz.getMethod(wrappedName, methods[k].getParameterTypes());
397
Method JavaDoc method = getMethod(clazz, methods[k]);
398                   long hash = MethodHashing.methodHash(method);
399                   unadvisedMethods.put(hash, method);
400                }
401             }
402          }
403       }
404    }
405
406
407    public synchronized void removeAdviceBinding(AdviceBinding binding)
408    {
409       removeCallerPointcut(binding); // if binding is a caller remove references to it
410
super.removeAdviceBinding(binding);
411    }
412
413    public synchronized void removeAdviceBindings(ArrayList JavaDoc bindings)
414    {
415       for (int i = 0; i < bindings.size(); i++)
416       {
417          AdviceBinding binding = (AdviceBinding) bindings.get(i);
418          removeCallerPointcut(binding);
419       }
420       adviceBindings.removeAll(bindings);
421       rebuildInterceptors();
422       doesHaveAspects = adviceBindings.size() > 0;
423    }
424
425    private void resolveFieldPointcut(ArrayList JavaDoc newFieldInfos, AdviceBinding binding, boolean write)
426    {
427       for (int i = 0; i < advisedFields.length; i++)
428       {
429          Field JavaDoc field = advisedFields[i];
430          
431          if ((!write && binding.getPointcut().matchesGet(this, field))
432          || (write && binding.getPointcut().matchesSet(this, field)))
433          {
434             if (AspectManager.verbose) System.err.println("field matched binding " + binding.getName());
435             adviceBindings.add(binding);
436             binding.addAdvisor(this);
437             FieldInfo info = (FieldInfo)newFieldInfos.get(i);
438             pointcutResolved(info, binding, new FieldJoinpoint(field));
439          }
440       }
441    }
442
443    protected MethodInterceptors initializeMethodChain()
444    {
445       MethodInterceptors newInterceptors = new MethodInterceptors(this);
446       long[] keys = advisedMethods.keys();
447       for (int i = 0; i < keys.length; i++)
448       {
449          MethodInfo info = new MethodInfo();
450          Method JavaDoc amethod = (Method JavaDoc) advisedMethods.get(keys[i]);
451          info.setAdvisedMethod(amethod);
452          Method JavaDoc umethod = (Method JavaDoc) unadvisedMethods.get(keys[i]);
453
454          if (umethod == null) umethod = amethod;
455          info.setUnadvisedMethod(umethod);
456          info.setHash(keys[i]);
457          info.setAdvisor(this);
458          newInterceptors.put(keys[i], info);
459          try
460          {
461             Field JavaDoc infoField = clazz.getDeclaredField(MethodExecutionTransformer.getMethodInfoFieldName(amethod.getName(), keys[i]));
462             infoField.setAccessible(true);
463             infoField.set(null, new WeakReference JavaDoc(info));
464          }
465          catch (NoSuchFieldException JavaDoc e)
466          {
467             // ignore, method may not be advised.
468
}
469          catch (IllegalAccessException JavaDoc e)
470          {
471             throw new RuntimeException JavaDoc(e); //To change body of catch statement use Options | File Templates.
472
}
473       }
474       return newInterceptors;
475    }
476
477    protected ArrayList JavaDoc initializeFieldReadChain()
478    {
479       ArrayList JavaDoc chain = new ArrayList JavaDoc(advisedFields.length);
480       for (int i = 0; i < advisedFields.length; i++)
481       {
482          FieldInfo info = new FieldInfo();
483          info.setAdvisedField(advisedFields[i]);
484          info.setAdvisor(this);
485          info.setIndex(i);
486
487          try
488          {
489             info.setWrapper(clazz.getDeclaredMethod(
490                   FieldAccessTransformer.fieldRead(advisedFields[i].getName()),
491                   new Class JavaDoc[] {Object JavaDoc.class}));
492          }
493          catch (NoSuchMethodException JavaDoc e)
494          {
495             //Just means not advised
496
}
497
498          chain.add(info);
499          
500          try
501          {
502             Field JavaDoc infoField = clazz.getDeclaredField(FieldAccessTransformer.getFieldReadInfoFieldName(advisedFields[i].getName()));
503             infoField.setAccessible(true);
504             infoField.set(null, new WeakReference JavaDoc(info));
505          }
506          catch (NoSuchFieldException JavaDoc e)
507          {
508             // ignore, method may not be advised.
509
}
510          catch (IllegalAccessException JavaDoc e)
511          {
512             throw new RuntimeException JavaDoc(e);
513          }
514          
515       }
516       return chain;
517    }
518
519    protected ArrayList JavaDoc initializeFieldWriteChain()
520    {
521       ArrayList JavaDoc chain = new ArrayList JavaDoc(advisedFields.length);
522       for (int i = 0; i < advisedFields.length; i++)
523       {
524          FieldInfo info = new FieldInfo();
525          info.setAdvisedField(advisedFields[i]);
526          info.setAdvisor(this);
527          info.setIndex(i);
528
529          try
530          {
531             info.setWrapper(clazz.getDeclaredMethod(
532                   FieldAccessTransformer.fieldWrite(advisedFields[i].getName()),
533                   new Class JavaDoc[] {Object JavaDoc.class, advisedFields[i].getType()}));
534          }
535          catch (NoSuchMethodException JavaDoc e)
536          {
537             //Just means not advised
538
}
539
540          chain.add(info);
541          
542          try
543          {
544             Field JavaDoc infoField = clazz.getDeclaredField(FieldAccessTransformer.getFieldWriteInfoFieldName(advisedFields[i].getName()));
545             infoField.setAccessible(true);
546             infoField.set(null, new WeakReference JavaDoc(info));
547          }
548          catch (NoSuchFieldException JavaDoc e)
549          {
550             // ignore, method may not be advised.
551
}
552          catch (IllegalAccessException JavaDoc e)
553          {
554             throw new RuntimeException JavaDoc(e);
555          }
556          
557       }
558       return chain;
559    }
560
561    protected void finalizeFieldReadChain(ArrayList JavaDoc newFieldInfos)
562    {
563       for (int i = 0; i < newFieldInfos.size(); i++)
564       {
565          FieldInfo info = (FieldInfo)newFieldInfos.get(i);
566          ArrayList JavaDoc list = info.getInterceptorChain();
567          Interceptor[] interceptors = null;
568          if (list.size() > 0)
569          {
570           interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()]));
571          }
572          info.setInterceptors(interceptors);
573       }
574    }
575
576    protected void finalizeFieldWriteChain(ArrayList JavaDoc newFieldInfos)
577    {
578       for (int i = 0; i < newFieldInfos.size(); i++)
579       {
580          FieldInfo info = (FieldInfo)newFieldInfos.get(i);
581          ArrayList JavaDoc list = info.getInterceptorChain();
582          Interceptor[] interceptors = null;
583          if (list.size() > 0)
584          {
585           interceptors = applyPrecedence((Interceptor[]) list.toArray(new Interceptor[list.size()]));
586          }
587          info.setInterceptors(interceptors);
588       }
589    }
590
591    private void createInterceptorChains() throws Exception JavaDoc
592    {
593       MethodInterceptors newMethodInfos = initializeMethodChain();
594       ArrayList JavaDoc newFieldReadInfos = initializeFieldReadChain();
595       ArrayList JavaDoc newFieldWriteInfos = initializeFieldWriteChain();
596       ArrayList JavaDoc newConstructorInfos = initializeConstructorChain();
597       ArrayList JavaDoc newConstructionInfos = initializeConstructionChain();
598       
599       synchronized (manager.getBindings())
600       {
601          Iterator JavaDoc it = manager.getBindings().values().iterator();
602          while (it.hasNext())
603          {
604             AdviceBinding binding = (AdviceBinding) it.next();
605             if (AspectManager.verbose) System.out.println("iterate binding " + binding.getName() + " " + binding.getPointcut().getExpr());
606             resolveMethodPointcut(newMethodInfos, binding);
607             resolveFieldPointcut(newFieldReadInfos, binding, false);
608             resolveFieldPointcut(newFieldWriteInfos, binding, true);
609             resolveConstructorPointcut(newConstructorInfos, binding);
610             resolveConstructionPointcut(newConstructionInfos, binding);
611          }
612       }
613       finalizeMethodChain(newMethodInfos);
614       finalizeFieldReadChain(newFieldReadInfos);
615       finalizeFieldWriteChain(newFieldWriteInfos);
616       finalizeConstructorChain(newConstructorInfos);
617       finalizeConstructionChain(newConstructionInfos);
618       fieldReadInfos = (FieldInfo[]) newFieldReadInfos.toArray(new FieldInfo[newFieldReadInfos.size()]);
619       fieldWriteInfos = (FieldInfo[]) newFieldWriteInfos.toArray(new FieldInfo[newFieldWriteInfos.size()]);
620       constructorInfos = (ConstructorInfo[]) newConstructorInfos.toArray(new ConstructorInfo[newConstructorInfos.size()]);
621       constructionInfos = (ConstructionInfo[]) newConstructionInfos.toArray(new ConstructionInfo[newConstructionInfos.size()]);
622       
623       populateInterceptorsFromInfos();
624       
625       doesHaveAspects = adviceBindings.size() > 0;
626       // Notify observer about this change
627
if (this.interceptorChainObserver != null)
628       {
629          this.interceptorChainObserver.interceptorChainsUpdated(fieldReadInterceptors, fieldWriteInterceptors,
630                constructorInterceptors, methodInterceptors);
631       }
632    }
633    
634    private MethodByMethodInfo initializeCallerInterceptorsMap(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash, Method JavaDoc callingMethod, Method JavaDoc calledMethod) throws Exception JavaDoc
635    {
636       HashMap calledClassesMap = (HashMap) methodCalledByMethodInterceptors.get(callingMethodHash);
637       if (calledClassesMap == null)
638       {
639          calledClassesMap = new HashMap();
640          methodCalledByMethodInterceptors.put(callingMethodHash, calledClassesMap);
641       }
642       TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
643       if (calledMethodsMap == null)
644       {
645          calledMethodsMap = new TLongObjectHashMap();
646          calledClassesMap.put(calledClass, calledMethodsMap);
647       }
648       //The standard MethodCalledByXXXXInvocation class calls by reflection and needs access
649
calledMethod.setAccessible(true);
650       
651       Class JavaDoc calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
652       MethodByMethodInfo info = new MethodByMethodInfo(this, calledClazz, calledMethod, callingMethodHash, calledMethodHash, null);
653       calledMethodsMap.put(calledMethodHash, info);
654       return info;
655    }
656
657    private ConByMethodInfo initializeConCalledByMethodInterceptorsMap(long callingMethodHash, String JavaDoc calledClass, long calledConHash, Constructor JavaDoc calledCon) throws Exception JavaDoc
658    {
659       HashMap calledClassesMap = (HashMap) conCalledByMethodInterceptors.get(callingMethodHash);
660       if (calledClassesMap == null)
661       {
662          calledClassesMap = new HashMap();
663          conCalledByMethodInterceptors.put(callingMethodHash, calledClassesMap);
664       }
665       TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
666       if (calledMethodsMap == null)
667       {
668          calledMethodsMap = new TLongObjectHashMap();
669          calledClassesMap.put(calledClass, calledMethodsMap);
670       }
671
672       ConByMethodInfo info = createConByMethodInfo(calledClass, callingMethodHash, calledCon, calledConHash);
673       calledMethodsMap.put(calledConHash, info);
674       return info;
675    }
676
677    private ConByMethodInfo createConByMethodInfo(String JavaDoc calledClass, long callingMethodHash, Constructor JavaDoc calledCon, long calledConHash) throws Exception JavaDoc
678    {
679       //The standard ConstructorCalledByXXXXInvocation class calls by reflection and needs access
680
calledCon.setAccessible(true);
681
682       Class JavaDoc calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
683       try
684       {
685          int index = calledClass.lastIndexOf('.');
686          String JavaDoc baseClassName = calledClass.substring(index + 1);
687          Method JavaDoc wrapper = calledCon.getDeclaringClass().getDeclaredMethod(ConstructorExecutionTransformer.constructorFactory(baseClassName), calledCon.getParameterTypes());
688          return new ConByMethodInfo(this, calledClazz, callingMethodHash, calledCon, calledConHash, wrapper, null);
689       }
690       catch (NoSuchMethodException JavaDoc e)
691       {
692          return new ConByMethodInfo(this, calledClazz, callingMethodHash, calledCon, calledConHash, null, null);
693       }
694    }
695
696    private MethodByConInfo initializeConstructorCallerInterceptorsMap(int callingIndex, String JavaDoc calledClass, long calledMethodHash, Method JavaDoc calledMethod) throws Exception JavaDoc
697    {
698       HashMap calledClassesMap = methodCalledByConInterceptors[callingIndex];
699       if (calledClassesMap == null)
700       {
701          calledClassesMap = new HashMap();
702          methodCalledByConInterceptors[callingIndex] = calledClassesMap;
703       }
704       TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
705       if (calledMethodsMap == null)
706       {
707          calledMethodsMap = new TLongObjectHashMap();
708          calledClassesMap.put(calledClass, calledMethodsMap);
709       }
710
711       //The standard MethodCalledByXXXXInvocation class calls by reflection and needs access
712
calledMethod.setAccessible(true);
713       Class JavaDoc calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
714       MethodByConInfo info = new MethodByConInfo(this, calledClazz, callingIndex, calledMethod, calledMethodHash, null);
715       calledMethodsMap.put(calledMethodHash, info);
716       return info;
717    }
718
719    private ConByConInfo initializeConCalledByConInterceptorsMap(int callingIndex, String JavaDoc calledClass, long calledConHash, Constructor JavaDoc calledCon) throws Exception JavaDoc
720    {
721       HashMap calledClassesMap = conCalledByConInterceptors[callingIndex];
722       if (calledClassesMap == null)
723       {
724          calledClassesMap = new HashMap();
725          conCalledByConInterceptors[callingIndex] = calledClassesMap;
726       }
727       TLongObjectHashMap calledMethodsMap = (TLongObjectHashMap) calledClassesMap.get(calledClass);
728       if (calledMethodsMap == null)
729       {
730          calledMethodsMap = new TLongObjectHashMap();
731          calledClassesMap.put(calledClass, calledMethodsMap);
732       }
733       ConByConInfo info = createConByConInfo(callingIndex, calledClass, calledCon, calledConHash);
734       calledMethodsMap.put(calledConHash, info);
735       return info;
736    }
737
738
739    private ConByConInfo createConByConInfo(int callingIndex, String JavaDoc calledClass, Constructor JavaDoc calledCon, long calledConHash) throws Exception JavaDoc
740    {
741       //The standard ConstructorCalledByXXXXInvocation class calls by reflection and needs access
742
calledCon.setAccessible(true);
743       Class JavaDoc calledClazz = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
744
745       try
746       {
747          int index = calledClass.lastIndexOf('.');
748          String JavaDoc baseClassName = calledClass.substring(index + 1);
749          Method JavaDoc wrapper = calledCon.getDeclaringClass().getDeclaredMethod(ConstructorExecutionTransformer.constructorFactory(baseClassName), calledCon.getParameterTypes());
750          return new ConByConInfo(this, calledClazz, callingIndex, calledCon, calledConHash, wrapper, null);
751       }
752       catch (NoSuchMethodException JavaDoc e)
753       {
754          return new ConByConInfo(this, calledClazz, callingIndex, calledCon, calledConHash, null, null);
755       }
756    }
757    
758    protected void rebuildCallerInterceptors() throws Exception JavaDoc
759    {
760       long[] callingKeys = methodCalledByMethodInterceptors.keys();
761       for (int i = 0; i < callingKeys.length; i++)
762       {
763          long callingHash = callingKeys[i];
764          HashMap calledClasses = (HashMap) methodCalledByMethodInterceptors.get(callingHash);
765          Iterator JavaDoc classesIterator = calledClasses.entrySet().iterator();
766          while (classesIterator.hasNext())
767          {
768             Map.Entry entry = (Map.Entry) classesIterator.next();
769             String JavaDoc cname = (String JavaDoc) entry.getKey();
770             TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
771             long[] calledKeys = calledMethods.keys();
772             for (int j = 0; j < calledKeys.length; j++)
773             {
774                long calledHash = calledKeys[j];
775                ArrayList JavaDoc bindings = getCallerBindings(callingHash, cname, calledHash);
776                Method JavaDoc calling = MethodHashing.findMethodByHash(clazz, callingHash);
777                bindCallerInterceptorChain(bindings, callingHash, cname, calledHash, calling);
778             }
779          }
780       }
781       for (int i = 0; i < methodCalledByConInterceptors.length; i++)
782       {
783          HashMap calledClasses = methodCalledByConInterceptors[i];
784          if (calledClasses == null) continue;
785          Iterator JavaDoc classesIterator = calledClasses.entrySet().iterator();
786          while (classesIterator.hasNext())
787          {
788             Map.Entry entry = (Map.Entry) classesIterator.next();
789             String JavaDoc cname = (String JavaDoc) entry.getKey();
790             TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
791             long[] calledKeys = calledMethods.keys();
792             for (int j = 0; j < calledKeys.length; j++)
793             {
794                long calledHash = calledKeys[j];
795                ArrayList JavaDoc bindings = getConstructorCallerBindings(i, cname, calledHash);
796                bindConstructorCallerInterceptorChain(bindings, i, cname, calledHash);
797             }
798          }
799       }
800       callingKeys = conCalledByMethodInterceptors.keys();
801       for (int i = 0; i < callingKeys.length; i++)
802       {
803          long callingHash = callingKeys[i];
804          HashMap calledClasses = (HashMap) conCalledByMethodInterceptors.get(callingHash);
805          Iterator JavaDoc classesIterator = calledClasses.entrySet().iterator();
806          while (classesIterator.hasNext())
807          {
808             Map.Entry entry = (Map.Entry) classesIterator.next();
809             String JavaDoc cname = (String JavaDoc) entry.getKey();
810             TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
811             long[] calledKeys = calledMethods.keys();
812             for (int j = 0; j < calledKeys.length; j++)
813             {
814                long calledHash = calledKeys[j];
815                ArrayList JavaDoc bindings = getConCalledByMethodBindings(callingHash, cname, calledHash);
816                bindConCalledByMethodInterceptorChain(bindings, callingHash, cname, calledHash);
817             }
818          }
819       }
820       for (int i = 0; i < conCalledByConInterceptors.length; i++)
821       {
822          HashMap calledClasses = conCalledByConInterceptors[i];
823          if (calledClasses == null) continue;
824          Iterator JavaDoc classesIterator = calledClasses.entrySet().iterator();
825          while (classesIterator.hasNext())
826          {
827             Map.Entry entry = (Map.Entry) classesIterator.next();
828             String JavaDoc cname = (String JavaDoc) entry.getKey();
829             TLongObjectHashMap calledMethods = (TLongObjectHashMap) entry.getValue();
830             long[] calledKeys = calledMethods.keys();
831             for (int j = 0; j < calledKeys.length; j++)
832             {
833                long calledHash = calledKeys[j];
834                ArrayList JavaDoc bindings = getConCalledByConBindings(i, cname, calledHash);
835                bindConCalledByConInterceptorChain(bindings, i, cname, calledHash);
836             }
837          }
838       }
839    }
840
841    private ArrayList JavaDoc getCallerBindings(long callingHash, String JavaDoc cname, long calledHash)
842    {
843       HashMap calledClasses = (HashMap) methodCalledByMethodBindings.get(callingHash);
844       TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(cname);
845       return (ArrayList JavaDoc) calledMethods.get(calledHash);
846    }
847
848    private ArrayList JavaDoc getConCalledByMethodBindings(long callingHash, String JavaDoc cname, long calledHash)
849    {
850       HashMap calledClasses = (HashMap) conCalledByMethodBindings.get(callingHash);
851       TLongObjectHashMap calledCons = (TLongObjectHashMap) calledClasses.get(cname);
852       return (ArrayList JavaDoc) calledCons.get(calledHash);
853    }
854
855    private ArrayList JavaDoc getConstructorCallerBindings(int callingIndex, String JavaDoc cname, long calledHash)
856    {
857       HashMap calledClasses = methodCalledByConBindings[callingIndex];
858       TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(cname);
859       return (ArrayList JavaDoc) calledMethods.get(calledHash);
860    }
861
862    private ArrayList JavaDoc getConCalledByConBindings(int callingIndex, String JavaDoc cname, long calledHash)
863    {
864       HashMap calledClasses = conCalledByConBindings[callingIndex];
865       TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(cname);
866       return (ArrayList JavaDoc) calledMethods.get(calledHash);
867    }
868
869    private void bindCallerInterceptorChain(ArrayList JavaDoc bindings, long callingHash, String JavaDoc cname, long calledHash, Method JavaDoc calling)
870    {
871       MethodByMethodInfo info = getCallerMethodInfo(callingHash, cname, calledHash);
872       info.clear();
873       Iterator JavaDoc it = bindings.iterator();
874       while (it.hasNext())
875       {
876          AdviceBinding binding = (AdviceBinding) it.next();
877          pointcutResolved(info, binding, new MethodCalledByMethodJoinpoint(info.getCallingMethod(), info.getMethod()));
878       }
879       finalizeMethodCalledByMethodInterceptorChain(info);
880    }
881    
882    protected void finalizeMethodCalledByMethodInterceptorChain(MethodByMethodInfo info)
883    {
884       ArrayList JavaDoc list = info.getInterceptorChain();
885       Interceptor[] interceptors = null;
886       if (list.size() > 0)
887       {
888          interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
889       }
890       info.setInterceptors(interceptors);
891    }
892
893    private void bindConCalledByMethodInterceptorChain(ArrayList JavaDoc bindings, long callingHash, String JavaDoc cname, long calledHash) throws Exception JavaDoc
894    {
895       ConByMethodInfo info = getConCalledByMethod(callingHash, cname, calledHash);
896       info.clear();
897       Iterator JavaDoc it = bindings.iterator();
898       while (it.hasNext())
899       {
900          AdviceBinding binding = (AdviceBinding) it.next();
901          pointcutResolved(info, binding, new ConstructorCalledByMethodJoinpoint(info.getCallingMethod(), info.getConstructor()));
902       }
903       finalizeConCalledByMethodInterceptorChain(info);
904    }
905    
906    protected void finalizeConCalledByMethodInterceptorChain(ConByMethodInfo info)
907    {
908       ArrayList JavaDoc list = info.getInterceptorChain();
909       Interceptor[] interceptors = null;
910       if (list.size() > 0)
911       {
912          interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
913       }
914       info.setInterceptors(interceptors);
915    }
916
917    private void bindConCalledByConInterceptorChain(ArrayList JavaDoc bindings, int callingIndex, String JavaDoc cname, long calledHash)
918    {
919       ConByConInfo info = getConCalledByCon(callingIndex, cname, calledHash);
920       info.clear();
921       Iterator JavaDoc it = bindings.iterator();
922       while (it.hasNext())
923       {
924          AdviceBinding binding = (AdviceBinding) it.next();
925          pointcutResolved(info, binding, new ConstructorCalledByConstructorJoinpoint(info.getCalling(), info.getConstructor()));
926       }
927       finalizeConCalledByConInterceptorChain(info);
928    }
929
930    protected void finalizeConCalledByConInterceptorChain(ConByConInfo info)
931    {
932       ArrayList JavaDoc list = info.getInterceptorChain();
933       Interceptor[] interceptors = null;
934       if (list.size() > 0)
935       {
936          interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
937       }
938       info.setInterceptors(interceptors);
939    }
940
941    private void bindConstructorCallerInterceptorChain(ArrayList JavaDoc bindings, int callingIndex, String JavaDoc cname, long calledHash)
942    {
943       MethodByConInfo info = getConstructorCallerMethodInfo(callingIndex, cname, calledHash);
944       info.clear();
945       Iterator JavaDoc it = bindings.iterator();
946       while (it.hasNext())
947       {
948          AdviceBinding binding = (AdviceBinding) it.next();
949          pointcutResolved(info, binding, new MethodCalledByConstructorJoinpoint(info.getCalling(), info.getMethod()));
950       }
951       finalizeMethodCalledByConInterceptorChain(info);
952    }
953    
954    protected void finalizeMethodCalledByConInterceptorChain(MethodByConInfo info)
955    {
956       ArrayList JavaDoc list = info.getInterceptorChain();
957       Interceptor[] interceptors = null;
958       if (list.size() > 0)
959       {
960          interceptors = (Interceptor[]) list.toArray(new Interceptor[list.size()]);
961       }
962       info.setInterceptors(interceptors);
963    }
964
965    protected void rebuildInterceptors()
966    {
967       if (initialized)
968       {
969          if (System.getSecurityManager() == null)
970          {
971             RebuildInterceptorsAction.NON_PRIVILEGED.rebuildInterceptors(this);
972          }
973          else
974          {
975             RebuildInterceptorsAction.PRIVILEGED.rebuildInterceptors(this);
976          }
977       }
978    }
979
980    protected void doRebuildInterceptors()
981    {
982       try
983       {
984          adviceBindings.clear();
985          createInterceptorChains();
986          rebuildCallerInterceptors();
987       }
988       catch (Exception JavaDoc ex)
989       {
990          throw new RuntimeException JavaDoc(ex);
991       }
992    }
993    protected void bindClassMetaData(ClassMetaDataBinding data)
994    {
995       try
996       {
997          ClassMetaDataLoader loader = data.getLoader();
998          Object JavaDoc[] objs = advisedMethods.getValues();
999          Method JavaDoc[] methods = new Method JavaDoc[objs.length];
1000         Field JavaDoc[] fields = advisedFields;
1001         // set to empty array because advisedFields may not have been initialized yet
1002
if (fields == null) fields = new Field JavaDoc[0];
1003         Constructor JavaDoc[] cons = constructors;
1004         // set to empty array because constructors may not have been initialized yet
1005
if (cons == null) cons = new Constructor JavaDoc[0];
1006         for (int i = 0; i < objs.length; i++) methods[i] = (Method JavaDoc) objs[i];
1007         loader.bind(this, data, methods, fields, cons);
1008      }
1009      catch (Exception JavaDoc ex)
1010      {
1011         // REVISIT: Need to know how errors affects deployment
1012
ex.printStackTrace();
1013      }
1014   }
1015
1016   protected void rebindClassMetaData()
1017   {
1018      defaultMetaData.clear();
1019      methodMetaData.clear();
1020      fieldMetaData.clear();
1021      constructorMetaData.clear();
1022      classMetaData.clear();
1023
1024      for (int i = 0; i < classMetaDataBindings.size(); i++)
1025      {
1026         ClassMetaDataBinding data = (ClassMetaDataBinding) classMetaDataBindings.get(i);
1027         bindClassMetaData(data);
1028      }
1029      
1030      deployAnnotationOverrides();
1031   }
1032
1033
1034   public synchronized void addClassMetaData(ClassMetaDataBinding data)
1035   {
1036      classMetaDataBindings.add(data);
1037      if (this.clazz == null) return; // don't bind till later.
1038

1039      bindClassMetaData(data);
1040      // Recalculate interceptorPointcuts because of MetaDataInterceptorPointcuts
1041
adviceBindings.clear();
1042      doesHaveAspects = false;
1043      rebuildInterceptors();
1044   }
1045
1046   public synchronized void removeClassMetaData(ClassMetaDataBinding data)
1047   {
1048      if (classMetaDataBindings.remove(data))
1049      {
1050         if (this.clazz == null) return; // not bound yet
1051
rebindClassMetaData();
1052         // Recalculate interceptorPointcuts because of MetaDataInterceptorPointcuts
1053
adviceBindings.clear();
1054         doesHaveAspects = false;
1055         rebuildInterceptors();
1056      }
1057      
1058      
1059   }
1060
1061   private void initializeEmptyCallerChain(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash) throws Exception JavaDoc
1062   {
1063      HashMap callingMethod = (HashMap) methodCalledByMethodBindings.get(callingMethodHash);
1064      if (callingMethod == null)
1065      {
1066         callingMethod = new HashMap();
1067         methodCalledByMethodBindings.put(callingMethodHash, callingMethod);
1068      }
1069      TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
1070      if (classMap == null)
1071      {
1072         classMap = new TLongObjectHashMap();
1073         callingMethod.put(calledClass, classMap);
1074      }
1075      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledMethodHash);
1076      if (bindings == null)
1077      {
1078         bindings = new ArrayList JavaDoc();
1079         classMap.put(calledMethodHash, bindings);
1080      }
1081   }
1082
1083   private void initializeConCalledByMethodEmptyChain(long callingMethodHash, String JavaDoc calledClass, long calledConHash) throws Exception JavaDoc
1084   {
1085      HashMap callingMethod = (HashMap) conCalledByMethodBindings.get(callingMethodHash);
1086      if (callingMethod == null)
1087      {
1088         callingMethod = new HashMap();
1089         conCalledByMethodBindings.put(callingMethodHash, callingMethod);
1090      }
1091      TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
1092      if (classMap == null)
1093      {
1094         classMap = new TLongObjectHashMap();
1095         callingMethod.put(calledClass, classMap);
1096      }
1097      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledConHash);
1098      if (bindings == null)
1099      {
1100         bindings = new ArrayList JavaDoc();
1101         classMap.put(calledConHash, bindings);
1102      }
1103   }
1104
1105   private void initializeEmptyConstructorCallerChain(int callingIndex, String JavaDoc calledClass, long calledMethodHash) throws Exception JavaDoc
1106   {
1107      HashMap callingCon = methodCalledByConBindings[callingIndex];
1108      if (callingCon == null)
1109      {
1110         callingCon = new HashMap();
1111         methodCalledByConBindings[callingIndex] = callingCon;
1112      }
1113      TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
1114      if (classMap == null)
1115      {
1116         classMap = new TLongObjectHashMap();
1117         callingCon.put(calledClass, classMap);
1118      }
1119      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledMethodHash);
1120      if (bindings == null)
1121      {
1122         bindings = new ArrayList JavaDoc();
1123         classMap.put(calledMethodHash, bindings);
1124      }
1125   }
1126
1127   private void initializeConCalledByConEmptyChain(int callingIndex, String JavaDoc calledClass, long calledConHash) throws Exception JavaDoc
1128   {
1129      HashMap callingCon = conCalledByConBindings[callingIndex];
1130      if (callingCon == null)
1131      {
1132         callingCon = new HashMap();
1133         conCalledByConBindings[callingIndex] = callingCon;
1134      }
1135      TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
1136      if (classMap == null)
1137      {
1138         classMap = new TLongObjectHashMap();
1139         callingCon.put(calledClass, classMap);
1140      }
1141      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledConHash);
1142      if (bindings == null)
1143      {
1144         bindings = new ArrayList JavaDoc();
1145         classMap.put(calledConHash, bindings);
1146      }
1147   }
1148
1149   private void addMethodCalledByMethodPointcut(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash, AdviceBinding binding) throws Exception JavaDoc
1150   {
1151      if (AspectManager.verbose) System.err.println("method call matched binding " + binding.getPointcut().getExpr());
1152      adviceBindings.add(binding);
1153      binding.addAdvisor(this);
1154      HashMap callingMethod = (HashMap) methodCalledByMethodBindings.get(callingMethodHash);
1155      if (callingMethod == null)
1156      {
1157         callingMethod = new HashMap();
1158         methodCalledByMethodBindings.put(callingMethodHash, callingMethod);
1159      }
1160      TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
1161      if (classMap == null)
1162      {
1163         classMap = new TLongObjectHashMap();
1164         callingMethod.put(calledClass, classMap);
1165      }
1166      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledMethodHash);
1167      boolean createdBindings = false;
1168      if (bindings == null)
1169      {
1170         bindings = new ArrayList JavaDoc();
1171         classMap.put(calledMethodHash, bindings);
1172         createdBindings = true;
1173      }
1174      if (!bindings.contains(binding)) bindings.add(binding);
1175
1176      // this is so that we can undeploy a caller
1177
ArrayList JavaDoc backrefs = (ArrayList JavaDoc) backrefMethodCalledByMethodBindings.get(binding.getName());
1178      if (backrefs == null)
1179      {
1180         backrefs = new ArrayList JavaDoc();
1181         backrefMethodCalledByMethodBindings.put(binding.getName(), backrefs);
1182         backrefs.add(bindings);
1183      }
1184      else if (createdBindings) backrefs.add(bindings);
1185   }
1186
1187   private void addConstructorCalledByMethodPointcut(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash, AdviceBinding binding) throws Exception JavaDoc
1188   {
1189      if (AspectManager.verbose) System.err.println("method call matched binding " + binding.getPointcut().getExpr());
1190      adviceBindings.add(binding);
1191      binding.addAdvisor(this);
1192      HashMap callingMethod = (HashMap) conCalledByMethodBindings.get(callingMethodHash);
1193      if (callingMethod == null)
1194      {
1195         callingMethod = new HashMap();
1196         conCalledByMethodBindings.put(callingMethodHash, callingMethod);
1197      }
1198      TLongObjectHashMap classMap = (TLongObjectHashMap) callingMethod.get(calledClass);
1199      if (classMap == null)
1200      {
1201         classMap = new TLongObjectHashMap();
1202         callingMethod.put(calledClass, classMap);
1203      }
1204      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledMethodHash);
1205      boolean createdBindings = false;
1206      if (bindings == null)
1207      {
1208         bindings = new ArrayList JavaDoc();
1209         classMap.put(calledMethodHash, bindings);
1210         createdBindings = true;
1211      }
1212      if (!bindings.contains(binding)) bindings.add(binding);
1213
1214      // this is so that we can undeploy a caller
1215
ArrayList JavaDoc backrefs = (ArrayList JavaDoc) backrefConCalledByMethodBindings.get(binding.getName());
1216      if (backrefs == null)
1217      {
1218         backrefs = new ArrayList JavaDoc();
1219         backrefConCalledByMethodBindings.put(binding.getName(), backrefs);
1220         backrefs.add(bindings);
1221      }
1222      else if (createdBindings) backrefs.add(bindings);
1223   }
1224
1225   public void addConstructorCallerPointcut(int callingIndex, String JavaDoc calledClass, long calledMethodHash, AdviceBinding binding) throws Exception JavaDoc
1226   {
1227      if (AspectManager.verbose) System.err.println("constructor call matched binding " + binding.getPointcut().getExpr());
1228      adviceBindings.add(binding);
1229      binding.addAdvisor(this);
1230      HashMap callingCon = methodCalledByConBindings[callingIndex];
1231      if (callingCon == null)
1232      {
1233         callingCon = new HashMap();
1234         methodCalledByConBindings[callingIndex] = callingCon;
1235      }
1236      TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
1237      if (classMap == null)
1238      {
1239         classMap = new TLongObjectHashMap();
1240         callingCon.put(calledClass, classMap);
1241      }
1242      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledMethodHash);
1243      boolean createdBindings = false;
1244      if (bindings == null)
1245      {
1246         bindings = new ArrayList JavaDoc();
1247         classMap.put(calledMethodHash, bindings);
1248         createdBindings = true;
1249      }
1250      if (!bindings.contains(binding)) bindings.add(binding);
1251
1252      // this is so that we can undeploy a caller
1253
ArrayList JavaDoc backrefs = (ArrayList JavaDoc) backrefMethodCalledByConstructorBindings.get(binding.getName());
1254      if (backrefs == null)
1255      {
1256         backrefs = new ArrayList JavaDoc();
1257         backrefMethodCalledByConstructorBindings.put(binding.getName(), backrefs);
1258         backrefs.add(bindings);
1259      }
1260      else if (createdBindings) backrefs.add(bindings);
1261   }
1262
1263   private void addConstructorCalledByConPointcut(int callingIndex, String JavaDoc calledClass, long calledConHash, AdviceBinding binding) throws Exception JavaDoc
1264   {
1265      if (AspectManager.verbose) System.err.println("constructor call matched binding " + binding.getPointcut().getExpr());
1266      adviceBindings.add(binding);
1267      binding.addAdvisor(this);
1268      HashMap callingCon = conCalledByConBindings[callingIndex];
1269      if (callingCon == null)
1270      {
1271         callingCon = new HashMap();
1272         conCalledByConBindings[callingIndex] = callingCon;
1273      }
1274      TLongObjectHashMap classMap = (TLongObjectHashMap) callingCon.get(calledClass);
1275      if (classMap == null)
1276      {
1277         classMap = new TLongObjectHashMap();
1278         callingCon.put(calledClass, classMap);
1279      }
1280      ArrayList JavaDoc bindings = (ArrayList JavaDoc) classMap.get(calledConHash);
1281      boolean createdBindings = false;
1282      if (bindings == null)
1283      {
1284         bindings = new ArrayList JavaDoc();
1285         classMap.put(calledConHash, bindings);
1286         createdBindings = true;
1287      }
1288      if (!bindings.contains(binding)) bindings.add(binding);
1289
1290      // this is so that we can undeploy a caller
1291
ArrayList JavaDoc backrefs = (ArrayList JavaDoc) backrefConCalledByConstructorBindings.get(binding.getName());
1292      if (backrefs == null)
1293      {
1294         backrefs = new ArrayList JavaDoc();
1295         backrefConCalledByConstructorBindings.put(binding.getName(), backrefs);
1296         backrefs.add(bindings);
1297      }
1298      else if (createdBindings) backrefs.add(bindings);
1299   }
1300
1301   private void removeCallerPointcut(AdviceBinding binding)
1302   {
1303      ArrayList JavaDoc backrefs = (ArrayList JavaDoc) backrefMethodCalledByMethodBindings.get(binding.getName());
1304      if (backrefs == null) return;
1305      for (int i = 0; i < backrefs.size(); i++)
1306      {
1307         ArrayList JavaDoc ref = (ArrayList JavaDoc) backrefs.get(i);
1308         ref.remove(binding);
1309      }
1310   }
1311
1312   /**
1313    * Generates internal, unadvised version of a method name.
1314    */

1315   public static String JavaDoc notAdvisedMethodName(String JavaDoc className,
1316                                             String JavaDoc methodName)
1317   {
1318      return className.replace('.', '$') + "$" + methodName +
1319      NOT_TRANSFORMABLE_SUFFIX;
1320   }
1321
1322   /**
1323    * Is this the name of a private, unadvised thing?
1324    */

1325   public static boolean isWithoutAdvisement(String JavaDoc name)
1326   {
1327      return name.endsWith(NOT_TRANSFORMABLE_SUFFIX);
1328   }
1329
1330   /**
1331    * Is the method advisable?
1332    */

1333   public static boolean isAdvisable(Method JavaDoc method)
1334   {
1335      // note: this should match the implementation in the instrumentor.
1336
int modifiers = method.getModifiers();
1337      return (
1338      !isWithoutAdvisement(method.getName()) &&
1339      !Modifier.isAbstract(modifiers) &&
1340      !Modifier.isNative(modifiers) &&
1341      !(method.getName().equals("_getAdvisor") &&
1342            method.getParameterTypes().length == 0 &&
1343            method.getReturnType().equals(Advisor.class)) &&
1344      !(method.getName().equals("_getClassAdvisor") &&
1345            method.getParameterTypes().length == 0 &&
1346            method.getReturnType().equals(Advisor.class)) &&
1347      !(method.getName().equals("_getInstanceAdvisor") &&
1348            method.getParameterTypes().length == 0 &&
1349            method.getReturnType().equals(InstanceAdvisor.class)) &&
1350      !(method.getName().equals("_setInstanceAdvisor") &&
1351            method.getParameterTypes().length == 1 &&
1352            method.getParameterTypes()[0].equals(InstanceAdvisor.class)));
1353   }
1354   
1355   private void populateFieldTable(ArrayList JavaDoc fields, Class JavaDoc superclass)
1356   throws Exception JavaDoc
1357   {
1358      if (superclass == null) return;
1359      if (superclass.equals(Object JavaDoc.class)) return;
1360
1361      populateFieldTable(fields, superclass.getSuperclass());
1362
1363      // if (!isAdvised(superclass)) return;
1364

1365      ArrayList JavaDoc temp = new ArrayList JavaDoc();
1366      Field JavaDoc[] declaredFields = superclass.getDeclaredFields();
1367      for (int i = 0; i < declaredFields.length; i++)
1368      {
1369         if (Advisable.isAdvisable(declaredFields[i]))
1370         {
1371            // Need to do this because notadvisable fields maybe private or protected
1372
declaredFields[i].setAccessible(true);
1373            temp.add(declaredFields[i]);
1374         }
1375      }
1376      Collections.sort(temp, FieldComparator.INSTANCE);
1377      fields.addAll(temp);
1378   }
1379
1380   /**
1381    * Gets advised methods.
1382    */

1383   private void createFieldTable() throws Exception JavaDoc
1384   {
1385      ArrayList JavaDoc fields = new ArrayList JavaDoc();
1386
1387      populateFieldTable(fields, clazz);
1388
1389      advisedFields = (Field JavaDoc[]) fields.toArray(new Field JavaDoc[fields.size()]);
1390
1391   }
1392
1393   protected void addDeclaredMethods(Class JavaDoc superclass) throws Exception JavaDoc
1394   {
1395      Method JavaDoc[] declaredMethods = superclass.getDeclaredMethods();
1396      for (int i = 0; i < declaredMethods.length; i++)
1397      {
1398         if (ClassAdvisor.isAdvisable(declaredMethods[i]))
1399         {
1400            long hash = MethodHashing.methodHash(declaredMethods[i]);
1401            advisedMethods.put(hash, declaredMethods[i]);
1402            try
1403            {
1404               Method JavaDoc m = declaredMethods[i];
1405               Method JavaDoc un = superclass.getDeclaredMethod(ClassAdvisor.notAdvisedMethodName(superclass.getName(),
1406               m.getName()),
1407               m.getParameterTypes());
1408               un.setAccessible(true);
1409               unadvisedMethods.put(hash, un);
1410            }
1411            catch (NoSuchMethodException JavaDoc ignored)
1412            {
1413            }
1414         }
1415      }
1416   }
1417
1418   /**
1419    * Create a HashMap of method hash and Method
1420    * Superclasses get added first so subclasses will override with
1421    * correct overriden method
1422    */

1423   private void populateMethodTables(Class JavaDoc superclass)
1424   throws Exception JavaDoc
1425   {
1426      if (superclass == null) return;
1427      if (superclass.equals(Object JavaDoc.class)) return;
1428
1429      populateMethodTables(superclass.getSuperclass());
1430
1431      //The advisor for the superclass may be a container
1432
Advisor superAdvisor = manager.getAnyAdvisorIfAdvised(superclass);
1433      if (superAdvisor != null && superAdvisor instanceof ClassAdvisor)
1434      {
1435         TLongObjectHashMap superHash = ((ClassAdvisor)superAdvisor).getUnadvisedMethods();
1436         long[] keys = superHash.keys();
1437         for (int i = 0; i < keys.length; i++)
1438         {
1439            unadvisedMethods.put(keys[i], superHash.get(keys[i]));
1440         }
1441      }
1442      addDeclaredMethods(superclass);
1443   }
1444
1445   private void createMethodTables()
1446   throws Exception JavaDoc
1447   {
1448      populateMethodTables(clazz.getSuperclass());
1449      addDeclaredMethods(clazz);
1450   }
1451
1452   private void createConstructorTables() throws Exception JavaDoc
1453   {
1454      constructors = clazz.getDeclaredConstructors();
1455      methodCalledByConBindings = new HashMap[constructors.length];
1456      methodCalledByConInterceptors = new HashMap[constructors.length];
1457
1458      conCalledByConBindings = new HashMap[constructors.length];
1459      conCalledByConInterceptors = new HashMap[constructors.length];
1460      for (int i = 0; i < constructors.length; i++)
1461      {
1462         constructors[i].setAccessible(true);
1463      }
1464      Arrays.sort(constructors, ConstructorComparator.INSTANCE);
1465   }
1466
1467   public MethodByMethodInfo resolveCallerMethodInfo(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash)
1468   {
1469      if (System.getSecurityManager() == null)
1470      {
1471         return ResolveCallerMethodInfoAction.NON_PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledMethodHash);
1472      }
1473      else
1474      {
1475         return ResolveCallerMethodInfoAction.PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledMethodHash);
1476      }
1477   }
1478
1479   private MethodByMethodInfo doResolveCallerMethodInfo(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash)
1480   {
1481      try
1482      {
1483         Method JavaDoc callingMethod = MethodHashing.findMethodByHash(clazz, callingMethodHash);
1484         if (callingMethod == null) throw new RuntimeException JavaDoc("Unable to figure out calling method of a caller pointcut");
1485         Class JavaDoc called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
1486         Method JavaDoc calledMethod = MethodHashing.findMethodByHash(called, calledMethodHash);
1487         if (calledMethod == null) throw new RuntimeException JavaDoc("Unable to figure out calledmethod of a caller pointcut");
1488
1489         Iterator JavaDoc it = manager.getBindings().values().iterator();
1490         boolean matched = false;
1491         while (it.hasNext())
1492         {
1493            AdviceBinding binding = (AdviceBinding) it.next();
1494            if (binding.getPointcut().matchesCall(this, callingMethod, called, calledMethod))
1495            {
1496               addMethodCalledByMethodPointcut(callingMethodHash, calledClass, calledMethodHash, binding);
1497               matched = true;
1498            }
1499         }
1500         if (!matched) initializeEmptyCallerChain(callingMethodHash, calledClass, calledMethodHash);
1501         MethodByMethodInfo info = initializeCallerInterceptorsMap(callingMethodHash, calledClass, calledMethodHash, callingMethod, calledMethod);
1502         ArrayList JavaDoc bindings = getCallerBindings(callingMethodHash, calledClass, calledMethodHash);
1503         bindCallerInterceptorChain(bindings, callingMethodHash, calledClass, calledMethodHash, callingMethod);
1504         return info;
1505      }
1506      catch (Exception JavaDoc x)
1507      {
1508         throw new RuntimeException JavaDoc(x);
1509      }
1510   }
1511
1512   public WeakReference JavaDoc resolveCallerMethodInfoAsWeakReference(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash)
1513   {
1514      //Javassist doesn't like this in a field initialiser hence this method
1515
return new WeakReference JavaDoc(resolveCallerMethodInfo(callingMethodHash, calledClass, calledMethodHash));
1516   }
1517   
1518   public ConByMethodInfo resolveCallerConstructorInfo(long callingMethodHash, String JavaDoc calledClass, long calledConHash)
1519   {
1520      if (System.getSecurityManager() == null)
1521      {
1522         return ResolveCallerConstuctorInfoAction.NON_PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledConHash);
1523      }
1524      else
1525      {
1526         return ResolveCallerConstuctorInfoAction.PRIVILEGED.resolveInfo(this, callingMethodHash, calledClass, calledConHash);
1527      }
1528   }
1529
1530   private ConByMethodInfo doResolveCallerConstructorInfo(long callingMethodHash, String JavaDoc calledClass, long calledConHash)
1531   {
1532      try
1533      {
1534         Method JavaDoc callingMethod = MethodHashing.findMethodByHash(clazz, callingMethodHash);
1535         if (callingMethod == null) throw new RuntimeException JavaDoc("Unable to figure out calling method of a constructor caller pointcut");
1536         Class JavaDoc called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
1537         Constructor JavaDoc calledCon = MethodHashing.findConstructorByHash(called, calledConHash);
1538         if (calledCon == null) throw new RuntimeException JavaDoc("Unable to figure out calledcon of a constructor caller pointcut");
1539
1540         boolean matched = false;
1541         synchronized (manager.getBindings())
1542         {
1543            Iterator JavaDoc it = manager.getBindings().values().iterator();
1544            while (it.hasNext())
1545            {
1546               AdviceBinding binding = (AdviceBinding) it.next();
1547               if (binding.getPointcut().matchesCall(this, callingMethod, called, calledCon))
1548               {
1549                  addConstructorCalledByMethodPointcut(callingMethodHash, calledClass, calledConHash, binding);
1550                  matched = true;
1551               }
1552            }
1553         }
1554         if (!matched) initializeConCalledByMethodEmptyChain(callingMethodHash, calledClass, calledConHash);
1555         ConByMethodInfo info = initializeConCalledByMethodInterceptorsMap(callingMethodHash, calledClass, calledConHash, calledCon);
1556         ArrayList JavaDoc bindings = getConCalledByMethodBindings(callingMethodHash, calledClass, calledConHash);
1557         bindConCalledByMethodInterceptorChain(bindings, callingMethodHash, calledClass, calledConHash);
1558         return info;
1559      }
1560      catch (Exception JavaDoc x)
1561      {
1562         throw new RuntimeException JavaDoc(x);
1563      }
1564   }
1565   
1566   public WeakReference JavaDoc resolveCallerConstructorInfoAsWeakReference(long callingMethodHash, String JavaDoc calledClass, long calledConHash)
1567   {
1568      //Javassist doesn't like this in a field initialiser hence this method
1569
return new WeakReference JavaDoc(resolveCallerConstructorInfo(callingMethodHash, calledClass, calledConHash));
1570   }
1571
1572   public MethodByConInfo resolveConstructorCallerMethodInfo(int callingIndex, String JavaDoc calledClass, long calledMethodHash)
1573   {
1574      if (System.getSecurityManager() == null)
1575      {
1576         return ResolveConstructorCallerMethodInfoAction.NON_PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledMethodHash);
1577      }
1578      else
1579      {
1580         return ResolveConstructorCallerMethodInfoAction.PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledMethodHash);
1581      }
1582   }
1583
1584   private MethodByConInfo doResolveConstructorCallerMethodInfo(int callingIndex, String JavaDoc calledClass, long calledMethodHash)
1585   {
1586      try
1587      {
1588         Constructor JavaDoc callingConstructor = constructors[callingIndex];
1589         if (callingConstructor == null) throw new RuntimeException JavaDoc("Unable to figure out calling method of a caller pointcut");
1590         Class JavaDoc called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
1591         Method JavaDoc calledMethod = MethodHashing.findMethodByHash(called, calledMethodHash);
1592         if (calledMethod == null) throw new RuntimeException JavaDoc("Unable to figure out calledmethod of a caller pointcut");
1593
1594         boolean matched = false;
1595         
1596         synchronized (manager.getBindings())
1597         {
1598            Iterator JavaDoc it = manager.getBindings().values().iterator();
1599            while (it.hasNext())
1600            {
1601               AdviceBinding binding = (AdviceBinding) it.next();
1602               if (binding.getPointcut().matchesCall(this, callingConstructor, called, calledMethod))
1603               {
1604                  addConstructorCallerPointcut(callingIndex, calledClass, calledMethodHash, binding);
1605                  matched = true;
1606               }
1607            }
1608         }
1609         if (!matched) initializeEmptyConstructorCallerChain(callingIndex, calledClass, calledMethodHash);
1610         MethodByConInfo info = initializeConstructorCallerInterceptorsMap(callingIndex, calledClass, calledMethodHash, calledMethod);
1611         ArrayList JavaDoc bindings = getConstructorCallerBindings(callingIndex, calledClass, calledMethodHash);
1612         bindConstructorCallerInterceptorChain(bindings, callingIndex, calledClass, calledMethodHash);
1613         return info;
1614      }
1615      catch (Exception JavaDoc x)
1616      {
1617         throw new RuntimeException JavaDoc(x);
1618      }
1619   }
1620
1621
1622   public WeakReference JavaDoc resolveConstructorCallerMethodInfoAsWeakReference(int callingIndex, String JavaDoc calledClass, long calledMethodHash)
1623   {
1624      //Javassist doesn't like this in a field initialiser hence this method
1625
return new WeakReference JavaDoc(resolveConstructorCallerMethodInfo(callingIndex, calledClass, calledMethodHash));
1626   }
1627   
1628   public ConByConInfo resolveConstructorCallerConstructorInfo(int callingIndex, String JavaDoc calledClass, long calledConHash)
1629   {
1630      if (System.getSecurityManager() == null)
1631      {
1632         return ResolveConstructorCallerConstructorInfoAction.NON_PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledConHash);
1633      }
1634      else
1635      {
1636         return ResolveConstructorCallerConstructorInfoAction.PRIVILEGED.resolveInfo(this, callingIndex, calledClass, calledConHash);
1637      }
1638   }
1639
1640   private ConByConInfo doResolveConstructorCallerConstructorInfo(int callingIndex, String JavaDoc calledClass, long calledConHash)
1641   {
1642      try
1643      {
1644         Constructor JavaDoc callingConstructor = constructors[callingIndex];
1645         if (callingConstructor == null) throw new RuntimeException JavaDoc("Unable to figure out calling method of a caller pointcut");
1646         Class JavaDoc called = Thread.currentThread().getContextClassLoader().loadClass(calledClass);
1647         Constructor JavaDoc calledCon = MethodHashing.findConstructorByHash(called, calledConHash);
1648         if (calledCon == null) throw new RuntimeException JavaDoc("Unable to figure out calledcon of a caller pointcut");
1649
1650         boolean matched = false;
1651         synchronized (manager.getBindings())
1652         {
1653            Iterator JavaDoc it = manager.getBindings().values().iterator();
1654            while (it.hasNext())
1655            {
1656               AdviceBinding binding = (AdviceBinding) it.next();
1657               if (binding.getPointcut().matchesCall(this, callingConstructor, called, calledCon))
1658               {
1659                  addConstructorCalledByConPointcut(callingIndex, calledClass, calledConHash, binding);
1660                  matched = true;
1661               }
1662            }
1663         }
1664         if (!matched) initializeConCalledByConEmptyChain(callingIndex, calledClass, calledConHash);
1665         ConByConInfo info = initializeConCalledByConInterceptorsMap(callingIndex, calledClass, calledConHash, calledCon);
1666         ArrayList JavaDoc bindings = getConCalledByConBindings(callingIndex, calledClass, calledConHash);
1667         bindConCalledByConInterceptorChain(bindings, callingIndex, calledClass, calledConHash);
1668         return info;
1669      }
1670      catch (Exception JavaDoc x)
1671      {
1672         throw new RuntimeException JavaDoc(x);
1673      }
1674   }
1675
1676   public WeakReference JavaDoc resolveConstructorCallerConstructorInfoAsWeakReference(int callingIndex, String JavaDoc calledClass, long calledConHash)
1677   {
1678      //Javassist doesn't like this in a field initialiser hence this method
1679
return new WeakReference JavaDoc(resolveConstructorCallerConstructorInfo(callingIndex, calledClass, calledConHash));
1680   }
1681   /////////////////////////
1682
// Invoking
1683

1684   /**
1685    * Invokes target object without applying interceptors.
1686    */

1687   public Object JavaDoc invokeWithoutAdvisement(Object JavaDoc target, long methodHash,
1688                                         Object JavaDoc[] arguments) throws Throwable JavaDoc
1689   {
1690      try
1691      {
1692         Method JavaDoc method = (Method JavaDoc) unadvisedMethods.get(methodHash);
1693         return method.invoke(target, arguments);
1694      }
1695      catch (InvocationTargetException JavaDoc e)
1696      {
1697         throw e.getTargetException();
1698      }
1699   }
1700
1701   public Object JavaDoc invokeNewWithoutAdvisement(Object JavaDoc[] arguments, Constructor JavaDoc constructor) throws Throwable JavaDoc
1702   {
1703      try
1704      {
1705         return constructor.newInstance(arguments);
1706      }
1707      catch (InstantiationException JavaDoc in)
1708      {
1709         throw new RuntimeException JavaDoc("failed to call constructor", in);
1710      }
1711      catch (IllegalAccessException JavaDoc ill)
1712      {
1713         throw new RuntimeException JavaDoc("illegal access", ill);
1714      }
1715      catch (InvocationTargetException JavaDoc ite)
1716      {
1717         throw ite.getCause();
1718      }
1719   }
1720
1721
1722   public Object JavaDoc invokeMethod(long methodHash, Object JavaDoc[] arguments) throws Throwable JavaDoc
1723   {
1724      return invokeMethod(null, methodHash, arguments);
1725   }
1726
1727   public Object JavaDoc invokeMethod(Object JavaDoc target, long methodHash, Object JavaDoc[] arguments) throws Throwable JavaDoc
1728   {
1729      InstanceAdvisor advisor = null;
1730      if (target != null)
1731      {
1732         InstanceAdvised advised = (InstanceAdvised) target;
1733         advisor = advised._getInstanceAdvisor();
1734      }
1735      MethodInfo info = (MethodInfo) methodInterceptors.get(methodHash);
1736      return invokeMethod(advisor, target, methodHash, arguments, info);
1737   }
1738
1739
1740   public Object JavaDoc invokeMethod(InstanceAdvisor instanceAdvisor, Object JavaDoc target, long methodHash, Object JavaDoc[] arguments)
1741   throws Throwable JavaDoc
1742   {
1743      MethodInfo info = (MethodInfo) methodInterceptors.get(methodHash);
1744      if (info == null)
1745      {
1746         System.out.println("info is null for hash: " + methodHash + " of " + clazz.getName());
1747      }
1748      return invokeMethod(instanceAdvisor, target, methodHash, arguments, info);
1749   }
1750
1751   public Object JavaDoc invokeMethod(InstanceAdvisor instanceAdvisor, Object JavaDoc target, long methodHash, Object JavaDoc[] arguments, MethodInfo info)
1752   throws Throwable JavaDoc
1753   {
1754      Interceptor[] aspects = info.getInterceptors();
1755      if (instanceAdvisor != null && (instanceAdvisor.hasInterceptors()))
1756      {
1757         aspects = instanceAdvisor.getInterceptors(aspects);
1758      }
1759      MethodInvocation invocation = new MethodInvocation(info, aspects);
1760
1761      invocation.setArguments(arguments);
1762      invocation.setTargetObject(target);
1763      return invocation.invokeNext();
1764   }
1765
1766   /**
1767    *@deprecated
1768    */

1769   public Object JavaDoc invokeCaller(long callingMethodHash, Object JavaDoc target, Object JavaDoc[] args, CallerMethodInfo info, Object JavaDoc callingObject)
1770   throws Throwable JavaDoc
1771   {
1772      return invokeCaller((MethodByMethodInfo)info, callingObject, target, args);
1773   }
1774
1775   public Object JavaDoc invokeCaller(MethodByMethodInfo info, Object JavaDoc callingObject, Object JavaDoc target, Object JavaDoc[] args) throws Throwable JavaDoc
1776   {
1777      MethodCalledByMethodInvocation invocation = new MethodCalledByMethodInvocation(info, callingObject, target, args, info.getInterceptors());
1778      invocation.setTargetObject(target);
1779      return invocation.invokeNext();
1780   }
1781
1782   /**
1783    *@deprecated
1784    */

1785   public Object JavaDoc invokeConCalledByMethod(long callingMethodHash, Object JavaDoc[] args, CallerConstructorInfo info, Object JavaDoc callingObject)
1786   throws Throwable JavaDoc
1787   {
1788      return invokeConCalledByMethod((ConByMethodInfo)info, callingObject, args);
1789   }
1790   
1791   public Object JavaDoc invokeConCalledByMethod(ConByMethodInfo info, Object JavaDoc callingObject, Object JavaDoc[] args)
1792   throws Throwable JavaDoc
1793   {
1794      ConstructorCalledByMethodInvocation invocation = new ConstructorCalledByMethodInvocation(info, callingObject, args, info.getInterceptors());
1795      return invocation.invokeNext();
1796   }
1797   
1798   /**
1799    *@deprecated
1800    */

1801   public Object JavaDoc invokeConstructorCaller(int callingIndex, Object JavaDoc target, Object JavaDoc[] args, CallerMethodInfo info)
1802   throws Throwable JavaDoc
1803   {
1804      return invokeConstructorCaller((MethodByConInfo)info, target, args);
1805   }
1806      
1807   
1808   public Object JavaDoc invokeConstructorCaller(MethodByConInfo info, Object JavaDoc target, Object JavaDoc[] args)
1809   throws Throwable JavaDoc
1810   {
1811      MethodCalledByConstructorInvocation invocation = new MethodCalledByConstructorInvocation(info, target, args, info.getInterceptors());
1812      invocation.setTargetObject(target);
1813      return invocation.invokeNext();
1814   }
1815
1816   /**
1817    *@deprecated
1818    */

1819   public Object JavaDoc invokeConCalledByCon(int callingIndex, Object JavaDoc[] args, CallerConstructorInfo info)
1820   throws Throwable JavaDoc
1821   {
1822      return invokeConCalledByCon((ConByConInfo)info, args);
1823   }
1824   
1825   public Object JavaDoc invokeConCalledByCon(ConByConInfo info, Object JavaDoc[] args)
1826   throws Throwable JavaDoc
1827   {
1828      ConstructorCalledByConstructorInvocation invocation = new ConstructorCalledByConstructorInvocation(info, args, info.getInterceptors());
1829      return invocation.invokeNext();
1830   }
1831
1832   private MethodByMethodInfo getCallerMethodInfo(long callingMethodHash, String JavaDoc calledClass, long calledMethodHash)
1833   {
1834      HashMap calledClasses = (HashMap) methodCalledByMethodInterceptors.get(callingMethodHash);
1835      TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
1836      MethodByMethodInfo info = (MethodByMethodInfo) calledMethods.get(calledMethodHash);
1837      return info;
1838   }
1839
1840   private ConByMethodInfo getConCalledByMethod(long callingMethodHash, String JavaDoc calledClass, long calledConHash)
1841   {
1842      HashMap calledClasses = (HashMap) conCalledByMethodInterceptors.get(callingMethodHash);
1843      TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
1844      ConByMethodInfo info = (ConByMethodInfo) calledMethods.get(calledConHash);
1845      return info;
1846   }
1847
1848   private MethodByConInfo getConstructorCallerMethodInfo(int callingIndex, String JavaDoc calledClass, long calledMethodHash)
1849   {
1850      HashMap calledClasses = methodCalledByConInterceptors[callingIndex];
1851      TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
1852      MethodByConInfo info = (MethodByConInfo) calledMethods.get(calledMethodHash);
1853      return info;
1854   }
1855
1856   private ConByConInfo getConCalledByCon(int callingIndex, String JavaDoc calledClass, long calledConHash)
1857   {
1858      HashMap calledClasses = conCalledByConInterceptors[callingIndex];
1859      TLongObjectHashMap calledMethods = (TLongObjectHashMap) calledClasses.get(calledClass);
1860      ConByConInfo info = (ConByConInfo) calledMethods.get(calledConHash);
1861      return info;
1862   }
1863
1864
1865   public Object JavaDoc invokeNew(Object JavaDoc[] args, int idx) throws Throwable JavaDoc
1866   {
1867      Interceptor[] cInterceptors = constructorInfos[idx].getInterceptors();
1868      if (cInterceptors == null) cInterceptors = new Interceptor[0];
1869      ConstructorInvocation invocation = new ConstructorInvocation(cInterceptors);
1870
1871      invocation.setAdvisor(this);
1872      invocation.setArguments(args);
1873      invocation.setConstructor(constructors[idx]);
1874      return invocation.invokeNext();
1875   }
1876
1877   /**
1878    * Invokes interceptor chain.
1879    * This is the beginning
1880    */

1881   public Object JavaDoc invokeRead(Object JavaDoc target, int index)
1882   throws Throwable JavaDoc
1883   {
1884      Interceptor[] aspects = fieldReadInfos[index].getInterceptors();
1885      if (aspects == null) aspects = new Interceptor[0];
1886      FieldReadInvocation invocation;
1887      if (target != null)
1888      {
1889         InstanceAdvised advised = (InstanceAdvised) target;
1890         InstanceAdvisor advisor = advised._getInstanceAdvisor();
1891         if (advisor != null && advisor.hasInterceptors())
1892         {
1893            aspects = advisor.getInterceptors(aspects);
1894         }
1895      }
1896      invocation = new FieldReadInvocation(advisedFields[index], index, aspects);
1897      invocation.setAdvisor(this);
1898      invocation.setTargetObject(target);
1899      return invocation.invokeNext();
1900   }
1901
1902   /**
1903    * Invokes interceptor chain.
1904    * This is the beginning
1905    */

1906   public Object JavaDoc invokeWrite(Object JavaDoc target, int index, Object JavaDoc value)
1907   throws Throwable JavaDoc
1908   {
1909      Interceptor[] aspects = fieldWriteInfos[index].getInterceptors();
1910      if (aspects == null) aspects = new Interceptor[0];
1911      FieldWriteInvocation invocation;
1912      if (target != null)
1913      {
1914         InstanceAdvised advised = (InstanceAdvised) target;
1915         InstanceAdvisor advisor = advised._getInstanceAdvisor();
1916         if (advisor != null && advisor.hasInterceptors())
1917         {
1918            aspects = advised._getInstanceAdvisor().getInterceptors(aspects);
1919         }
1920      }
1921      invocation = new FieldWriteInvocation(advisedFields[index], index, value, aspects);
1922      invocation.setAdvisor(this);
1923      invocation.setTargetObject(target);
1924      return invocation.invokeNext();
1925   }
1926
1927   /**
1928    * Invokes interceptor chain.
1929    * This is the beginning
1930    */

1931   public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
1932   {
1933      if (invocation instanceof FieldWriteInvocation)
1934      {
1935         FieldWriteInvocation fieldInvocation = (FieldWriteInvocation) invocation;
1936         Object JavaDoc target = fieldInvocation.getTargetObject();
1937         Object JavaDoc val = fieldInvocation.getValue();
1938         Field JavaDoc field = fieldInvocation.getField();
1939         field.set(target, val);
1940         return null;
1941      }
1942      else if (invocation instanceof FieldReadInvocation)
1943      {
1944         FieldReadInvocation fieldInvocation = (FieldReadInvocation) invocation;
1945         Object JavaDoc target = fieldInvocation.getTargetObject();
1946         Field JavaDoc field = fieldInvocation.getField();
1947         return field.get(target);
1948      }
1949      else if (invocation instanceof MethodInvocation)
1950      {
1951         MethodInvocation methodInvocation = (MethodInvocation) invocation;
1952         return invokeWithoutAdvisement(methodInvocation.getTargetObject(),
1953         methodInvocation.getMethodHash(),
1954         methodInvocation.getArguments());
1955      }
1956      else if (invocation instanceof ConstructorInvocation)
1957      {
1958         ConstructorInvocation cInvocation = (ConstructorInvocation) invocation;
1959         Object JavaDoc[] arguments = cInvocation.getArguments();
1960         Constructor JavaDoc constructor = cInvocation.getConstructor();
1961         return invokeNewWithoutAdvisement(arguments, constructor);
1962      }
1963      throw new IllegalStateException JavaDoc("Unknown Invocation type: " + invocation.getClass().getName());
1964   }
1965
1966   // interceptor chain observer
1967
private InterceptorChainObserver interceptorChainObserver;
1968   
1969   /**
1970    * Returns the interceptor chain observer associated with this advisor.
1971    */

1972   protected InterceptorChainObserver getInterceptorChainObserver()
1973   {
1974      return this.interceptorChainObserver;
1975   }
1976   
1977   /**
1978    * Defines the interceptor chain observer associated with this advisor.
1979    * @param observer the interceptor chain observer.
1980    */

1981   protected void setInterceptorChainObserver(InterceptorChainObserver observer)
1982   {
1983      if (observer != null)
1984      {
1985         observer.initialInterceptorChains(this.clazz, fieldReadInterceptors, fieldWriteInterceptors,
1986               constructorInterceptors, methodInterceptors);
1987      }
1988      this.interceptorChainObserver = observer;
1989   }
1990
1991   /** @deprecated We should just be using xxxxInfos */
1992   protected void populateInterceptorsFromInfos()
1993   {
1994      super.populateInterceptorsFromInfos();
1995      fieldReadInterceptors = new Interceptor[fieldReadInfos.length][];
1996      for (int i = 0 ; i < fieldReadInfos.length ; i++)
1997      {
1998         fieldReadInterceptors[i] = fieldReadInfos[i].getInterceptors();
1999      }
2000      fieldWriteInterceptors = new Interceptor[fieldWriteInfos.length][];
2001      for (int i = 0 ; i < fieldWriteInfos.length ; i++)
2002      {
2003         fieldWriteInterceptors[i] = fieldWriteInfos[i].getInterceptors();
2004      }
2005      constructionInterceptors = new Interceptor[constructionInfos.length][];
2006      for (int i = 0 ; i < constructionInfos.length ; i++)
2007      {
2008         constructionInterceptors[i] = constructionInfos[i].getInterceptors();
2009      }
2010
2011   }
2012   
2013   interface ResolveCallerConstuctorInfoAction
2014   {
2015      ConByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String JavaDoc calledClass, long calledConHash);
2016      
2017      ResolveCallerConstuctorInfoAction PRIVILEGED = new ResolveCallerConstuctorInfoAction()
2018      {
2019         public ConByMethodInfo resolveInfo(final ClassAdvisor advisor, final long callingMethodHash, final String JavaDoc calledClass, final long calledConHash)
2020         {
2021            try
2022            {
2023               return (ConByMethodInfo)AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
2024               {
2025                  public Object JavaDoc run() throws Exception JavaDoc
2026                  {
2027                     return advisor.doResolveCallerConstructorInfo(callingMethodHash, calledClass, calledConHash);
2028                  }
2029               });
2030            }
2031            catch (PrivilegedActionException JavaDoc e)
2032            {
2033               Exception JavaDoc ex = e.getException();
2034               if (ex instanceof RuntimeException JavaDoc)
2035               {
2036                  throw (RuntimeException JavaDoc)ex;
2037               }
2038               throw new RuntimeException JavaDoc(ex);
2039            }
2040         }
2041      };
2042
2043      ResolveCallerConstuctorInfoAction NON_PRIVILEGED = new ResolveCallerConstuctorInfoAction()
2044      {
2045         public ConByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String JavaDoc calledClass, long calledConHash)
2046         {
2047            return advisor.doResolveCallerConstructorInfo(callingMethodHash, calledClass, calledConHash);
2048         }
2049      };
2050   }
2051
2052   interface ResolveCallerMethodInfoAction
2053   {
2054      MethodByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String JavaDoc calledClass, long calledMethodHash);
2055      
2056      ResolveCallerMethodInfoAction PRIVILEGED = new ResolveCallerMethodInfoAction()
2057      {
2058         public MethodByMethodInfo resolveInfo(final ClassAdvisor advisor, final long callingMethodHash, final String JavaDoc calledClass, final long calledMethodHash)
2059         {
2060            try
2061            {
2062               return (MethodByMethodInfo)AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
2063               {
2064                  public Object JavaDoc run() throws Exception JavaDoc
2065                  {
2066                     return advisor.doResolveCallerMethodInfo(callingMethodHash, calledClass, calledMethodHash);
2067                  }
2068               });
2069            }
2070            catch (PrivilegedActionException JavaDoc e)
2071            {
2072               Exception JavaDoc ex = e.getException();
2073               if (ex instanceof RuntimeException JavaDoc)
2074               {
2075                  throw (RuntimeException JavaDoc)ex;
2076               }
2077               throw new RuntimeException JavaDoc(ex);
2078            }
2079         }
2080      };
2081
2082      ResolveCallerMethodInfoAction NON_PRIVILEGED = new ResolveCallerMethodInfoAction()
2083      {
2084         public MethodByMethodInfo resolveInfo(ClassAdvisor advisor, long callingMethodHash, String JavaDoc calledClass, long calledMethodHash)
2085         {
2086            return advisor.doResolveCallerMethodInfo(callingMethodHash, calledClass, calledMethodHash);
2087         }
2088      };
2089   }
2090
2091   interface ResolveConstructorCallerMethodInfoAction
2092   {
2093      MethodByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String JavaDoc calledClass, long calledMethodHash);
2094      
2095      ResolveConstructorCallerMethodInfoAction PRIVILEGED = new ResolveConstructorCallerMethodInfoAction()
2096      {
2097         public MethodByConInfo resolveInfo(final ClassAdvisor advisor, final int callingIndex, final String JavaDoc calledClass, final long calledMethodHash)
2098         {
2099            try
2100            {
2101               return (MethodByConInfo)AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
2102               {
2103                  public Object JavaDoc run() throws Exception JavaDoc
2104                  {
2105                     return advisor.doResolveConstructorCallerMethodInfo(callingIndex, calledClass, calledMethodHash);
2106                  }
2107               });
2108            }
2109            catch (PrivilegedActionException JavaDoc e)
2110            {
2111               Exception JavaDoc ex = e.getException();
2112               if (ex instanceof RuntimeException JavaDoc)
2113               {
2114                  throw (RuntimeException JavaDoc)ex;
2115               }
2116               throw new RuntimeException JavaDoc(ex);
2117            }
2118         }
2119      };
2120
2121      ResolveConstructorCallerMethodInfoAction NON_PRIVILEGED = new ResolveConstructorCallerMethodInfoAction()
2122      {
2123         public MethodByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String JavaDoc calledClass, long calledMethodHash)
2124         {
2125            return advisor.doResolveConstructorCallerMethodInfo(callingIndex, calledClass, calledMethodHash);
2126         }
2127      };
2128   }
2129
2130   interface ResolveConstructorCallerConstructorInfoAction
2131   {
2132      ConByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String JavaDoc calledClass, long calledConHash);
2133      
2134      ResolveConstructorCallerConstructorInfoAction PRIVILEGED = new ResolveConstructorCallerConstructorInfoAction()
2135      {
2136         public ConByConInfo resolveInfo(final ClassAdvisor advisor, final int callingIndex, final String JavaDoc calledClass, final long calledConHash)
2137         {
2138            try
2139            {
2140               return (ConByConInfo)AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
2141               {
2142                  public Object JavaDoc run() throws Exception JavaDoc
2143                  {
2144                     return advisor.doResolveConstructorCallerConstructorInfo(callingIndex, calledClass, calledConHash);
2145                  }
2146               });
2147            }
2148            catch (PrivilegedActionException JavaDoc e)
2149            {
2150               Exception JavaDoc ex = e.getException();
2151               if (ex instanceof RuntimeException JavaDoc)
2152               {
2153                  throw (RuntimeException JavaDoc)ex;
2154               }
2155               throw new RuntimeException JavaDoc(ex);
2156            }
2157         }
2158      };
2159
2160      ResolveConstructorCallerConstructorInfoAction NON_PRIVILEGED = new ResolveConstructorCallerConstructorInfoAction()
2161      {
2162         public ConByConInfo resolveInfo(ClassAdvisor advisor, int callingIndex, String JavaDoc calledClass, long calledConHash)
2163         {
2164            return advisor.doResolveConstructorCallerConstructorInfo(callingIndex, calledClass, calledConHash);
2165         }
2166      };
2167   }
2168   interface RebuildInterceptorsAction
2169   {
2170      void rebuildInterceptors(ClassAdvisor advisor);
2171      
2172      RebuildInterceptorsAction PRIVILEGED = new RebuildInterceptorsAction()
2173      {
2174         public void rebuildInterceptors(final ClassAdvisor advisor)
2175         {
2176            try
2177            {
2178               AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
2179               {
2180                  public Object JavaDoc run()
2181                  {
2182                     advisor.doRebuildInterceptors();
2183                     return null;
2184                  }
2185               });
2186            }
2187            catch (PrivilegedActionException JavaDoc e)
2188            {
2189               Exception JavaDoc ex = e.getException();
2190               if (ex instanceof RuntimeException JavaDoc)
2191               {
2192                  throw (RuntimeException JavaDoc)ex;
2193               }
2194               throw new RuntimeException JavaDoc(ex);
2195            }
2196         }
2197      };
2198
2199      RebuildInterceptorsAction NON_PRIVILEGED = new RebuildInterceptorsAction()
2200      {
2201         public void rebuildInterceptors(ClassAdvisor advisor)
2202         {
2203            advisor.doRebuildInterceptors();
2204         }
2205      };
2206   }
2207}
Popular Tags