org.objectweb.fractal.julia.asm
Class InterceptorClassGenerator

java.lang.Object
  extended by org.objectweb.fractal.julia.asm.AbstractClassGenerator
      extended by org.objectweb.fractal.julia.asm.InterceptorClassGenerator
All Implemented Interfaces:
Opcodes, ClassGenerator, Initializable

public class InterceptorClassGenerator
extends AbstractClassGenerator
implements Initializable

A class generator to generate Interceptor classes. This generator produces sub classes of a given class that implement a given set of interfaces by adding interception code to the original code of each method (this original code just forwards method calls to the getFcItfDelegate object). The interception code is generated by CodeGenerator and/or ClassTransformer objects.

The original code of each method is visited and adapted on the fly by the code adapters returned by the code generators (see CodeGenerator), resulting in a modified code that includes the interception code generated by each code generator.

For example, if the original code void m () { impl.m() } is modified by the code adapter returned by a code generator A into:

 void m () {
   // pre code A
   try {
     impl.m();
   } finally {
     // post code A
   }
 }
 
and by the code adapter returned by a code generator B into:
 void m () {
   // pre code B
   impl.m();
   // post code B
 }
 
then the original code will be modified by A and B, in this order (the last code adapter is applied first), into:
 void m () {
   // pre code A
   try {
     // pre code B
     impl.m();
     // post code B
   } finally {
     // post code A
   }
 }
 
If the original code is modified by B and A, the result is:
 void m () {
   // pre code B
   // pre code A
   try {
     impl.m();
   } finally {
     // post code A
   }
   // post code B
 }
 
The complete class generated for an interface I containing only the above m method, and with A = LifeCycleCodeGenerator and B = TraceCodeGenerator, in this order, is the following (if there is more than one interface, some additional casts are used - as in the InterfaceClassGenerator class):
 public class XYZ
   implements I, Interceptor, Generated
 {

   private I impl;
   private UVW lc;

   public XYZ (Object impl) {
     setFcItfDelegate(impl);
   }

   public void m () {
     synchronized(lc) {
       if (lc.fcState != 2)
         lc.incrementFcInvocationCounter();
       else
         lc.fcInvocationCounter++;
     }
     try {
       System.err.println("Entering public abstract void I.m()");
       impl.m();
       System.err.println("Leaving public abstract void I.m()");
     } finally {
       synchronized (lc) {
         if (lc.fcState != 2)
           lc.decrementFcInvocationCounter();
         else
           lc.fcInvocationCounter--;
       }
     }
   }

   // overriden Controller methods

   public void initFcController (InitializationContext ic) {
     lc = (UVW)ic.getInterface("lifecycle-controller");
   }

   // Interceptor methods

   public Object getFcItfDelegate () {
     return impl;
   }

   public void setFcItfDelegate (Object o) {
     impl = (I)o;
   }

   public Object clone () {
     XYZ clone = new XYZ(impl);
     clone.lc = lc;
     return clone;
   }

   // Generated methods

   public String getFcGeneratorParameters () {
     return "((...InterceptorClassGenerator ...LifeCycleCodeGenerator
               ...TraceCodeGenerator) java.lang.Object (I) (...) in)";
   }
 }
 
This class generator can be used in two different ways, corresponding to the optimization levels of components: In the last case the generated code is quite different from the above code: ClassTransformers can be used only with the mergeControllersInterceptorsAndContent option. These transformers transform the "user component" class, before the interception code is added by the CodeGenerators. If class transformers are used, the generated class is not generated as a sub class of the given super class: instead, the code of this super class (and of its own super class) is directly copied (after tranformation) into the generated class.


Field Summary
 Tree args
          The arguments of the class that is being generated.
 ClassTransformer[] classTransformers
          The class transformers used by this interceptor class generator.
 Tree codeGenDescs
          Descriptors of the code generators used by this class generator.
 CodeGenerator[] codeGens
          The code generators used by this interceptor class generator.
 Class[] controllerClasses
          The controller classes that can be used by the generated interceptor class.
 String implFieldDesc
          The "impl" field descriptor.
 String implFieldName
          The "impl" field name.
 boolean in
          true if the class to be generated is an input interceptor class.
 boolean isComposite
          Indicates if the interceptors are generated for a composite component.
 boolean mergeAll
          Indicates if the controller, interceptor and content classes are merged.
 boolean mergeInterceptors
          Indicates if the controller and interceptor classes are merged.
 
Fields inherited from class org.objectweb.fractal.julia.asm.AbstractClassGenerator
classLoader, cw, interfaces, loader, name, parameters, superClass
 
Fields inherited from interface org.objectweb.asm.Opcodes
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, V1_1, V1_2, V1_3, V1_4, V1_5
 
Constructor Summary
InterceptorClassGenerator()
           
 
Method Summary
protected  boolean computeMaxs()
          Returns true.
 byte[] generateClass(String name, Tree args, Loader loader, ClassLoader classLoader)
          Initializes the specific fields of this class before calling the overriden method.
protected  void generateConstructor()
          Generates the constructor of the class to be generated.
protected  void generateDefaultMethods()
          Calls the overriden method and generates the "impl" field and the methods of the Interceptor interface.
protected  void generateInterfaceMethods()
          Generates the methods of the interfaces to be implemented by the class to be generated.
protected  void generateMethod(Method m)
          Generates the interception code for the given method.
protected  List getImplementedInterfaces()
          Adds Interceptor to the list returned by the overriden method.
protected  String getSource()
          Returns the source of the class to be generated.
 void initialize(Tree args)
          Initializes this object with the given arguments.
protected  void parseArgs(Tree args)
          Initializes this class generator with the given arguments.
 
