KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > instrument > JoinPointGenerator


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.instrument;
23
24 import java.lang.reflect.Constructor JavaDoc;
25 import java.lang.reflect.Field JavaDoc;
26 import java.security.AccessController JavaDoc;
27 import java.security.PrivilegedActionException JavaDoc;
28 import java.security.PrivilegedExceptionAction JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.HashMap JavaDoc;
31
32 import javassist.CannotCompileException;
33 import javassist.ClassPool;
34 import javassist.CtClass;
35 import javassist.CtConstructor;
36 import javassist.CtField;
37 import javassist.CtMethod;
38 import javassist.CtNewConstructor;
39 import javassist.CtNewMethod;
40 import javassist.Modifier;
41 import javassist.NotFoundException;
42
43 import org.jboss.aop.AspectManager;
44 import org.jboss.aop.CallerConstructorInfo;
45 import org.jboss.aop.GeneratedClassAdvisor;
46 import org.jboss.aop.InstanceAdvisor;
47 import org.jboss.aop.JoinPointInfo;
48 import org.jboss.aop.advice.AdviceMethodFactory;
49 import org.jboss.aop.advice.AdviceMethodProperties;
50 import org.jboss.aop.advice.GeneratedAdvisorInterceptor;
51 import org.jboss.aop.advice.Scope;
52 import org.jboss.aop.joinpoint.Invocation;
53 import org.jboss.aop.pointcut.ast.ASTCFlowExpression;
54 import org.jboss.aop.pointcut.ast.ClassExpression;
55 import org.jboss.aop.util.JavassistUtils;
56 import org.jboss.aop.util.ReflectToJavassist;
57
58 /** Creates the Joinpoint invocation replacement classes used with Generated advisors
59  *
60  * @author <a HREF="kabir.khan@jboss.com">Kabir Khan</a>
61  * @version $Revision$
62  */

