KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > advice > GeneratedAdvisorInterceptor


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.advice;
23
24 import java.lang.reflect.Field JavaDoc;
25 import java.lang.reflect.Modifier JavaDoc;
26
27 import org.jboss.aop.Advisor;
28 import org.jboss.aop.AspectManager;
29 import org.jboss.aop.ClassAdvisor;
30 import org.jboss.aop.ClassInstanceAdvisor;
31 import org.jboss.aop.GeneratedClassAdvisor;
32 import org.jboss.aop.GeneratedInstanceAdvisorMixin;
33 import org.jboss.aop.InstanceAdvisor;
34 import org.jboss.aop.joinpoint.ConstructionInvocation;
35 import org.jboss.aop.joinpoint.ConstructorCalledByConstructorInvocation;
36 import org.jboss.aop.joinpoint.ConstructorCalledByConstructorJoinpoint;
37 import org.jboss.aop.joinpoint.ConstructorCalledByMethodInvocation;
38 import org.jboss.aop.joinpoint.ConstructorCalledByMethodJoinpoint;
39 import org.jboss.aop.joinpoint.ConstructorInvocation;
40 import org.jboss.aop.joinpoint.ConstructorJoinpoint;
41 import org.jboss.aop.joinpoint.FieldInvocation;
42 import org.jboss.aop.joinpoint.FieldJoinpoint;
43 import org.jboss.aop.joinpoint.Invocation;
44 import org.jboss.aop.joinpoint.Joinpoint;
45 import org.jboss.aop.joinpoint.MethodCalledByConstructorInvocation;
46 import org.jboss.aop.joinpoint.MethodCalledByConstructorJoinpoint;
47 import org.jboss.aop.joinpoint.MethodCalledByMethodInvocation;
48 import org.jboss.aop.joinpoint.MethodCalledByMethodJoinpoint;
49 import org.jboss.aop.joinpoint.MethodInvocation;
50 import org.jboss.aop.joinpoint.MethodJoinpoint;
51 import org.jboss.aop.pointcut.ast.ASTCFlowExpression;
52
53 /**
54  * Special interceptor wrapping the interceptor factory, so that generated advisors have
55  * all the information they need about the contained advices for generating the invocation
56  * methods.
57  * If we are invoked upon dymamically we use vanilla invocations, i.e. the generated invocation code
58  * does not step in, so we generate the interceptor class as and when needed in our invoke() method.
59  *
60  * Old skool class advisors do not use this class
61  *
62  * @author <a HREF="kabir.khan@jboss.com">Kabir Khan</a>
63  * @version $Revision: 46117 $
64  */