Methods inherited from class org.objectweb.fractal.julia.asm.AbstractClassGenerator
generateHeader, getOpcodeOffset, getSize
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

args

public Tree args
The arguments of the class that is being generated.


codeGenDescs

public Tree codeGenDescs
Descriptors of the code generators used by this class generator.


codeGens

public CodeGenerator[] codeGens
The code generators used by this interceptor class generator.


classTransformers

public ClassTransformer[] classTransformers
The class transformers used by this interceptor class generator.


controllerClasses

public Class[] controllerClasses
The controller classes that can be used by the generated interceptor class.


in

public boolean in
true if the class to be generated is an input interceptor class. An input interceptor intercepts incoming calls, in external server interfaces, while an output interceptor intercepts outgoing calls, in external client interfaces (or in the corresponding internal server interfaces).


mergeInterceptors

public boolean mergeInterceptors
Indicates if the controller and interceptor classes are merged. This is equivalent to the fact that the controller class list is empty.


mergeAll

public boolean mergeAll
Indicates if the controller, interceptor and content classes are merged.


isComposite

public boolean isComposite
Indicates if the interceptors are generated for a composite component. This field is only used if interceptor and controller classes are merged. It is true if the merged controller class implements ContentController.


implFieldName

public String implFieldName
The "impl" field name.


implFieldDesc

public String implFieldDesc
The "impl" field descriptor.

Constructor Detail

InterceptorClassGenerator

public InterceptorClassGenerator()
Method Detail

initialize

public void initialize(Tree args)
Initializes this object with the given arguments.

Specified by:
initialize in interface Initializable
Parameters:
args - the descriptors of the code generators to be used by this interceptor class generator. This tree must be a list of object descriptors (see @link Loader#createObject createObject}, each object descriptor describing a CodeGenerator.

generateClass

public byte[] generateClass(String name,
                            Tree args,
                            Loader loader,
                            ClassLoader classLoader)
                     throws ClassGenerationException
Initializes the specific fields of this class before calling the overriden method.

Specified by:
generateClass in interface ClassGenerator
Overrides:
generateClass in class AbstractClassGenerator
Parameters:
name - the name of the class to be generated.
args - a tree of the form "(object descriptor superClass (itf1 ... itfN) (class1 ... classM) in|out)", where itf1 ... itfN are the names of the interfaces that the generated class must implement, class1 ... classM are the names of the controller classes that can used by the generated interceptor class, and in or out indicates if an input or output interceptor class must be generated.
loader - the class loader to be used to generate the specified class. This parameter, which may be null, can be a class loader, a class, or any other object (the class loader is then found by using the getClass() and getClassLoader() methods).
classLoader - the class loader to be used to load auxiliary classes.
Returns:
a sub class of the given class that implements the given interfaces.
Throws:
ClassGenerationException - if any other problem occurs.

parseArgs

protected void parseArgs(Tree args)
Description copied from class: AbstractClassGenerator
Initializes this class generator with the given arguments. The default implementation of this method requires arguments of the form "(objectDescriptor superClassName (itfName1 ... itfNameN) ...)", where superClassName is the name of the super class of the class to be generated, and itfName1 ... itfNameN the names of the interfaces it must implement.

Overrides:
parseArgs in class AbstractClassGenerator
Parameters:
args - the descriptor of the class to be generated.

computeMaxs

protected boolean computeMaxs()
Returns true.

Overrides:
computeMaxs in class AbstractClassGenerator
Returns:
true.

getSource

protected String getSource()
Returns the source of the class to be generated. This method returns "INTERCEPTOR[...]", where "..." is the name of the interface implemented by the generated class.

Overrides:
getSource in class AbstractClassGenerator
Returns:
the source of the class to be generated.

getImplementedInterfaces

protected List getImplementedInterfaces()
                                 throws ClassGenerationException
Adds Interceptor to the list returned by the overriden method. In fact this interface is not added if the interceptors are merged with the controller objects, and if isComposite is false.

Overrides:
getImplementedInterfaces in class AbstractClassGenerator
Returns:
the names of all the interfaces implemented by the generated class.
Throws:
ClassGenerationException - if a problem occurs.

generateConstructor

protected void generateConstructor()
                            throws ClassGenerationException
Description copied from class: AbstractClassGenerator
Generates the constructor of the class to be generated. The default implementation of this method generates an empty public constructor without arguments. The super class should also have such a constructor.

Overrides:
generateConstructor in class AbstractClassGenerator
Throws:
ClassGenerationException - if a problem occurs.

generateDefaultMethods

protected void generateDefaultMethods()
                               throws ClassGenerationException
Calls the overriden method and generates the "impl" field and the methods of the Interceptor interface. This method also generates the "initFcController" method, by concatenating the code generated by the generateInitCode method of each code generator. If the interceptor and controller objects are merged, and if isComposite is false, this method just calls the overriden method and sets the "impl" field to the "fcContent" field.

Overrides:
generateDefaultMethods in class AbstractClassGenerator
Throws:
ClassGenerationException - if a problem occurs.

generateInterfaceMethods

protected void generateInterfaceMethods()
                                 throws ClassGenerationException
Description copied from class: AbstractClassGenerator
Generates the methods of the interfaces to be implemented by the class to be generated. This method calls generateMethod for each method of each interface to be implemented (generateMethod is called only once per method, even for those that are specified in several interfaces).

Overrides:
generateInterfaceMethods in class AbstractClassGenerator
Throws:
ClassGenerationException - if a problem occurs.

generateMethod

protected void generateMethod(Method m)
                       throws ClassGenerationException
Generates the interception code for the given method.

Specified by:
generateMethod in class AbstractClassGenerator
Parameters:
m - the method to be generated.
Throws:
ClassGenerationException - if a problem occurs.