KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > reflection > ReflectionAspect


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.reflection;
23
24 import gnu.trove.TLongObjectHashMap;
25 import org.jboss.aop.Advised;
26 import org.jboss.aop.AspectManager;
27 import org.jboss.aop.ClassAdvisor;
28 import org.jboss.aop.ConByConInfo;
29 import org.jboss.aop.ConByMethodInfo;
30 import org.jboss.aop.ConstructorInfo;
31 import org.jboss.aop.FieldInfo;
32 import org.jboss.aop.MethodByConInfo;
33 import org.jboss.aop.MethodByMethodInfo;
34 import org.jboss.aop.advice.Interceptor;
35 import org.jboss.aop.instrument.Untransformable;
36 import org.jboss.aop.joinpoint.Invocation;
37 import org.jboss.aop.joinpoint.MethodCalledByConstructorInvocation;
38 import org.jboss.aop.joinpoint.MethodCalledByMethodInvocation;
39 import org.jboss.aop.util.MethodHashing;
40
41 import java.lang.reflect.Constructor JavaDoc;
42 import java.lang.reflect.Field JavaDoc;
43 import java.lang.reflect.Method JavaDoc;
44 import java.lang.reflect.Modifier JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.Iterator JavaDoc;
48 import java.util.regex.Matcher JavaDoc;
49 import java.util.regex.Pattern JavaDoc;
50
51 /**
52  * @author <a HREF="mailto:kabirkhan@bigfoot.com">Kabir Khan</a>
53  * <p/>
54  * Aspect to intercept calls to the reflection API. Calls to
55  * Class.newInstance(), Field.setXXX(), Field.getXXX(), Constructor.newInstance()
56  * don't get intercepted even though the underlying constructor/field
57  * might have an advice associated with it. This class adds advices to help intercept these
58  * calls and attach to the original chains on the caller or target object. Method.invoke()
59  * works for chains on the target object "out of the box", but bypasses caller chains.
60  * <p/>
61  * <BR>
62  * <BR>
63  * Also, Class.getMethods(), Class.getDeclaredMethods(), Class.getInterfaces(),
64  * and Class.getDeclaredFields() return extra methods/interfaces/fields added
65  * by the AOP framework. The aspects contained here cleans this information.
66  */