63 public abstract class JoinPointGenerator
64 {
65    public static final String JavaDoc INFO_FIELD = "info";
66    public static final String JavaDoc INVOKE_JOINPOINT = "invokeJoinpoint";
67    public static final String JavaDoc INVOKE_TARGET = "invokeTarget";
68    public static final String JavaDoc DISPATCH = "dispatch";
69    protected static final String JavaDoc TARGET_FIELD = "tgt";
70    protected static final String JavaDoc GENERATED_CLASS_ADVISOR = GeneratedClassAdvisor.class.getName();
71    public static final String JavaDoc GENERATE_JOINPOINT_CLASS = "generateJoinPointClass";
72    private static final String JavaDoc CURRENT_ADVICE = "super.currentInterceptor";
73    public static final String JavaDoc JOINPOINT_FIELD_PREFIX = "joinpoint_";
74    public static final String JavaDoc JOINPOINT_CLASS_PREFIX = "JoinPoint_";
75    public static final String JavaDoc GENERATOR_PREFIX = "generator_";
76    private static final String JavaDoc RETURN_VALUE = "ret";
77    private static final String JavaDoc THROWABLE = "t";
78    protected static final CtClass[] EMPTY_CTCLASS_ARRAY = new CtClass[0];
79
80    private JoinPointInfo oldInfo;
81    protected JoinPointInfo info;
82    private static int increment;
83    private Class JavaDoc advisorClass;
84    protected GeneratedClassAdvisor advisor;
85    protected String JavaDoc joinpointClassName;
86    protected String JavaDoc joinpointFieldName;
87    private String JavaDoc joinpointFqn;
88    private Field JavaDoc joinpointField;
89    private Field JavaDoc generatorField;
90    private boolean initialised;
91    
92    public JoinPointGenerator(GeneratedClassAdvisor advisor, JoinPointInfo info)
93    {
94       this.info = info;
95       this.advisor = advisor;
96       this.advisorClass = advisor.getClass();
97       Class JavaDoc[] interfaces = advisorClass.getInterfaces();
98       
99       for (int i = 0 ; i < interfaces.length ; i++)
100       {
101          if (interfaces[i].equals(InstanceAdvisor.class))
102          {
103             //The InstanceAdvisor extends the Advisor, which is what contains the JoinPoint field
104
advisorClass = advisorClass.getSuperclass();
105             break;
106          }
107       }
108
109       initialiseJoinPointNames();
110    
111       findAdvisedField(advisorClass, info);
112    }
113    
114    public void rebindJoinpoint(JoinPointInfo newInfo)
115    {
116       try
117       {
118          if (joinpointField == null) return;
119          if (initialised && oldInfo != null)
120          {
121             //We are not changing any of the bindings
122
if (oldInfo.equalChains(newInfo)) return;
123          }
124          oldInfo = info.copy();
125          info = newInfo;
126
127          joinpointField.set(advisor, null);
128
129          if (info.getInterceptors() == null)
130          {
131             //Turn off interceptions, by setting the generator to null
132
generatorField.set(advisor, null);
133          }
134          else
135          {
136             generatorField.set(advisor, this);
137          }
138       }
139       catch (Exception JavaDoc e)
140       {
141          throw new RuntimeException JavaDoc(e);
142       }
143    }
144       
145    /**
146     * Called by the joinpoint if a interceptors were regenereated
147     */

148    public synchronized void generateJoinPointClass()
149    {
150       if (System.getSecurityManager() == null)
151       {
152          GenerateJoinPointClassAction.NON_PRIVILEGED.generateJoinPointClass(this);
153       }
154       else
155       {
156          GenerateJoinPointClassAction.PRIVILEGED.generateJoinPointClass(this);
157       }
158    }
159     
160    /**
161     * Does the work for generateJoinPointClass()
162     * @see JoinPointGenerator#generateJoinPointClass()
163     */

164    private void doGenerateJoinPointClass()
165    {
166       try
167       {
168          if (joinpointField.get(advisor) != null)
169          {
170             //someone beat us to generating the class
171
return;
172          }
173          AspectManager manager = AspectManager.instance();
174          ClassPool pool = manager.findClassPool(Thread.currentThread().getContextClassLoader());
175          GeneratedClassInfo generatedClass = generateJoinpointClass(pool, info);
176          
177          Class JavaDoc clazz = toClass(pool, generatedClass.getGenerated());
178          Object JavaDoc obj = instantiateClass(clazz, generatedClass.getAroundSetups());
179          
180          joinpointField.set(advisor, obj);
181       }
182       catch (Throwable JavaDoc e)
183       {
184          // AutoGenerated
185
throw new RuntimeException JavaDoc("Error generating joinpoint class for joinpoint " + info, e);
186       }
187       initialised = true;
188    }
189
190    private Class JavaDoc toClass(ClassPool pool, CtClass ctclass) throws NotFoundException, CannotCompileException, ClassNotFoundException JavaDoc
191    {
192       return TransformerCommon.toClass(ctclass);
193    }
194    
195    private Object JavaDoc instantiateClass(Class JavaDoc clazz, AdviceSetup[] aroundSetups) throws Exception JavaDoc
196    {
197       Constructor JavaDoc ctor = clazz.getConstructor(new Class JavaDoc[] {info.getClass()});
198       Object JavaDoc obj;
199       try
200       {
201          obj = ctor.newInstance(new Object JavaDoc[] {info});
202       }
203       catch (Exception JavaDoc e)
204       {
205          StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
206          sb.append("\n\t\t" + Modifier.toString(clazz.getModifiers()) + " " + clazz.getName() + " " + clazz.getClassLoader() + "\n\t\t\textends\n");
207          clazz = clazz.getSuperclass();
208          sb.append("\t\t" + Modifier.toString(clazz.getModifiers()) + " " + clazz.getName() + " " + clazz.getClassLoader() + "\n");
209          Field JavaDoc[] fields = clazz.getDeclaredFields();
210          for (int i = 0 ; i < fields.length ; i++)
211          {
212             sb.append("\n\t\t\t" + Modifier.toString(fields[i].getModifiers()) + " " + fields[i].getType().getName() + " " + fields[i].getName() + " " + fields[i].getType().getClassLoader());
213          }
214          throw new RuntimeException JavaDoc(sb.toString(), e);
215       }
216       
217       for (int i = 0 ; i < aroundSetups.length ; i++)
218       {
219          if (aroundSetups[i].isNewCFlow())
220          {
221             Field JavaDoc field = clazz.getDeclaredField("cflow" + aroundSetups[i].useCFlowFrom());
222             field.setAccessible(true);
223             field.set(obj, aroundSetups[i].getCFlow());
224          }
225       }
226       return obj;
227    }
228     
229    private static synchronized int getIncrement()
230    {
231       return ++increment;
232    }
233    
234    protected abstract void initialiseJoinPointNames();
235
236    private GeneratedClassInfo generateJoinpointClass(ClassPool pool, JoinPointInfo newInfo) throws NotFoundException,
237    CannotCompileException, ClassNotFoundException JavaDoc
238    {
239       CtClass superClass = pool.get(joinpointFqn);
240       String JavaDoc className = getJoinpointClassName();
241       try
242       {
243          CtClass clazz = TransformerCommon.makeClass(pool, className);
244          clazz.setSuperclass(superClass);
245          addUntransformableInterface(pool, clazz);
246   
247          AdviceSetupsByType setups = initialiseAdviceInfosAndAddFields(pool, clazz);
248          
249          createConstructors(pool, superClass, clazz, setups);
250          createJoinPointInvokeMethod(
251                superClass,
252                clazz,
253                isVoid(),
254                setups);
255   
256          createInvokeNextMethod(clazz, isVoid(), setups.getAroundSetups());
257   
258          overrideDispatchMethods(superClass, clazz, newInfo);
259          return new GeneratedClassInfo(clazz, setups.getAroundSetups());
260       }
261       catch (NotFoundException e)
262       {
263          System.err.println("Exception generating " + className + ": " + e.getMessage());
264          throw e;
265       }
266       catch (CannotCompileException e)
267       {
268          System.err.println("Exception generating " + className + ": " + e.getMessage());
269          throw e;
270       }
271       catch (ClassNotFoundException JavaDoc e)
272       {
273          System.err.println("Exception generating " + className + ": " + e.getMessage());
274          throw e;
275       }
276    }
277
278    private String JavaDoc getJoinpointClassName()
279    {
280       Package JavaDoc pkg = advisor.getClass().getPackage();
281       
282       StringBuffer JavaDoc className = new StringBuffer JavaDoc();
283       if (pkg != null)
284       {
285          className.append(pkg.getName());
286          className.append(".");
287       }
288       className.append(joinpointClassName);
289       className.append("_");
290       className.append(getIncrement());
291       
292       return className.toString();
293    }
294
295    protected abstract boolean isVoid();
296    protected abstract Class JavaDoc getReturnType();
297    protected abstract AdviceMethodProperties getAdviceMethodProperties(AdviceSetup setup);
298    
299    protected boolean isCaller()
300    {
301       return false;
302    }
303    
304    protected boolean hasCallingObject()
305    {
306       return false;
307    }
308    
309    protected abstract boolean hasTargetObject();
310    
311    private boolean isStaticCall()
312    {
313       if (isCaller())
314       {
315          return !hasCallingObject();
316       }
317       else
318       {
319          return !hasTargetObject();
320       }
321    }
322    
323    private void findAdvisedField(Class JavaDoc advisorSuperClazz, JoinPointInfo info)
324    {
325       if (info.getClazz() == null)
326       {
327          return;
328       }
329       
330       while (advisorSuperClazz != null && advisorSuperClazz.getDeclaringClass() != info.getClazz())
331       {
332          advisorSuperClazz = advisorSuperClazz.getSuperclass();
333       }
334       try
335       {
336          try
337          {
338             joinpointField = advisorSuperClazz.getDeclaredField(joinpointFieldName);
339             SecurityActions.setAccessible(joinpointField);
340             joinpointFqn = advisorSuperClazz.getDeclaringClass().getName() + "$" + joinpointClassName;
341             
342             try
343             {
344                generatorField = advisorSuperClazz.getDeclaredField(getJoinPointGeneratorFieldName());
345                SecurityActions.setAccessible(generatorField);
346             }
347             catch(NoSuchFieldException JavaDoc e)
348             {
349                throw new RuntimeException JavaDoc("Found joinpoint field " +
350                      joinpointField.getName() + " in " + advisorSuperClazz.getName() +
351                      " but no JoinPointGenerator field called " + getJoinPointGeneratorFieldName());
352             }
353          }
354          catch (NoSuchFieldException JavaDoc e)
355          {
356             //GeneratedClassAdvisor is the base class for all generated advisors
357
if (!advisorSuperClazz.getName().equals(GENERATED_CLASS_ADVISOR))
358             {
359                findAdvisedField(advisorSuperClazz.getSuperclass(), info);
360             }
361          }
362       }
363       catch (NoClassDefFoundError JavaDoc e)
364       {
365          throw e;
366       }
367    }
368
369    private AdviceSetupsByType initialiseAdviceInfosAndAddFields(ClassPool pool, CtClass clazz) throws ClassNotFoundException JavaDoc, NotFoundException, CannotCompileException
370    {
371       HashMap JavaDoc cflows = new HashMap JavaDoc();
372       AdviceSetup[] setups = new AdviceSetup[info.getInterceptors().length];
373
374       for (int i = 0 ; i < info.getInterceptors().length ; i++)
375       {
376          setups[i] = new AdviceSetup(i, (GeneratedAdvisorInterceptor)info.getInterceptors()[i]);
377          addAspectFieldAndGetter(pool, clazz, setups[i]);
378          addCFlowFieldsAndGetters(pool, setups[i], clazz, cflows);
379       }
380    
381       return new AdviceSetupsByType(setups);
382    }
383    
384    private void addAspectFieldAndGetter(ClassPool pool, CtClass clazz, AdviceSetup setup) throws NotFoundException, CannotCompileException
385    {
386       CtClass aspectClass = setup.getAspectCtClass();
387       
388       if (!setup.shouldInvokeAspect())
389       {
390          return;
391       }
392
393       CtField field = new CtField(aspectClass, setup.getAspectFieldName(), clazz);
394       field.setModifiers(Modifier.PRIVATE | Modifier.TRANSIENT);
395       clazz.addField(field);
396       
397       String JavaDoc body = getAspectFieldGetterBody(setup);
398       CtMethod method = CtNewMethod.make(
399             aspectClass,
400             setup.getAspectInitialiserName(),
401             new CtClass[0],
402             new CtClass[0],
403             body,
404             clazz);
405       method.setModifiers(Modifier.PRIVATE);
406       clazz.addMethod(method);
407    }
408
409    private String JavaDoc getAspectFieldGetterBody(AdviceSetup setup)
410    {
411       if (setup.requiresInstanceAdvisor())
412       {
413          String JavaDoc instanceAdvisor = (isCaller()) ?
414                "org.jboss.aop.InstanceAdvisor ia = ((org.jboss.aop.Advised)callingObject)._getInstanceAdvisor();" :
415                   "org.jboss.aop.InstanceAdvisor ia = ((org.jboss.aop.Advised)targetObject)._getInstanceAdvisor();";
416                         
417          return
418             "{" +
419             " " + instanceAdvisor +
420             " org.jboss.aop.advice.GeneratedAdvisorInterceptor fw = (org.jboss.aop.advice.GeneratedAdvisorInterceptor)info.getInterceptors()[" + setup.getIndex() + "];" +
421             " Object o = fw.getPerInstanceAspect(info.getAdvisor(), info.getJoinpoint(), ia);" +
422             " return (" + setup.getAspectClass().getName() + ")o;" +
423             "}";
424       }
425       else
426       {
427          return
428             "{" +
429 //"System.out.println(\"xxxx ME \" + this.getClass().getName() + this.getClass().getClassLoader());" +
430
//"System.out.println(\"xxxx SUPER \" + super.getClass().getName() + super.getClass().getClassLoader());" +
431
" if (" + setup.getAspectFieldName() + " != null)" +
432             " {" +
433             " return " + setup.getAspectFieldName() + ";" +
434             " }" +
435             " org.jboss.aop.advice.GeneratedAdvisorInterceptor fw = (org.jboss.aop.advice.GeneratedAdvisorInterceptor)info.getInterceptors()[" + setup.getIndex() + "];" +
436             " Object o = fw.getAspect(info.getAdvisor(), info.getJoinpoint());" +
437             " return (" + setup.getAspectClass().getName() + ")o;" +
438             "}";
439       }
440    }
441    private void addCFlowFieldsAndGetters(ClassPool pool, AdviceSetup setup, CtClass clazz, HashMap JavaDoc cflows)throws NotFoundException, CannotCompileException
442    {
443       if (setup.getCFlowString() != null)
444       {
445          Integer JavaDoc useCFlowIndex = (Integer JavaDoc)cflows.get(setup.getCFlowString());
446          if (useCFlowIndex == null)
447          {
448             useCFlowIndex = new Integer JavaDoc(setup.getIndex());
449             cflows.put(setup.getCFlowString(), useCFlowIndex);
450             
451             CtField cflowX = new CtField(
452                   pool.get(ASTCFlowExpression.class.getName()),
453                   "cflow" + useCFlowIndex,
454                   clazz);
455             clazz.addField(cflowX);
456             
457             CtField matchesCFlowX = new CtField(
458                   CtClass.booleanType,
459                   "matchesCflow" + useCFlowIndex,
460                   clazz);
461             clazz.addField(matchesCFlowX);
462             
463             String JavaDoc initCFlowXBody =
464                "{" +
465                " org.jboss.aop.pointcut.CFlowMatcher matcher = new org.jboss.aop.pointcut.CFlowMatcher();" +
466                " return matcher.matches(" + cflowX.getName() + ", this);" +
467                "}";
468             CtMethod initCFlowX = CtNewMethod.make(
469                   CtClass.booleanType,
470                   "getCFlow" + useCFlowIndex,
471                   new CtClass[0],
472                   new CtClass[0],
473                   initCFlowXBody,
474                   clazz);
475             clazz.addMethod(initCFlowX);
476          }
477          setup.setUseCFlowFrom(useCFlowIndex.intValue());
478       }
479    }
480    
481    private void createJoinPointInvokeMethod(CtClass superClass, CtClass clazz, boolean isVoid, AdviceSetupsByType setups) throws CannotCompileException, NotFoundException
482    {
483       CtMethod superInvoke = superClass.getDeclaredMethod(INVOKE_JOINPOINT);
484       String JavaDoc code = null;
485       try
486       {
487          code = createJoinpointInvokeBody(
488                clazz,
489                setups,
490                superInvoke.getExceptionTypes());
491          CtMethod invoke = CtNewMethod.make(
492                superInvoke.getReturnType(),
493                superInvoke.getName(),
494                superInvoke.getParameterTypes(),
495                superInvoke.getExceptionTypes(),
496                code,
497                clazz);
498          clazz.addMethod(invoke);
499       }
500       catch (CannotCompileException e)
501       {
502          throw new RuntimeException JavaDoc("Error compiling code for Joinpoint (" + info.getJoinpoint() +"): " + code + "\n - " + e + "\n - " + getMethodString(clazz, superInvoke.getName(), superInvoke.getParameterTypes()) + "\n - " + clazz.getName(), e);
503       }
504    }
505    
506    private String JavaDoc createJoinpointInvokeBody(CtClass joinpointClass, AdviceSetupsByType setups, CtClass[] declaredExceptions)throws NotFoundException
507    {
508
509       StringBuffer JavaDoc code = new StringBuffer JavaDoc();
510       code.append("{");
511       if (!isVoid())
512       {
513          String JavaDoc ret = null;
514          Class JavaDoc retType = getReturnType();
515          if (retType.isPrimitive())
516          {
517             if (retType.equals(Boolean.TYPE)) ret = "false";
518             else if (retType.equals(Character.TYPE)) ret = "'\\0'";
519             else if (retType.equals(Byte.TYPE)) ret = "(byte)0";
520             else if (retType.equals(Short.TYPE)) ret = "(short)0";
521             else if (retType.equals(Integer.TYPE)) ret = "(int)0";
522             else if (retType.equals(Long.TYPE)) ret = "0L";
523             else if (retType.equals(Float.TYPE)) ret = "0.0f";
524             else if (retType.equals(Double.TYPE)) ret = "0.0d";
525          }
526          code.append(" " + ClassExpression.simpleType(getReturnType()) + " " + RETURN_VALUE + " = " + ret + ";");
527       }
528       code.append(" try");
529       code.append(" {");
530       addBeforeInvokeCode(code, setups);
531
532       addAroundInvokeCode(code, setups, joinpointClass);
533
534       addAfterInvokeCode(code, setups);
535       code.append(" }");
536       code.append(" catch(java.lang.Throwable " + THROWABLE + ")");
537       code.append(" {");
538       addThrowingInvokeCode(code, setups);
539       addHandleExceptionCode(code, declaredExceptions);
540       code.append(" }");
541       if (!isVoid())
542       {
543          code.append(" return " + RETURN_VALUE + ";");
544       }
545       code.append("}");;
546       
547       return code.toString();
548    }
549
550    private void addBeforeInvokeCode(StringBuffer JavaDoc code, AdviceSetupsByType setups) throws NotFoundException
551    {
552       AdviceSetup[] bsetups = setups.getBeforeSetups();
553       if (bsetups != null)
554       {
555          for (int i = 0 ; i < bsetups.length ; i++)
556          {
557             AdviceMethodProperties properties = bsetups[i].getAdviceMethodProperties();
558             
559             if (properties != null)
560             {
561                code.append(bsetups[i].getAspectFieldName() + "." + bsetups[i].getAdviceName() + "(");
562                appendAdviceCallParameters(code, properties, false);
563                code.append(");");
564             }
565          }
566       }
567    }
568    
569    
570    private void addAroundInvokeCode(StringBuffer JavaDoc code, AdviceSetupsByType setups, CtClass joinpointClass) throws NotFoundException
571    {
572       if (setups.getAroundSetups() != null)
573       {
574          StringBuffer JavaDoc aspects = new StringBuffer JavaDoc();
575          StringBuffer JavaDoc cflows = new StringBuffer JavaDoc();
576          
577          AdviceSetup[] asetups = setups.getAllSetups();
578          for (int i = 0 ; i < asetups.length ; i++)
579          {
580             if (asetups[i].requiresInstanceAdvisor())
581             {
582             }
583             else
584             {
585                aspects.append(", ");
586                aspects.append(asetups[i].getAspectFieldName());
587             }
588          
589             if (asetups[i].isNewCFlow())
590             {
591                cflows.append(", cflow" + asetups[i].getIndex());
592             }
593          }
594
595          code.append(" if(" + INFO_FIELD + ".getInterceptors() != null)");
596          code.append(" {");
597          code.append(" " + joinpointFqn + " jp = new " + joinpointClass.getName() + "(this, $$" + aspects.toString() + cflows.toString() + ");");
598          
599          if (!isVoid())
600          {
601             code.append(" " + RETURN_VALUE + " = ($r)");
602          }
603          code.append("jp.invokeNext();");
604          
605          code.append(" }");
606          code.append(" else");
607          code.append(" {");
608          
609          addDispatchCode(code);
610          
611          code.append(" }");
612       }
613       else
614       {
615          addDispatchCode(code);
616       }
617    }
618
619    private void addDispatchCode(StringBuffer JavaDoc code)
620    {
621       if (! isVoid())
622       {
623          code.append(" " + RETURN_VALUE + " = ");
624       }
625       code.append("super.dispatch($$);");
626    }
627    
628    private void addAfterInvokeCode(StringBuffer JavaDoc code, AdviceSetupsByType setups) throws NotFoundException
629    {
630       AdviceSetup[] asetups = setups.getAfterSetups();
631       if (asetups != null)
632       {
633          for (int i = 0 ; i < asetups.length ; i++)
634          {
635             AdviceMethodProperties properties = asetups[i].getAdviceMethodProperties();
636             
637             if (properties != null)
638             {
639                if (!isVoid() && !properties.isAdviceVoid())
640                {
641                   code.append(" " + RETURN_VALUE + " = (" + getReturnType().getName() + ")");
642                }
643                code.append(asetups[i].getAspectFieldName() + "." + asetups[i].getAdviceName() + "(");
644                appendAdviceCallParameters(code, properties, false);
645                code.append(");");
646             }
647          }
648       }
649    }
650    
651    private void addThrowingInvokeCode(StringBuffer JavaDoc code, AdviceSetupsByType setups) throws NotFoundException
652    {
653       AdviceSetup[] tsetups = setups.getThrowingSetups();
654       if (tsetups != null)
655       {
656          for (int i = 0 ; i < tsetups.length ; i++)
657          {
658             AdviceMethodProperties properties = tsetups[i].getAdviceMethodProperties();
659             
660             if (properties != null)
661             {
662                code.append(tsetups[i].getAspectFieldName() + "." + tsetups[i].getAdviceName() + "(");
663                appendAdviceCallParameters(code, properties, false);
664                code.append(");");
665             }
666          }
667       }
668    }
669
670    private void addHandleExceptionCode(StringBuffer JavaDoc code, CtClass[] declaredExceptions)
671    {
672       for (int i = 0 ; i < declaredExceptions.length ; i++)
673       {
674          code.append("if (t instanceof " + declaredExceptions[i].getName() + ")");
675          code.append(" throw (" + declaredExceptions[i].getName() + ")t;");
676       }
677       
678       code.append("if (t instanceof java.lang.RuntimeException)");
679       code.append( "throw t;");
680       
681       code.append("throw new java.lang.RuntimeException(t);");
682    }
683
684    private void createInvokeNextMethod(CtClass jp, boolean isVoid, AdviceSetup[] aroundSetups) throws NotFoundException, CannotCompileException
685    {
686       if (aroundSetups == null) return;
687       
688       CtMethod method = jp.getSuperclass().getSuperclass().getDeclaredMethod("invokeNext");
689       CtMethod invokeNext = CtNewMethod.copy(method, jp, null);
690       
691       String JavaDoc code = createInvokeNextMethodBody(jp, isVoid, aroundSetups);
692       
693       try
694       {
695          invokeNext.setBody(code);
696       }
697       catch (CannotCompileException e)
698       {
699          throw new RuntimeException JavaDoc("Error creating invokeNext method: " + code, e);
700       }
701       
702       jp.addMethod(invokeNext);
703    }
704
705    private String JavaDoc createInvokeNextMethodBody(CtClass jp, boolean isVoid, AdviceSetup[] aroundSetups) throws NotFoundException
706    {
707       final String JavaDoc returnStr = (isVoid) ? "" : "return ($w)";
708
709       StringBuffer JavaDoc body = new StringBuffer JavaDoc();
710       body.append("{");
711       body.append(" try{");
712       body.append(" switch(++" + CURRENT_ADVICE + "){");
713       
714       int addedAdvice = 0;
715       for (int i = 0 ; i < aroundSetups.length ; i++)
716       {
717          if (!aroundSetups[i].shouldInvokeAspect())
718          {
719             //We are invoking a static method/ctor, do not include advice in chain
720
continue;
721          }
722       
723          AdviceMethodProperties properties = AdviceMethodFactory.AROUND.findAdviceMethod(getAdviceMethodProperties(aroundSetups[i]));
724          if (properties == null || properties.getAdviceMethod() == null)
725          {
726 // throw new RuntimeException("DEBUG ONLY Properties was null " + aroundSetups[i].getAspectClass().getName() + "." + aroundSetups[i].getAdviceName());
727
continue;
728          }
729          
730          body.append(" case " + (++addedAdvice) + ":");
731          if (aroundSetups[i].getCFlowString() != null)
732          {
733             body.append(" if (matchesCflow" + aroundSetups[i].useCFlowFrom() + ")");
734             body.append(" {");
735             appendAroundCallString(body, returnStr, aroundSetups[i], properties);
736             body.append(" }");
737             body.append(" else");
738             body.append(" {");
739             body.append(" " + returnStr + " invokeNext();");
740             body.append(" }");
741          }
742          else
743          {
744             appendAroundCallString(body, returnStr, aroundSetups[i], properties);
745          }
746          
747          
748          body.append(" break;");
749       }
750       
751       body.append(" default:");
752       body.append(" " + returnStr + "this.dispatch();");
753       body.append(" }");
754       body.append(" }finally{");
755       body.append(" --" + CURRENT_ADVICE + ";");
756       body.append(" }");
757       body.append(" return null;");
758       body.append("}");
759       
760       return body.toString();
761    }
762    
763    private void createConstructors(ClassPool pool, CtClass superClass, CtClass clazz, AdviceSetupsByType setups) throws NotFoundException, CannotCompileException
764    {
765       CtConstructor[] superCtors = superClass.getDeclaredConstructors();
766       if (superCtors.length != 2 && !this.getClass().equals(MethodJoinPointGenerator.class))
767       {
768          throw new RuntimeException JavaDoc("JoinPoints should only have 2 and only constructors, not " + superCtors.length);
769       }
770       else if (superCtors.length != 3 && this.getClass().equals(MethodJoinPointGenerator.class))
771       {
772          throw new RuntimeException JavaDoc("Method JoinPoints should only have 2 and only constructors, not " + superCtors.length);
773       }
774       
775       int publicIndex = -1;
776       int protectedIndex = -1;
777       int defaultIndex = -1;
778       
779       for (int i = 0 ; i < superCtors.length ; i++)
780       {
781          int modifier = superCtors[i].getModifiers();
782          if (Modifier.isPublic(modifier))
783          {
784             if (superCtors[i].getParameterTypes().length == 0) defaultIndex = i;
785             else publicIndex = i;
786          }
787          else if (Modifier.isProtected(modifier))
788          {
789             protectedIndex = i;
790          }
791       }
792       
793       if (publicIndex < 0 || protectedIndex < 0)
794       {
795          throw new RuntimeException JavaDoc("One of the JoinPoint constructors should be public, the other protected");
796       }
797       
798       if (defaultIndex >= 0)
799       {
800          createDefaultConstructor(superCtors[defaultIndex], clazz);
801       }
802       
803       createPublicConstructor(superCtors[publicIndex], clazz, setups);
804       createProtectedConstructor(pool, superCtors[protectedIndex], clazz, setups);
805       createCopyConstructorAndMethod(pool, clazz);
806    }
807
808    /**
809     * Currently only method joinpoints need serialization and thus a default ctor
810     */

811    private void createDefaultConstructor(CtConstructor superCtor, CtClass clazz) throws CannotCompileException
812    {
813       CtConstructor ctor = CtNewConstructor.defaultConstructor(clazz);
814       clazz.addConstructor(ctor);
815    }
816    
817    /**
818     * This is the constructor that will be called by the GeneratedClassAdvisor, make sure it
819     * initialises all the non-per-instance aspects
820     */

821    private void createPublicConstructor(CtConstructor superCtor, CtClass clazz, AdviceSetupsByType setups)throws CannotCompileException, NotFoundException
822    {
823       StringBuffer JavaDoc body = new StringBuffer JavaDoc();
824       try
825       {
826          body.append("{super($$);");
827   
828          //Initialise all the aspects not scoped per_instance or per_joinpoint
829
AdviceSetup[] allSetups = setups.getAllSetups();
830          for (int i = 0 ; i < allSetups.length ; i++)
831          {
832             if (!allSetups[i].requiresInstanceAdvisor())
833             {
834                body.append(allSetups[i].getAspectFieldName() + " = " + allSetups[i].getAspectInitialiserName() + "();");
835             }
836          }
837          
838          body.append("}");
839
840          CtConstructor ctor = CtNewConstructor.make(superCtor.getParameterTypes(), superCtor.getExceptionTypes(), body.toString(), clazz);
841          ctor.setModifiers(superCtor.getModifiers());
842          clazz.addConstructor(ctor);
843       }
844       catch (CannotCompileException e)
845       {
846          // AutoGenerated
847
throw new CannotCompileException("Error compiling. Code \n" + body.toString(), e);
848       }
849    }
850    
851    /**
852     * This is the constructor that will be called by the invokeJoinPoint() method, make sure it
853     * copies across all the non-per-instance aspects
854     */

855    private void createProtectedConstructor(ClassPool pool, CtConstructor superCtor, CtClass clazz, AdviceSetupsByType setups) throws CannotCompileException, NotFoundException
856    {
857       
858       CtClass[] superParams = superCtor.getParameterTypes();
859       ArrayList JavaDoc aspects = new ArrayList JavaDoc();
860       ArrayList JavaDoc cflows = new ArrayList JavaDoc();
861       StringBuffer JavaDoc adviceInit = new StringBuffer JavaDoc();
862       
863       AdviceSetup[] allSetups = setups.getAllSetups();
864       for (int i = 0 ; i < allSetups.length ; i++)
865       {
866          if (!allSetups[i].shouldInvokeAspect())
867          {
868             continue;
869          }
870          
871          if (allSetups[i].requiresInstanceAdvisor())
872          {
873             adviceInit.append(allSetups[i].getAspectFieldName() + " = " + allSetups[i].getAspectInitialiserName() + "();");
874          }
875          else
876          {
877             aspects.add(allSetups[i]);
878          }
879          
880          if (allSetups[i].isNewCFlow())
881          {
882             cflows.add(new Integer JavaDoc(allSetups[i].useCFlowFrom()));
883          }
884       }
885
886       StringBuffer JavaDoc cflowInit = new StringBuffer JavaDoc();
887
888       //Set up the parameters
889
CtClass[] params = new CtClass[superParams.length + aspects.size() + cflows.size()];
890       System.arraycopy(superParams, 0, params, 0, superParams.length);
891
892       for (int i = 0 ; i < aspects.size() ; i++)
893       {
894          AdviceSetup setup = (AdviceSetup)aspects.get(i);
895          params[i + superParams.length] = setup.getAspectCtClass();
896          adviceInit.append("this." + setup.getAspectFieldName() + " = $" + (i + superParams.length + 1) + ";");
897       }
898       final int aspectsLength = superParams.length + aspects.size();
899       if (cflows.size() > 0 )
900       {
901          CtClass astCFlowExpr = pool.get(ASTCFlowExpression.class.getName());
902          for (int i = 0 ; i < cflows.size() ; i++)
903          {
904             params[i + aspectsLength] = astCFlowExpr;
905             cflowInit.append("cflow" + cflows.get(i) + "= $" + (i + aspectsLength + 1) + ";");
906             cflowInit.append("matchesCflow" + cflows.get(i) + " = getCFlow" + allSetups[i].useCFlowFrom() + "();");
907          }
908       }
909       
910       StringBuffer JavaDoc body = new StringBuffer JavaDoc("{super(");
911       for (int i = 0 ; i < superParams.length ; i++)
912       {
913          if (i > 0)
914          {
915             body.append(", ");
916          }
917          body.append("$" + (i + 1));
918       
919       }
920       body.append(");");
921       body.append(adviceInit.toString());
922       body.append(cflowInit.toString());
923       body.append("}");
924       CtConstructor ctor = CtNewConstructor.make(
925           params,
926           superCtor.getExceptionTypes(),
927           body.toString(),
928           clazz);
929          ctor.setModifiers(superCtor.getModifiers());
930          clazz.addConstructor(ctor);
931    }
932
933
934    private void createCopyConstructorAndMethod(ClassPool pool, CtClass clazz) throws NotFoundException, CannotCompileException
935    {
936       //Add all fields from this class and all superclasses
937
StringBuffer JavaDoc body = new StringBuffer JavaDoc();
938       body.append("{");
939       body.append(" super($1.info);");
940
941       CtClass superClass = clazz;
942       while (superClass != null && !superClass.getName().equals("java.lang.Object"))
943       {
944          CtField[] fields = superClass.getDeclaredFields();
945          for (int i = 0 ; i < fields.length ; i++)
946          {
947             if (Modifier.isPrivate(fields[i].getModifiers()) && fields[i].getDeclaringClass() != clazz)
948             {
949                continue;
950             }
951             
952             if (Modifier.isFinal(fields[i].getModifiers()) || Modifier.isStatic(fields[i].getModifiers()) )
953             {
954                continue;
955             }
956             
957             body.append(" this." + fields[i].getName() + " = $1." + fields[i].getName() + ";");
958          }
959          superClass = superClass.getSuperclass();
960       }
961       body.append("}");
962       
963       CtConstructor copyCtor = CtNewConstructor.make(new CtClass[] {clazz}, new CtClass[0], body.toString(), clazz);
964       copyCtor.setModifiers(Modifier.PRIVATE);
965       clazz.addConstructor(copyCtor);
966       
967       CtMethod superCopy = pool.get(Invocation.class.getName()).getDeclaredMethod("copy");
968       String JavaDoc copyBody =
969          "{" +
970          " return new " + clazz.getName() + "(this);" +
971          "}";
972       CtMethod copy = CtNewMethod.make(
973             superCopy.getReturnType(),
974             superCopy.getName(),
975             new CtClass[0],
976             new CtClass[0],
977             copyBody,
978             clazz);
979       clazz.setModifiers(Modifier.PUBLIC);
980       clazz.addMethod(copy);
981    }
982
983    /**
984     * Normal people don't want to override the dispatch method
985     */

986    protected void overrideDispatchMethods(CtClass superClass, CtClass clazz, JoinPointInfo newInfo) throws CannotCompileException, NotFoundException
987    {
988    }
989    
990    /**
991     * For ConByXXXX, If target constructor is execution advised, replace it with a call to the constructor wrapper
992     */

993    protected void overrideDispatchMethods(CtClass superClass, CtClass clazz, CallerConstructorInfo cinfo) throws NotFoundException, CannotCompileException
994    {
995       if (cinfo.getWrappingMethod() == null)
996       {
997          return;
998       }
999       
1000      CtMethod[] superDispatches = JavassistUtils.getDeclaredMethodsWithName(superClass, DISPATCH);
1001      
1002      if (superDispatches.length > 2)
1003      {
1004         if (AspectManager.verbose) System.out.println("[warn] - Too many dispatch() methods found in " + superClass.getName());
1005      }
1006      
1007      for (int i = 0 ; i < superDispatches.length ; i++)
1008      {
1009         CtMethod wrapperMethod = ReflectToJavassist.methodToJavassist(cinfo.getWrappingMethod());
1010         CtClass[] params = wrapperMethod.getParameterTypes();
1011         
1012         StringBuffer JavaDoc parameters = new StringBuffer JavaDoc("(");
1013         if (superDispatches[i].getParameterTypes().length == 0)
1014         {
1015            //This is the no params version called by invokeNext() for around advices
1016
for (int j = 0 ; j < params.length ; j++)
1017            {
1018               if (j > 0)parameters.append(", ");
1019               parameters.append("arg" + j);
1020            }
1021         }
1022         else
1023         {
1024            //This is the no parameterized version called by invokeJoinPoint() when there are no around advices
1025
int offset = (hasCallingObject()) ? 1 : 0;
1026            for (int j = 0 ; j < params.length ; j++)
1027            {
1028               if (j > 0)parameters.append(", ");
1029               parameters.append("$" + (j + offset + 1));
1030            }
1031         }
1032         parameters.append(")");
1033
1034         String JavaDoc body =
1035            "{ return " + cinfo.getConstructor().getDeclaringClass().getName() + "." + cinfo.getWrappingMethod().getName() + parameters + ";}";
1036   
1037         try
1038         {
1039            CtMethod dispatch = CtNewMethod.make(
1040                  superDispatches[i].getReturnType(),
1041                  superDispatches[i].getName(),
1042                  superDispatches[i].getParameterTypes(),
1043                  superDispatches[i].getExceptionTypes(),
1044                  body,
1045                  clazz);
1046            dispatch.setModifiers(superDispatches[i].getModifiers());
1047            clazz.addMethod(dispatch);
1048         }
1049         catch (CannotCompileException e)
1050         {
1051            throw new RuntimeException JavaDoc("Could not compile code " + body + " for method " + getMethodString(clazz, superDispatches[i].getName(), superDispatches[i].getParameterTypes()), e);
1052         }
1053         
1054      }
1055   }
1056   
1057   protected static void addUntransformableInterface(Instrumentor instrumentor, CtClass clazz) throws NotFoundException
1058   {
1059      addUntransformableInterface(instrumentor.getClassPool(), clazz);
1060   }
1061
1062   protected static void addUntransformableInterface(ClassPool pool, CtClass clazz) throws NotFoundException
1063   {
1064      CtClass untransformable = pool.get(Untransformable.class.getName());
1065      clazz.addInterface(untransformable);
1066   }
1067
1068   protected abstract String JavaDoc getJoinPointGeneratorFieldName();
1069   protected static String JavaDoc getMethodString(CtClass joinpoint, String JavaDoc method, CtClass[] params)
1070   {
1071      StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1072      sb.append(joinpoint);
1073      sb.append(".");
1074      sb.append("name");
1075      sb.append("(");
1076      for (int i = 0 ; i < params.length ; i++)
1077      {
1078         if (i > 0) sb.append(", ");
1079         sb.append(params[i].getName());
1080      }
1081      sb.append(")");
1082      
1083      return sb.toString();
1084   }
1085
1086   public void appendAroundCallString(StringBuffer JavaDoc invokeNextBody, String JavaDoc returnStr, AdviceSetup setup, AdviceMethodProperties properties)
1087   {
1088      Integer JavaDoc[] args = properties.getArgs();
1089      
1090      final boolean firstParamIsInvocation = (args.length >= 1 && args[0].equals(AdviceMethodProperties.INVOCATION_ARG));
1091
1092      if (!firstParamIsInvocation)
1093      {
1094         invokeNextBody.append("try{");
1095         invokeNextBody.append(" org.jboss.aop.joinpoint.CurrentInvocation.push(this); ");
1096      }
1097
1098      invokeNextBody.append(" " + returnStr + " " + setup.getAspectFieldName() + "." + properties.getAdviceName() + "(");
1099      appendAdviceCallParameters(invokeNextBody, properties, true);
1100      invokeNextBody.append(");");
1101      
1102      if (!firstParamIsInvocation)
1103      {
1104         invokeNextBody.append("}finally{");
1105         invokeNextBody.append(" org.jboss.aop.joinpoint.CurrentInvocation.pop(); ");
1106         invokeNextBody.append("}");
1107      }
1108   }
1109
1110   private void appendAdviceCallParameters(StringBuffer JavaDoc invokeNextBody, AdviceMethodProperties properties, boolean isAround)
1111   {
1112      final Integer JavaDoc[] args = properties.getArgs();
1113      final Class JavaDoc[] adviceParams = properties.getAdviceMethod().getParameterTypes();
1114      for (int i = 0 ; i < args.length ; i++)
1115      {
1116         if (i > 0) invokeNextBody.append(", ");
1117         
1118         if (args[i].equals(AdviceMethodProperties.INVOCATION_ARG))
1119         {
1120            invokeNextBody.append(castToAdviceProperties(i, adviceParams) + "this");
1121         }
1122         else if (args[i].equals(AdviceMethodProperties.JOINPOINT_ARG))
1123         {
1124            invokeNextBody.append(castToAdviceProperties(i, adviceParams) + INFO_FIELD);
1125         }
1126         else if (args[i].equals(AdviceMethodProperties.RETURN_ARG))
1127         {
1128            invokeNextBody.append(castToAdviceProperties(i, adviceParams) + RETURN_VALUE);
1129         }
1130         else if (args[i].equals(AdviceMethodProperties.THROWABLE_ARG))
1131         {
1132            invokeNextBody.append(castToAdviceProperties(i, adviceParams) + THROWABLE);
1133         }
1134         else
1135         {
1136            if (isAround)
1137            {
1138               invokeNextBody.append(castToAdviceProperties(i, adviceParams) + "this.arg" + args[i]);
1139            }
1140            else
1141            {
1142               //The parameter array is 1-based, and the invokeJoinPoint method may also take the target and caller objects
1143
int offset = 1;
1144               if (hasTargetObject()) offset++;
1145               if (hasCallingObject()) offset++;
1146               invokeNextBody.append(castToAdviceProperties(i, adviceParams) + "$" + (args[i].intValue() + offset));
1147            }
1148         }
1149      }
1150   }
1151   
1152   private String JavaDoc castToAdviceProperties(int i, Class JavaDoc[] args)
1153   {
1154      //In case of overloaded methods javassist sometimes seems to pick up the wrong method - use explicit casts to get hold of the parameters
1155
return "(" + ClassExpression.simpleType(args[i]) + ")";
1156   }
1157   
1158   protected class AdviceSetup
1159   {
1160      int index;
1161      Class JavaDoc aspectClass;
1162      CtClass aspectCtClass;
1163      String JavaDoc adviceName;
1164      Scope scope;
1165      String JavaDoc registeredName;
1166      String JavaDoc cflowString;
1167      ASTCFlowExpression cflowExpr;
1168      int cflowIndex;
1169      boolean isBefore;
1170      boolean isAfter;
1171      boolean isThrowing;
1172      AdviceMethodProperties adviceMethodProperties;
1173      
1174      AdviceSetup(int index, GeneratedAdvisorInterceptor ifw) throws ClassNotFoundException JavaDoc, NotFoundException
1175      {
1176         this.index = index;
1177         scope = ifw.getScope();
1178         adviceName = ifw.getAdviceName();
1179         registeredName = ifw.getRegisteredName();
1180         cflowString = ifw.getCFlowString();
1181         cflowExpr = ifw.getCflowExpression();
1182         if (ifw.isAspectFactory())
1183         {
1184            Object JavaDoc aspectInstance = ((GeneratedAdvisorInterceptor)info.getInterceptors()[index]).getAspect(info.getAdvisor(), info.getJoinpoint(), true);
1185            aspectClass = aspectInstance.getClass();
1186         }
1187         else
1188         {
1189            aspectClass = Thread.currentThread().getContextClassLoader().loadClass(ifw.getAspectClassName());
1190         }
1191         aspectCtClass = ReflectToJavassist.classToJavassist(aspectClass);
1192
1193         isBefore = ifw.isBefore();
1194         isAfter = ifw.isAfter();
1195         isThrowing = ifw.isThrowing();
1196      }
1197      
1198      String JavaDoc getAdviceName()
1199      {
1200         return adviceName;
1201      }
1202      
1203      
1204      Class JavaDoc getAspectClass()
1205      {
1206         return aspectClass;
1207      }
1208      
1209      CtClass getAspectCtClass()
1210      {
1211         return aspectCtClass;
1212      }
1213      
1214      Scope getScope()
1215      {
1216         return scope;
1217      }
1218      
1219      int getIndex()
1220      {
1221         return index;
1222      }
1223      
1224      String JavaDoc getRegisteredName()
1225      {
1226         return registeredName;
1227      }
1228      
1229      String JavaDoc getAspectFieldName()
1230      {
1231         StringBuffer JavaDoc name = new StringBuffer JavaDoc();
1232         if (isAround())
1233         {
1234            name.append("around");
1235         }
1236         else if (isBefore())
1237         {
1238            name.append("before");
1239         }
1240         else if (isAfter())
1241         {
1242            name.append("after");
1243         }
1244         else if (isThrowing())
1245         {
1246            name.append("throwing");
1247         }
1248         else
1249         {
1250            if (AspectManager.verbose) System.out.println("[warn] Unsupported type of advice");
1251         }
1252         name.append(index + 1);
1253         return name.toString();
1254      }
1255      
1256      String JavaDoc getAspectInitialiserName()
1257      {
1258         StringBuffer JavaDoc name = new StringBuffer JavaDoc();
1259         if (isAround())
1260         {
1261            name.append("getAround");
1262         }
1263         else if (isBefore())
1264         {
1265            name.append("getBefore");
1266         }
1267         else if (isAfter())
1268         {
1269            name.append("getAfter");
1270         }
1271         else if (isThrowing())
1272         {
1273            name.append("getThrowing");
1274         }
1275         else
1276         {
1277            if (AspectManager.verbose) System.out.println("[warn] Unsupported type of advice");
1278         }
1279         name.append(index + 1);
1280         return name.toString();
1281      }
1282      
1283      boolean isPerInstance()
1284      {
1285         return scope == Scope.PER_INSTANCE;
1286      }
1287      
1288      boolean isPerJoinpoint()
1289      {
1290         return scope == Scope.PER_JOINPOINT;
1291      }
1292      
1293      boolean shouldInvokeAspect()
1294      {
1295         return !(isPerInstance() && isStaticCall());
1296      }
1297      
1298      boolean requiresInstanceAdvisor()
1299      {
1300         return (isPerInstance() || (isPerJoinpoint() && !isStaticCall()));
1301      }
1302      
1303      String JavaDoc getCFlowString()
1304      {
1305         return cflowString;
1306      }
1307      
1308      ASTCFlowExpression getCFlow()
1309      {
1310         return cflowExpr;
1311      }
1312      
1313      void setUseCFlowFrom(int index)
1314      {
1315         cflowIndex = index;
1316      }
1317      
1318      int useCFlowFrom()
1319      {
1320         return cflowIndex;
1321      }
1322      
1323      boolean isNewCFlow()
1324      {
1325         return (getCFlowString() != null && index == cflowIndex);
1326      }
1327
1328      boolean isAfter()
1329      {
1330         return isAfter;
1331      }
1332
1333      boolean isBefore()
1334      {
1335         return isBefore;
1336      }
1337
1338      boolean isThrowing()
1339      {
1340         return isThrowing;
1341      }
1342      
1343      boolean isAround()
1344      {
1345         return !isAfter && !isBefore && !isThrowing;
1346      }
1347
1348      public AdviceMethodProperties getAdviceMethodProperties()
1349      {
1350         return adviceMethodProperties;
1351      }
1352
1353      public void setAdviceMethodProperties(AdviceMethodProperties adviceMethodProperties)
1354      {
1355         this.adviceMethodProperties = adviceMethodProperties;
1356      }
1357   }
1358   
1359   private class GeneratedClassInfo
1360   {
1361      CtClass generated;
1362      AdviceSetup[] aroundSetups;
1363      
1364      GeneratedClassInfo(CtClass generated, AdviceSetup[] aroundSetups)
1365      {
1366         this.generated = generated;
1367         this.aroundSetups = aroundSetups;
1368      }
1369      
1370      CtClass getGenerated()
1371      {
1372         return generated;
1373      }
1374      
1375      AdviceSetup[] getAroundSetups()
1376      {
1377         return (aroundSetups == null) ? new AdviceSetup[0] : aroundSetups;
1378      }
1379   }
1380   
1381   private class AdviceSetupsByType
1382   {
1383      AdviceSetup[] allSetups;
1384      AdviceSetup[] beforeSetups;
1385      AdviceSetup[] afterSetups;
1386      AdviceSetup[] throwingSetups;
1387      AdviceSetup[] aroundSetups;
1388
1389      AdviceSetupsByType(AdviceSetup[] setups)
1390      {
1391         allSetups = setups;
1392         ArrayList JavaDoc beforeAspects = null;
1393         ArrayList JavaDoc afterAspects = null;
1394         ArrayList JavaDoc throwingAspects = null;
1395         ArrayList JavaDoc aroundAspects = null;
1396
1397         for (int i = 0 ; i < setups.length ; i++)
1398         {
1399            if (setups[i].isBefore())
1400            {
1401               if (beforeAspects == null) beforeAspects = new ArrayList JavaDoc();
1402               
1403               AdviceMethodProperties properties = AdviceMethodFactory.BEFORE.findAdviceMethod(getAdviceMethodProperties(setups[i]));
1404               if (properties != null)
1405               {
1406                  setups[i].setAdviceMethodProperties(properties);
1407                  beforeAspects.add(setups[i]);
1408                  continue;
1409               }
1410
1411            }
1412            else if (setups[i].isAfter())
1413            {
1414               if (afterAspects == null) afterAspects = new ArrayList JavaDoc();
1415               AdviceMethodProperties properties = AdviceMethodFactory.AFTER.findAdviceMethod(getAdviceMethodProperties(setups[i]));
1416               if (properties != null)
1417               {
1418                  setups[i].setAdviceMethodProperties(properties);
1419                  afterAspects.add(setups[i]);
1420                  continue;
1421               }
1422            }
1423            else if (setups[i].isThrowing())
1424            {
1425               if (throwingAspects == null) throwingAspects = new ArrayList JavaDoc();
1426               AdviceMethodProperties properties = AdviceMethodFactory.THROWING.findAdviceMethod(getAdviceMethodProperties(setups[i]));
1427               if (properties != null)
1428               {
1429                  setups[i].setAdviceMethodProperties(properties);
1430                  throwingAspects.add(setups[i]);
1431                  continue;
1432               }
1433            }
1434            else
1435            {
1436               if (aroundAspects == null) aroundAspects = new ArrayList JavaDoc();
1437               AdviceMethodProperties properties = AdviceMethodFactory.AROUND.findAdviceMethod(getAdviceMethodProperties(setups[i]));
1438               if (properties != null)
1439               {
1440                  setups[i].setAdviceMethodProperties(properties);
1441                  aroundAspects.add(setups[i]);
1442                  continue;
1443               }
1444            }
1445            
1446            if (AspectManager.verbose)
1447            {
1448               System.out.println("[warn] No matching advice called '" + setups[i].getAdviceName() +
1449                     "' could be found in " + setups[i].getAspectClass().getName() + " for joinpoint " + info);
1450            }
1451         }
1452         beforeSetups = (beforeAspects == null) ? null : (AdviceSetup[])beforeAspects.toArray(new AdviceSetup[beforeAspects.size()]);
1453         afterSetups = (afterAspects == null) ? null : (AdviceSetup[])afterAspects.toArray(new AdviceSetup[afterAspects.size()]);
1454         throwingSetups = (throwingAspects == null) ? null : (AdviceSetup[])throwingAspects.toArray(new AdviceSetup[throwingAspects.size()]);
1455         aroundSetups = (aroundAspects == null) ? null : (AdviceSetup[])aroundAspects.toArray(new AdviceSetup[aroundAspects.size()]);
1456      }
1457
1458      public AdviceSetup[] getAllSetups()
1459      {
1460         return allSetups;
1461      }
1462      
1463      public AdviceSetup[] getAfterSetups()
1464      {
1465         return afterSetups;
1466      }
1467
1468      public AdviceSetup[] getAroundSetups()
1469      {
1470         return aroundSetups;
1471      }
1472
1473      public AdviceSetup[] getBeforeSetups()
1474      {
1475         return beforeSetups;
1476      }
1477
1478      public AdviceSetup[] getThrowingSetups()
1479      {
1480         return throwingSetups;
1481      }
1482   }
1483
1484   private interface GenerateJoinPointClassAction
1485   {
1486      void generateJoinPointClass(JoinPointGenerator joinPointGenerator);
1487      
1488      GenerateJoinPointClassAction PRIVILEGED = new GenerateJoinPointClassAction()
1489      {
1490         public void generateJoinPointClass(final JoinPointGenerator joinPointGenerator)
1491         {
1492            try
1493            {
1494               AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
1495               {
1496                  public Object JavaDoc run() throws Exception JavaDoc
1497                  {
1498                     joinPointGenerator.doGenerateJoinPointClass();
1499                     return null;
1500                  }
1501               });
1502            }
1503            catch (PrivilegedActionException JavaDoc e)
1504            {
1505               Exception JavaDoc actual = e.getException();
1506               if (actual instanceof RuntimeException JavaDoc)
1507               {
1508                  throw (RuntimeException JavaDoc)actual;
1509               }
1510               throw new RuntimeException JavaDoc(actual);
1511            }
1512         }
1513      };
1514
1515      GenerateJoinPointClassAction NON_PRIVILEGED = new GenerateJoinPointClassAction()
1516      {
1517         public void generateJoinPointClass(JoinPointGenerator joinPointGenerator)
1518         {
1519            joinPointGenerator.doGenerateJoinPointClass();
1520         }
1521      };
1522   }
1523}
1524
Popular Tags