65 public class GeneratedAdvisorInterceptor implements Interceptor
66 {
67    private InterceptorFactory factory;
68    private volatile Object JavaDoc instance;
69    private String JavaDoc cflowString;
70    private ASTCFlowExpression cflowExpression;
71    
72    /**
73     * The interceptor that is used if and only if we invoke dynamically
74     */

75    volatile Interceptor lazyInterceptor;
76    
77    public GeneratedAdvisorInterceptor(
78          InterceptorFactory factory,
79          GeneratedClassAdvisor advisor,
80          Joinpoint joinpoint,
81          String JavaDoc cflowString,
82          ASTCFlowExpression cflowExpr)
83    {
84       this(factory, advisor, joinpoint);
85       this.cflowString = cflowString;
86       this.cflowExpression = cflowExpr;
87    }
88    
89    public GeneratedAdvisorInterceptor(InterceptorFactory factory, GeneratedClassAdvisor advisor, Joinpoint joinpoint)
90    {
91       this.factory = factory;
92       
93       if (!(factory instanceof GenericInterceptorFactory))
94       {
95          if (getScope() == Scope.PER_INSTANCE)
96          {
97             if (!advisor.getPerInstanceAspectDefinitions().contains(factory.getAspect()))
98             {
99                advisor.addPerInstanceAspect(factory.getAspect());
100             }
101          }
102          else if (getScope() == Scope.PER_JOINPOINT)
103          {
104             advisor.addPerInstanceJoinpointAspect(joinpoint, factory.getAspect());
105          }
106          else if (getScope() == Scope.PER_CLASS_JOINPOINT)
107          {
108             if (advisor.getPerClassJoinpointAspect(factory.getAspect(), joinpoint) == null)
109             {
110                advisor.addPerClassJoinpointAspect(factory.getAspect(), joinpoint);
111             }
112          }
113       }
114    }
115
116    public Interceptor create(Advisor advisor, Joinpoint joinpoint)
117    {
118       return factory.create(advisor, joinpoint);
119    }
120
121    /**
122     * Used to obtain aspects from the generated code at runtime for joinpoints/aspects requiring an instance advisor
123     */

124    public Object JavaDoc getAspect(Advisor advisor, Joinpoint joinpoint)
125    {
126       return getAspect(advisor, joinpoint, false);
127    }
128    
129    /**
130     * Also used as a convenience method to create aspect instances for the JoinPointGenerator in order to figure
131     * out what the class of the aspect should be when making the call from the generated joinpoint class.
132     * PER_INSTANCE or PER_JOINPOINT (for non-static fields) aspects cannot be created "properly"
133     * until at runtime, since that requires access to the instance advisor. If forCodeGeneration
134     * is true we create a temporary InstanceAdvisor to avoid NPEs in case we are calling an
135     * AspectFactory needing access to the instance advisor
136     */

137    public Object JavaDoc getAspect(Advisor advisor, Joinpoint joinpoint, boolean forCodeGeneration)
138    {
139       if (factory instanceof GenericInterceptorFactory)
140       {
141          if (instance == null)
142          {
143             instance = ((GenericInterceptorFactory)factory).create(advisor, joinpoint);
144          }
145          return instance;
146       }
147       else if (factory instanceof GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)
148       {
149          return ((GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)factory).create(advisor, joinpoint);
150       }
151       else if (factory instanceof ScopedInterceptorFactory || factory instanceof AdviceFactory)
152       {
153          ClassInstanceAdvisor temp = (forCodeGeneration) ? new ClassInstanceAdvisor(advisor) : null;
154          return getAspectInstance(factory.getAspect(), advisor, joinpoint, temp);
155       }
156       
157       return null;
158    }
159    
160    /**
161     * Used to obtain aspects from the generated code at runtime for joinpoints/aspects requiring an instance advisor
162     */

163    public Object JavaDoc getPerInstanceAspect(Advisor advisor, Joinpoint joinpoint, InstanceAdvisor ia)
164    {
165       if (factory instanceof GenericInterceptorFactory)
166       {
167          if (instance == null)
168          {
169             instance = ((GenericInterceptorFactory)factory).create(advisor, joinpoint);
170          }
171          return instance;
172       }
173       else if (factory instanceof ScopedInterceptorFactory || factory instanceof AdviceFactory)
174       {
175          return getAspectInstance(factory.getAspect(), advisor, joinpoint, ia);
176       }
177       
178       return null;
179    }
180    
181    private Object JavaDoc getAspectInstance(AspectDefinition def, Advisor advisor, Joinpoint joinpoint, InstanceAdvisor ia)
182    {
183       if (def.getScope() == Scope.PER_VM)
184       {
185          if (instance == null)
186          {
187             instance = advisor.getManager().getPerVMAspect(def);
188          }
189          return instance;
190       }
191       else if (def.getScope() == Scope.PER_CLASS)
192       {
193          if (instance == null)
194          {
195             instance = advisor.getPerClassAspect(def);
196             if (instance != null)
197             {
198                return instance;
199             }
200             advisor.addPerClassAspect(def);
201             instance = advisor.getPerClassAspect(def);
202          }
203          return instance;
204       }
205       else if (def.getScope() == Scope.PER_INSTANCE)
206       {
207          return getPerInstanceAspect(def, advisor, joinpoint, ia);
208       }
209       else if (def.getScope() == Scope.PER_JOINPOINT)
210       {
211          return getPerJoinPointAspect(def, advisor, joinpoint, ia);
212       }
213       else if (def.getScope() == Scope.PER_CLASS_JOINPOINT)
214       {
215          if (instance == null)
216          {
217             instance = ((GeneratedClassAdvisor)advisor).getPerClassJoinpointAspect(def, joinpoint);
218             if (instance != null)
219             {
220                return instance;
221             }
222             
223             ((GeneratedClassAdvisor)advisor).addPerClassJoinpointAspect(def, joinpoint);
224             instance = ((GeneratedClassAdvisor)advisor).getPerClassJoinpointAspect(def, joinpoint);
225          }
226          return instance;
227       }
228       else
229       {
230          //if (aspect.getScope() == null) System.err.println("scope is null: " + aspect.getName() + "." + advice);
231
}
232       return null;
233    }
234
235    private Object JavaDoc getPerJoinPointAspect(AspectDefinition def, Advisor advisor, Joinpoint joinpoint, InstanceAdvisor ia)
236    {
237       if (ia == null)
238       {
239          if (instance == null)
240          {
241             //Used by JoinPointGenerator at code generation time
242
if (AspectManager.verbose)
243             {
244                System.out.println("[info] Calling create on PER_JOINPOINT scoped AspectFactory with no InstanceAdvisor as part of setup");
245             }
246             
247             if (joinpoint instanceof FieldJoinpoint)
248             {
249                Field JavaDoc field = ((FieldJoinpoint)joinpoint).getField();
250                if (Modifier.isStatic(field.getModifiers()))
251                {
252                   instance = ((ClassAdvisor)advisor).getFieldAspect((FieldJoinpoint)joinpoint, def);
253                }
254             }
255
256             if (instance == null)
257             {
258                instance = def.getFactory().createPerJoinpoint(advisor, ia, joinpoint);
259             }
260          }
261          return instance;
262       }
263       else
264       {
265          //Used by code generated by JoinPointGenerator at runtime
266
return ia.getPerInstanceJoinpointAspect(joinpoint, def);
267       }
268    }
269    
270    private Object JavaDoc getPerInstanceAspect(AspectDefinition def, Advisor advisor, Joinpoint joinpoint, InstanceAdvisor ia)
271    {
272       if (ia == null)
273       {
274          //Used by JoinPointGenerator at code generation time
275
if (AspectManager.verbose)
276          {
277             System.out.println("[info] Calling create on PER_INSTANCE scoped AspectFactory with no InstanceAdvisor as part of setup");
278          }
279          return def.getFactory().createPerInstance(advisor, ia);
280       }
281       else
282       {
283          return ia.getPerInstanceAspect(def);
284       }
285    }
286    
287    public boolean isAspectFactory()
288    {
289       if (factory instanceof GenericInterceptorFactory || factory instanceof GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)
290       {
291          return false;
292       }
293       else
294       {
295          return !(factory.getAspect().getFactory() instanceof GenericAspectFactory);
296       }
297    }
298
299    public InterceptorFactory getDelegate()
300    {
301       return factory;
302    }
303    
304    public AspectDefinition getAspect()
305    {
306       return factory.getAspect();
307    }
308
309    public String JavaDoc getName()
310    {
311       return factory.getName();
312    }
313    
314    public String JavaDoc getAspectClassName()
315    {
316       if (factory instanceof GenericInterceptorFactory)
317       {
318          //Dynamically added interceptors
319
return ((GenericInterceptorFactory)factory).getClassName();
320       }
321       else if (factory instanceof GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)
322       {
323          return ((GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)factory).getClassName();
324       }
325       else
326       {
327          AspectFactory af = factory.getAspect().getFactory();
328          
329          if (af instanceof AspectFactoryDelegator)
330          {
331             return ((AspectFactoryDelegator)af).getName();
332          }
333          else
334          {
335             return ((GenericAspectFactory)af).getName();
336          }
337       }
338    }
339    
340    public boolean isBefore()
341    {
342       return factory instanceof BeforeFactory;
343    }
344    
345    public boolean isAfter()
346    {
347       return factory instanceof AfterFactory;
348    }
349    
350    public boolean isThrowing()
351    {
352       return factory instanceof ThrowingFactory;
353    }
354    
355    public boolean isAround()
356    {
357       return !isBefore() && !isAfter() && ! isThrowing();
358    }
359    
360    public boolean isInterceptor()
361    {
362       if (factory instanceof AdviceFactory)
363       {
364          return false;
365       }
366       return true;
367    }
368    
369    public String JavaDoc getAdviceName()
370    {
371       if (factory instanceof AdviceFactory)
372       {
373          return ((AdviceFactory)factory).getAdvice();
374       }
375       
376       return "invoke";
377    }
378    
379    public Scope getScope()
380    {
381       if (factory instanceof GenericInterceptorFactory || factory instanceof GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)
382       {
383          return null;
384       }
385       else
386       {
387          return factory.getAspect().getScope();
388       }
389    }
390    
391    public String JavaDoc getRegisteredName()
392    {
393       if (factory instanceof GenericInterceptorFactory || factory instanceof GeneratedInstanceAdvisorMixin.InstanceInterceptorFactory)
394       {
395          return null;
396       }
397       else
398       {
399          return factory.getAspect().getName();
400       }
401    }
402
403    public ASTCFlowExpression getCflowExpression()
404    {
405       return cflowExpression;
406    }
407
408    public String JavaDoc getCFlowString()
409    {
410       return cflowString;
411    }
412
413    public boolean equals(Object JavaDoc obj)
414    {
415       if (!(obj instanceof GeneratedAdvisorInterceptor)) return false;
416       return this.factory.equals(((GeneratedAdvisorInterceptor)obj).getDelegate());
417    }
418
419    public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
420    {
421       if (lazyInterceptor == null)
422       {
423          synchronized (this)
424          {
425             if (lazyInterceptor == null)
426             {
427                if (factory instanceof GeneratedOnly)
428                {
429                   lazyInterceptor = new GeneratedOnlyInterceptor(factory.getName(), (GeneratedOnly)factory);
430                }
431                else
432                {
433                   lazyInterceptor = create(invocation.getAdvisor(), getJoinpoint(invocation));
434                }
435             }
436          }
437       }
438       return lazyInterceptor.invoke(invocation);
439    }
440
441    private Joinpoint getJoinpoint(Invocation invocation)
442    {
443       if (invocation instanceof MethodInvocation)
444       {
445          return new MethodJoinpoint(((MethodInvocation)invocation).getMethod());
446       }
447       if (invocation instanceof FieldInvocation)
448       {
449          return new FieldJoinpoint(((FieldInvocation)invocation).getField());
450       }
451       if (invocation instanceof ConstructorInvocation)
452       {
453          return new ConstructorJoinpoint(((ConstructorInvocation)invocation).getConstructor());
454       }
455       if (invocation instanceof ConstructionInvocation)
456       {
457          return new ConstructorJoinpoint(((ConstructionInvocation)invocation).getConstructor());
458       }
459       if (invocation instanceof MethodCalledByMethodInvocation)
460       {
461          return new MethodCalledByMethodJoinpoint(((MethodCalledByMethodInvocation)invocation).getCallingMethod(), ((MethodCalledByMethodInvocation)invocation).getCalledMethod());
462       }
463       if (invocation instanceof MethodCalledByConstructorInvocation)
464       {
465          return new MethodCalledByConstructorJoinpoint(((MethodCalledByConstructorInvocation)invocation).getCalling(), ((MethodCalledByConstructorInvocation)invocation).getCalledMethod());
466       }
467       if (invocation instanceof ConstructorCalledByMethodInvocation)
468       {
469          return new ConstructorCalledByMethodJoinpoint(((ConstructorCalledByMethodInvocation)invocation).getCallingMethod(), ((ConstructorCalledByMethodInvocation)invocation).getCalledConstructor());
470       }
471       if (invocation instanceof ConstructorCalledByConstructorInvocation)
472       {
473          return new ConstructorCalledByConstructorJoinpoint(((ConstructorCalledByConstructorInvocation)invocation).getCallingConstructor(), ((ConstructorCalledByConstructorInvocation)invocation).getCalledConstructor());
474       }
475       
476       throw new RuntimeException JavaDoc("Invocation type not handled " + invocation);
477    }
478    
479    private class GeneratedOnlyInterceptor implements Interceptor
480    {
481       String JavaDoc name;
482       String JavaDoc type;
483       
484       GeneratedOnlyInterceptor(String JavaDoc name, GeneratedOnly factory)
485       {
486          this.name = name;
487
488          if (factory instanceof BeforeFactory)
489          {
490             type = "before";
491          }
492          else if (factory instanceof AfterFactory)
493          {
494             type = "after";
495          }
496          else if (factory instanceof ThrowingFactory)
497          {
498             type = "throwing";
499          }
500          System.out.println("[warn] " + type + " interceptor:s'" + name + "' is ignored for dynamic invocation. Adding null GeneratedOnlyInterceptor in its place");
501       }
502       
503       public String JavaDoc getName()
504       {
505          return name;
506       }
507
508       public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
509       {
510          return invocation.invokeNext();
511       }
512       
513    }
514 }
515
Popular Tags