67 public class ReflectionAspect
68 {
69    // Constants -----------------------------------------------------
70

71    // Attributes ----------------------------------------------------
72

73    // Static --------------------------------------------------------
74

75    private static Pattern JavaDoc fieldGetPattern =
76    Pattern.compile("get(|Boolean|Byte|Char|Double|Float|Int|Long|Short)?");
77
78    private static Pattern JavaDoc fieldSetPattern =
79    Pattern.compile("set(|Boolean|Byte|Char|Double|Float|Int|Long|Short)?");
80
81    private static Pattern JavaDoc accessMethodPattern = Pattern.compile("access[$](\\d)+");
82    
83    // Constructors --------------------------------------------------
84

85    public ReflectionAspect()
86    {
87    }
88    
89    // Public --------------------------------------------------------
90

91    /**
92     * Advice for calls to Class.newInstance() and Constructor.newInstance(). Intended use is for
93     * caller pointcuts. If you wish to handle the intercepted calls, override interceptConstructor.
94     *
95     * @param invocation
96     * @return result of invocation
97     * @throws Throwable
98     * @see ReflectionAspect#interceptConstructor(Invocation, Constructor, Object[])
99     */

100    public Object JavaDoc interceptNewInstance(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
101    {
102
103       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
104       Object JavaDoc targetObject = invocation.getTargetObject();
105       Object JavaDoc[] args = invocation.getArguments();
106
107       return interceptNewInstance(invocation, reflectionMethod, targetObject, args);
108    }
109
110    /**
111     * Advice for calls to Class.newInstance() and Constructor.newInstance(). Intended use is for
112     * caller pointcuts. If you wish to handle the intercepted calls, override interceptConstructor.
113     *
114     * @param invocation
115     * @return result of invocation
116     * @throws Throwable
117     * @see ReflectionAspect#interceptConstructor(Invocation, Constructor, Object[])
118     */

119    public Object JavaDoc interceptNewInstance(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
120    {
121
122       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
123       Object JavaDoc targetObject = invocation.getTargetObject();
124       Object JavaDoc[] args = invocation.getArguments();
125
126       return interceptNewInstance(invocation, reflectionMethod, targetObject, args);
127    }
128
129
130    /**
131     * Advice for calls to Method.invoke(). Intended use is for
132     * caller pointcuts. If you wish to handle the intercepted calls, override interceptMethod.
133     *
134     * @param invocation
135     * @return result of invocation
136     * @throws Throwable
137     * @see ReflectionAspect#interceptMethod(Invocation, Object, Method, Object[])
138     */

139    public Object JavaDoc interceptMethodInvoke(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
140    {
141
142       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
143       Object JavaDoc targetObject = invocation.getTargetObject();
144       Object JavaDoc[] args = invocation.getArguments();
145
146       return interceptMethodInvoke(invocation, reflectionMethod, targetObject, args);
147    }
148
149    /**
150     * Advice for calls to Class.newInstance() and Constructor.newInstance(). Intended use is for
151     * caller pointcuts. If you wish to handle the intercepted calls, override interceptMethod.
152     *
153     * @param invocation
154     * @return result of invocation
155     * @throws Throwable
156     * @see ReflectionAspect#interceptMethod(Invocation, Object, Method, Object[])
157     */

158    public Object JavaDoc interceptMethodInvoke(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
159    {
160
161       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
162       Object JavaDoc targetObject = invocation.getTargetObject();
163       Object JavaDoc[] args = invocation.getArguments();
164
165       return interceptMethodInvoke(invocation, reflectionMethod, targetObject, args);
166    }
167
168
169    /**
170     * Advice for calls to Field.setXXX(). Intended use is for caller pointcuts. If you wish to handle
171     * the intercepted calls, override interceptFieldWrite.
172     *
173     * @param invocation
174     * @return result of invocation
175     * @throws Throwable
176     * @see ReflectionAspect#interceptFieldWrite(Invocation, Field, Object, Object)
177     */

178    public Object JavaDoc interceptFieldSet(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
179    {
180
181       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
182       Object JavaDoc targetObject = invocation.getTargetObject();
183       Object JavaDoc[] args = invocation.getArguments();
184
185       return interceptFieldSet(invocation, reflectionMethod, targetObject, args);
186    }
187
188    /**
189     * Advice for calls to Field.setXXX(). Intended use is for caller pointcuts. If you wish to handle
190     * the intercepted calls, override interceptFieldWrite.
191     *
192     * @param invocation
193     * @return result of invocation
194     * @throws Throwable
195     * @see ReflectionAspect#interceptFieldWrite(Invocation, Field, Object, Object)
196     */

197    public Object JavaDoc interceptFieldSet(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
198    {
199
200       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
201       Object JavaDoc targetObject = invocation.getTargetObject();
202       Object JavaDoc[] args = invocation.getArguments();
203
204       return interceptFieldSet(invocation, reflectionMethod, targetObject, args);
205    }
206
207    /**
208     * Advice for calls to Field.getXXX(). Intended use is for caller pointcuts. If you wish to handle
209     * the intercepted calls, override interceptFieldRead.
210     *
211     * @param invocation
212     * @return The value of the field (or whatever you choose)
213     * @throws Throwable
214     * @see ReflectionAspect#interceptFieldRead(Invocation, Field, Object)
215     */

216    public Object JavaDoc interceptFieldGet(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
217    {
218
219       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
220       Object JavaDoc targetObject = invocation.getTargetObject();
221       Object JavaDoc[] args = invocation.getArguments();
222
223       return interceptFieldGet(invocation, reflectionMethod, targetObject, args);
224    }
225
226
227    /**
228     * Advice for calls to Field.getXXX(). Intended use is for caller pointcuts. If you wish to handle
229     * the intercepted calls, override interceptFieldRead.
230     *
231     * @param invocation
232     * @return The value of the field (or whatever you choose)
233     * @throws Throwable
234     * @see ReflectionAspect#interceptFieldRead(Invocation, Field, Object)
235     */

236    public Object JavaDoc interceptFieldGet(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
237    {
238
239
240       Method JavaDoc reflectionMethod = invocation.getCalledMethod();
241       Object JavaDoc targetObject = invocation.getTargetObject();
242       Object JavaDoc[] args = invocation.getArguments();
243
244       return interceptFieldGet(invocation, reflectionMethod, targetObject, args);
245    }
246
247
248    /**
249     * Advice for calls to Class.getDeclaredMethods(). Cleans methods that get added to the
250     * class by the AOP framework (Methods introduced by introductions/mixin classes will
251     * still be returned). Intended use is for caller pointcuts.
252     *
253     * @param invocation The invocation
254     * @return java.lang.reflect.Method[] containing the declared methods of the class
255     * @throws Throwable
256     * @see Class#getDeclaredMethods()()
257     */

258    public final Object JavaDoc interceptGetDeclaredMethods(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
259    {
260
261       Object JavaDoc targetObject = invocation.getTargetObject();
262       return interceptGetDeclaredMethods((Class JavaDoc) targetObject);
263    }
264
265    /**
266     * Advice for calls to Class.getDeclaredMethods(). Cleans methods that get added to the
267     * class by the AOP framework (Methods introduced by introductions/mixin classes will
268     * still be returned). Intended use is for caller pointcuts.
269     *
270     * @param invocation The invocation
271     * @return java.lang.reflect.Method[] containing the declared methods of the class
272     * @throws Throwable
273     * @see Class#getDeclaredMethods()()
274     */

275    public final Object JavaDoc interceptGetDeclaredMethods(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
276    {
277
278       Object JavaDoc targetObject = invocation.getTargetObject();
279       return interceptGetDeclaredMethods((Class JavaDoc) targetObject);
280    }
281
282    /**
283     * Advice for calls to Class.getDeclaredMethod(). Cleans methods that get added to the
284     * class by the AOP framework (Methods introduced by introductions/mixin classes will
285     * still be returned). Intended use is for caller pointcuts.
286     *
287     * @param invocation The invocation
288     * @return java.lang.reflect.Method the declared method
289     * @throws Throwable
290     * @see Class#getDeclaredMethod()()
291     */

292    public final Object JavaDoc interceptGetDeclaredMethod(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
293    {
294
295       Object JavaDoc targetObject = invocation.getTargetObject();
296       Object JavaDoc[] args = invocation.getArguments();
297       return interceptGetDeclaredMethod((Class JavaDoc) targetObject, args);
298    }
299
300    /**
301     * Advice for calls to Class.getDeclaredMethod(). Cleans methods that get added to the
302     * class by the AOP framework (Methods introduced by introductions/mixin classes will
303     * still be returned). Intended use is for caller pointcuts.
304     *
305     * @param invocation The invocation
306     * @return java.lang.reflect.Method the declared method
307     * @throws Throwable
308     * @see Class#getDeclaredMethod()()
309     */

310    public final Object JavaDoc interceptGetDeclaredMethod(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
311    {
312
313       Object JavaDoc targetObject = invocation.getTargetObject();
314       Object JavaDoc[] args = invocation.getArguments();
315       return interceptGetDeclaredMethod((Class JavaDoc) targetObject, args);
316    }
317
318    /**
319     * Advice for calls to Class.getDeclaredMethod(). Cleans methods that get added to the
320     * class by the AOP framework (Methods introduced by introductions/mixin classes will
321     * still be returned). Intended use is for caller pointcuts.
322     *
323     * @param invocation The invocation
324     * @return java.lang.reflect.Method[] The methods of the class
325     * @throws Throwable
326     * @see Class#getDeclaredMethod()()
327     */

328    public final Object JavaDoc interceptGetMethods(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
329    {
330
331       Object JavaDoc targetObject = invocation.getTargetObject();
332       return interceptGetMethods((Class JavaDoc) targetObject);
333    }
334
335    /**
336     * Advice for calls to Class.getMethods(). Cleans methods that get added to the
337     * class by the AOP framework (Methods introduced by introductions/mixin classes will
338     * still be returned). Intended use is for caller pointcuts.
339     *
340     * @param invocation The invocation
341     * @return java.lang.reflect.Method[] The methods of the class
342     * @throws Throwable
343     * @see Class#getMethods()()
344     */

345    public final Object JavaDoc interceptGetMethods(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
346    {
347
348       Object JavaDoc targetObject = invocation.getTargetObject();
349       return interceptGetMethods((Class JavaDoc) targetObject);
350    }
351
352    /**
353     * Advice for calls to Class.getMethod(). Cleans methods that get added to the
354     * class by the AOP framework (Methods introduced by introductions/mixin classes will
355     * still be returned). Intended use is for caller pointcuts.
356     *
357     * @param invocation The invocation
358     * @return java.lang.reflect.Method The method
359     * @throws Throwable
360     * @see Class#getDeclaredMethod()()
361     */

362    public final Object JavaDoc interceptGetMethod(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
363    {
364
365       Object JavaDoc targetObject = invocation.getTargetObject();
366       Object JavaDoc[] args = invocation.getArguments();
367       return interceptGetMethod((Class JavaDoc) targetObject, args);
368    }
369
370    /**
371     * Advice for calls to Class.getMethod(). Cleans methods that get added to the
372     * class by the AOP framework (Methods introduced by introductions/mixin classes will
373     * still be returned). Intended use is for caller pointcuts.
374     *
375     * @param invocation The invocation
376     * @return java.lang.reflect.Method The method
377     * @throws Throwable
378     * @see Class#getDeclaredMethod()()
379     */

380    public final Object JavaDoc interceptGetMethod(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
381    {
382
383       Object JavaDoc targetObject = invocation.getTargetObject();
384       Object JavaDoc[] args = invocation.getArguments();
385       return interceptGetMethod((Class JavaDoc) targetObject, args);
386    }
387
388    /**
389     * Advice for calls to Class.getInterfaces(). Cleans interfaces that get added to the
390     * class by the AOP framework. (Interfaces introduced by introductions will
391     * still be returned). Intended use is for caller pointcuts.
392     *
393     * @param invocation The invocation
394     * @return java.lang.Class[] containing the interfaces of the class
395     * @throws Throwable
396     * @see Class#getInterfaces()
397     */

398    public final Object JavaDoc interceptGetInterfaces(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
399    {
400
401       Object JavaDoc targetObject = invocation.getTargetObject();
402       return interceptGetInterfaces((Class JavaDoc) targetObject);
403    }
404
405    /**
406     * Advice for calls to Class.getInterfaces(). Cleans interfaces that get added to the
407     * class by the AOP framework. (Interfaces introduced by introductions will
408     * still be returned). Intended use is for caller pointcuts.
409     *
410     * @param invocation The invocation
411     * @return java.lang.Class[] containing the interfaces of the class
412     * @throws Throwable
413     * @see Class#getInterfaces()
414     */

415    public final Object JavaDoc interceptGetInterfaces(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
416    {
417
418       Object JavaDoc targetObject = invocation.getTargetObject();
419       return interceptGetInterfaces((Class JavaDoc) targetObject);
420    }
421
422    /**
423     * Advice for calls to Class.getDeclaredClasses(). Cleans inner classes that get added to the
424     * class by the AOP framework. Intended use is for caller pointcuts.
425     *
426     * @param invocation The invocation
427     * @return java.lang.Class[] containing the Class objects representing inner classes of the class
428     * @throws Throwable
429     * @see Class#getDeclaredClasses()
430     */

431    public final Object JavaDoc interceptGetDeclaredClasses(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
432    {
433
434       Object JavaDoc targetObject = invocation.getTargetObject();
435       return interceptGetDeclaredClasses((Class JavaDoc) targetObject);
436    }
437
438    /**
439     * Advice for calls to Class.getDeclaredClasses(). Cleans inner classes that get added to the
440     * class by the AOP framework. Intended use is for caller pointcuts.
441     *
442     * @param invocation The invocation
443     * @return java.lang.Class[] containing the Class objects representing inner classes of the class
444     * @throws Throwable
445     * @see Class#getDeclaredClasses()
446     */

447    public final Object JavaDoc interceptGetDeclaredClasses(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
448    {
449
450       Object JavaDoc targetObject = invocation.getTargetObject();
451       return interceptGetDeclaredClasses((Class JavaDoc) targetObject);
452    }
453
454    /**
455     * Advice for calls to Class.getClasses(). Cleans inner classes that get added to the
456     * class by the AOP framework. Intended use is for caller pointcuts.
457     * Extra stuff only seems to get returned when using JRockit
458     *
459     * @param invocation The invocation
460     * @return java.lang.Class[] containing the Class objects representing inner classes of the class
461     * @throws Throwable
462     * @see Class#getClasses()
463     */

464    public final Object JavaDoc interceptGetClasses(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
465    {
466
467       Object JavaDoc targetObject = invocation.getTargetObject();
468       return interceptGetClasses((Class JavaDoc) targetObject);
469    }
470
471    /**
472     * Advice for calls to Class.getClasses(). Cleans inner classes that get added to the
473     * class by the AOP framework. Intended use is for caller pointcuts.
474     * Extra stuff only seems to get returned when using JRockit
475     *
476     * @param invocation The invocation
477     * @return java.lang.Class[] containing the Class objects representing inner classes of the class
478     * @throws Throwable
479     * @see Class#getDeclaredClasses()
480     */

481    public final Object JavaDoc interceptGetClasses(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
482    {
483       Object JavaDoc targetObject = invocation.getTargetObject();
484       return interceptGetClasses((Class JavaDoc) targetObject);
485    }
486
487    /**
488     * Advice for calls to Class.getDeclaredFields(). Cleans fields that get added to the
489     * class by the AOP framework. Intended use is for caller pointcuts.
490     *
491     * @param invocation The invocation
492     * @return java.lang.reflect.Field[] containing the Fields of the class
493     * @throws Throwable
494     * @see Class#getDeclaredClasses()
495     */

496    public final Object JavaDoc interceptGetDeclaredFields(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
497    {
498
499       Object JavaDoc targetObject = invocation.getTargetObject();
500       return interceptGetDeclaredFields((Class JavaDoc) targetObject);
501    }
502
503    /**
504     * Advice for calls to Class.getDeclaredFields(). Cleans fields that get added to the
505     * class by the AOP framework. Intended use is for caller pointcuts.
506     *
507     * @param invocation The invocation
508     * @return java.lang.reflect.Field[] containing the Fields of the class
509     * @throws Throwable
510     * @see Class#getDeclaredFields()
511     */

512    public final Object JavaDoc interceptGetDeclaredFields(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
513    {
514
515       Object JavaDoc targetObject = invocation.getTargetObject();
516       return interceptGetDeclaredFields((Class JavaDoc) targetObject);
517    }
518
519    /**
520     * Advice for calls to Class.getDeclaredField(). Cleans fields that get added to the
521     * class by the AOP framework. Intended use is for caller pointcuts.
522     *
523     * @param invocation The invocation
524     * @return java.lang.reflect.Field The Field
525     * @throws Throwable
526     * @see Class#getDeclaredField()
527     */

528    public final Object JavaDoc interceptGetDeclaredField(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
529    {
530
531       Object JavaDoc targetObject = invocation.getTargetObject();
532       Object JavaDoc[] args = invocation.getArguments();
533       return interceptGetDeclaredField((Class JavaDoc) targetObject, args);
534    }
535
536    /**
537     * Advice for calls to Class.getDeclaredField(). Cleans fields that get added to the
538     * class by the AOP framework. Intended use is for caller pointcuts.
539     *
540     * @param invocation The invocation
541     * @return java.lang.reflect.Field[] The Field
542     * @throws Throwable
543     * @see Class#getDeclaredField()
544     */

545    public final Object JavaDoc interceptGetDeclaredField(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
546    {
547       Object JavaDoc targetObject = invocation.getTargetObject();
548       Object JavaDoc[] args = invocation.getArguments();
549       return interceptGetDeclaredField((Class JavaDoc) targetObject, args);
550    }
551
552    /**
553     * Advice for calls to Class.getFields(). Cleans fields that get added to the
554     * class by the AOP framework. Intended use is for caller pointcuts.
555     *
556     * @param invocation The invocation
557     * @return java.lang.reflect.Field[] containing the Fields of the class
558     * @throws Throwable
559     * @see Class#getFields()
560     */

561    public final Object JavaDoc interceptGetFields(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
562    {
563
564       //Nothing seems to get added
565
return invocation.invokeNext();
566    }
567
568    /**
569     * Advice for calls to Class.getFields(). Cleans fields that get added to the
570     * class by the AOP framework. Intended use is for caller pointcuts.
571     *
572     * @param invocation The invocation
573     * @return java.lang.reflect.Field[] containing the Fields of the class
574     * @throws Throwable
575     * @see Class#getFields()
576     */

577    public final Object JavaDoc interceptGetFields(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
578    {
579
580       //Nothing seems to get added
581
return invocation.invokeNext();
582    }
583
584    /**
585     * Advice for calls to Class.getDeclaredConstructors(). Cleans constructors that get added to the
586     * class by the AOP framework. Intended use is for caller pointcuts.
587     *
588     * @param invocation The invocation
589     * @return java.lang.reflect.Constructor[] containing the Constructors of the class
590     * @throws Throwable
591     * @see Class#getDeclaredConstructors()
592     */

593    public final Object JavaDoc interceptGetDeclaredConstructors(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
594    {
595
596       //Nothing seems to get added
597
return invocation.invokeNext();
598    }
599
600    /**
601     * Advice for calls to Class.getDeclaredConstructors(). Cleans constructors that get added to the
602     * class by the AOP framework. Intended use is for caller pointcuts.
603     *
604     * @param invocation The invocation
605     * @return java.lang.reflect.Constructor[] containing the Constructors of the class
606     * @throws Throwable
607     * @see Class#getDeclaredConstructors()
608     */

609    public final Object JavaDoc interceptGetDeclaredConstructors(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
610    {
611
612       //Nothing seems to get added
613
return invocation.invokeNext();
614    }
615
616    /**
617     * Advice for calls to Class.getDeclaredConstructor(). Cleans constructors that get added to the
618     * class by the AOP framework. Intended use is for caller pointcuts.
619     *
620     * @param invocation The invocation
621     * @return java.lang.reflect.Constructor[] The constructor
622     * @throws Throwable
623     * @see Class#getFields()
624     */

625    public final Object JavaDoc interceptGetDeclaredConstructor(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
626    {
627
628       //Nothing seems to get added
629
return invocation.invokeNext();
630    }
631
632    /**
633     * Advice for calls to Class.getDeclaredConstructor(). Cleans constructors that get added to the
634     * class by the AOP framework. Intended use is for caller pointcuts.
635     *
636     * @param invocation The invocation
637     * @return java.lang.reflect.Constructor[] The constructor
638     * @throws Throwable
639     * @see Class#getFields()
640     */

641    public final Object JavaDoc interceptGetDeclaredConstructor(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
642    {
643
644       //Nothing seems to get added
645
return invocation.invokeNext();
646    }
647
648    /**
649     * Advice for calls to Class.getConstructors(). Cleans fields that get added to the
650     * class by the AOP framework. Intended use is for caller pointcuts.
651     *
652     * @param invocation The invocation
653     * @return java.lang.Constructor[] containing the Constructors of the class
654     * @throws Throwable
655     * @see Class#getFields()
656     */

657    public final Object JavaDoc interceptGetConstructors(MethodCalledByConstructorInvocation invocation) throws Throwable JavaDoc
658    {
659
660       //Nothing seems to get added
661
return invocation.invokeNext();
662    }
663
664    /**
665     * Advice for calls to Class.getConstructors(). Cleans constructors that get added to the
666     * class by the AOP framework. Intended use is for caller pointcuts.
667     *
668     * @param invocation The invocation
669     * @return java.lang.Constructor[] containing the Constructors of the class
670     * @throws Throwable
671     * @see Class#getFields()
672     */

673    public final Object JavaDoc interceptGetConstructors(MethodCalledByMethodInvocation invocation) throws Throwable JavaDoc
674    {
675
676       //Nothing seems to get added
677
return invocation.invokeNext();
678    }
679    
680
681    // Z implementation ----------------------------------------------
682

683    // Y overrides ---------------------------------------------------
684

685    // Package protected ---------------------------------------------
686

687    // Protected -----------------------------------------------------
688

689    
690    /**
691     * Overridable advice for a Constructor.newInstance() or Class.newInstance() call.
692     * Default behaviour is to first try to attach to any caller advice chain. If that
693     * does not exist, try to attach to the advice chains on the target object. And
694     * if that does not exist to invoke the reflected constructor.
695     *
696     * @param invocation The invocation
697     * @param constructor The field on which we are calling set
698     * @param args The arguments for the constructor
699     * @return The new instance
700     * @throws Throwable
701     */

702    protected Object JavaDoc interceptConstructor(Invocation invocation, Constructor JavaDoc constructor, Object JavaDoc[] args) throws Throwable JavaDoc
703    {
704       return invokeOriginalChainIfExists(invocation, constructor, args);
705    }
706
707    /**
708     * Overridable advice for a Field.setXXX() call.
709     * Default behaviour is to first try to attach to the advice chains on the target object. And
710     * if that does not exist to invoke the reflected field read.
711     *
712     * @param invocation The invocation
713     * @param field The field on which we are calling set
714     * @param instance The instance on which we want to write a field
715     * @return The value of the field (or whatever you choose)
716     * @throws Throwable
717     */

718    protected Object JavaDoc interceptFieldRead(Invocation invocation, Field JavaDoc field, Object JavaDoc instance) throws Throwable JavaDoc
719    {
720       return invokeOriginalChainIfExists(invocation, field, instance);
721    }
722
723    /**
724     * Overridable advice for a Field.setXXX() call.
725     * Default behaviour is to first try attach to the advice chains on the target object. And
726     * if that does not exist to invoke the reflected field write.
727     *
728     * @param invocation The invocation
729     * @param field The field on which we are calling set
730     * @param instance The instance on which we want to read a field
731     * @param arg The value we want to set the field to
732     * @return result of invocation
733     * @throws Throwable
734     */

735    protected Object JavaDoc interceptFieldWrite(Invocation invocation, Field JavaDoc field, Object JavaDoc instance, Object JavaDoc arg) throws Throwable JavaDoc
736    {
737       return invokeOriginalChainIfExists(invocation, field, instance, arg);
738    }
739
740    /**
741     * Overridable advice for a Method.invoke() call.
742     * Default behaviour is to first try to attach to any caller advice chain. If that
743     * does not exist, try to attach to the advice chains on the target object. And
744     * if that does not exist to invoke the reflected method.
745     *
746     * @param invocation The invocation
747     * @param method The method on which we are calling set
748     * @param instance The instance on which we want to read a field
749     * @param arg The value we want to set the field to
750     * @return result of invocation
751     * @throws Throwable
752     */

753    protected Object JavaDoc interceptMethod(Invocation invocation, Method JavaDoc method, Object JavaDoc instance, Object JavaDoc[] args) throws Throwable JavaDoc
754    {
755       return invokeOriginalChainIfExists(invocation, method, instance, args);
756    }
757    
758    
759    // Private -------------------------------------------------------
760

761    private Object JavaDoc interceptNewInstance(Invocation invocation,
762                                        Method JavaDoc reflectionMethod,
763                                        Object JavaDoc targetObject,
764                                        Object JavaDoc[] args) throws Throwable JavaDoc
765    {
766       Class JavaDoc reflectionClass = targetObject.getClass();
767
768       if (reflectionClass.equals(Class JavaDoc.class))
769       {
770
771          //For our purposes Class.newInstance() can be made into a call to the empty constructor
772
Constructor JavaDoc constructor = ((Class JavaDoc) targetObject).getConstructor(new Class JavaDoc[0]);
773          return interceptConstructor(invocation, constructor, args);
774       }
775       else if (reflectionClass.equals(Constructor JavaDoc.class))
776       {
777
778          if (reflectionMethod.getName().equals("newInstance"))
779          {
780             //Object newObject = args[0];
781

782             Object JavaDoc[] constructorArgs;
783
784             int length = args.length;
785
786             if (length < 1)
787             {
788                constructorArgs = new Object JavaDoc[0];
789             }
790             else
791             {
792                constructorArgs = (Object JavaDoc[]) args[0];
793             }
794
795             Constructor JavaDoc constructor = (Constructor JavaDoc) targetObject;
796             return interceptConstructor(invocation, constructor, constructorArgs);
797          }
798       }
799
800       return invocation.invokeNext();
801    }
802
803    private Object JavaDoc interceptMethodInvoke(Invocation invocation,
804                                         Method JavaDoc reflectionMethod,
805                                         Object JavaDoc targetObject,
806                                         Object JavaDoc[] args) throws Throwable JavaDoc
807    {
808       Method JavaDoc method = (Method JavaDoc) invocation.getTargetObject();
809       if (reflectionMethod.getName().equals("invoke"))
810       {
811          Object JavaDoc instance = args[0];
812          return interceptMethod(invocation, method, instance, (Object JavaDoc[]) args[1]);
813       }
814       return invocation.invokeNext();
815    }
816
817    private Class JavaDoc[] interceptGetInterfaces(Class JavaDoc clazz)
818    {
819       Class JavaDoc[] interfaces = clazz.getInterfaces();
820       ArrayList JavaDoc cleanedInterfaces = new ArrayList JavaDoc(interfaces.length);
821
822       for (int i = 0; i < interfaces.length; i++)
823       {
824          if (!interfaces[i].equals(Advised.class))
825          {
826             cleanedInterfaces.add(interfaces[i]);
827          }
828       }
829
830       return (Class JavaDoc[]) cleanedInterfaces.toArray(new Class JavaDoc[cleanedInterfaces.size()]);
831    }
832
833    private Object