org.apache.tapestry5.services
Interface ClassTransformation

All Superinterfaces:
AnnotationProvider
All Known Subinterfaces:
InternalClassTransformation
All Known Implementing Classes:
InternalClassTransformationImpl

public interface ClassTransformation
extends AnnotationProvider

Contains class-specific information used when transforming a raw component class into an executable component class. An executable class is one that has been transformed to work within Tapestry. This includes adding interfaces (Component) but also transforming access to fields, based on annotations and naming conventions. Most of the changes are provided by different implementations of ComponentClassTransformWorker.

Much of this information is somewhat like ordinary reflection, but applies to a class that has not yet been loaded.

Transformation is primarily about identifying annotations on fields and on methods and changing the class, adding new interfaces, fields and methods, and deleting some existing fields.

A ClassTransformation contains all the state data specific to a particular class being transformed. A number of workers will operate upon the ClassTransformation to effect the desired changes before the true class is loaded into memory.

Instances of this class are not designed to be thread safe, access to an instance should be restricted to a single thread. In fact, the design of this type is to allow stateless singletons in multiple threads to work on thread-specific data (within the ClassTransformation).

The majority of methods concern the declared members (field and methods) of a specific class, rather than any fields or methods inherited from a base class.

See Also:
TapestryModule.contributeComponentClassTransformWorker(org.apache.tapestry5.ioc.OrderedConfiguration, org.apache.tapestry5.ioc.ObjectLocator, InjectionProvider, ComponentClassResolver)

Method Summary
 void addCatch(TransformMethodSignature methodSignature, String exceptionType, String body)
          Adds a catch block to the method.
 String addField(int modifiers, String type, String suggestedName)
          Defines a new declared field for the class.
 void addImplementedInterface(Class interfaceClass)
          Transforms the class to implement the indicated interface.
 String addInjectedField(Class type, String suggestedName, Object value)
          Defines a new protected instance variable whose initial value is provided statically, via a constructor parameter.
 void addMethod(TransformMethodSignature signature, String methodBody)
          Adds a new method to the transformed class.
 void addTransformedMethod(TransformMethodSignature methodSignature, String methodBody)
          As with addMethod(TransformMethodSignature, String), but field references inside the method will be transformed, and the method must not already exist.
 void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice)
          Adds method advice for the indicated method.
 void claimField(String fieldName, Object tag)
          Claims a field so as to ensure that only a single annotation is applied to any single field.
 void extendConstructor(String statement)
          Adds a statement to the constructor.
 void extendExistingMethod(TransformMethodSignature methodSignature, String methodBody)
          Like extendMethod(TransformMethodSignature, String), but the extension does not mark the method as new, and field changes will be processed.
 void extendMethod(TransformMethodSignature methodSignature, String methodBody)
          Extends an existing method.
 List<String> findFields(FieldFilter filter)
          Finds all unclaimed fields matched by the provided filter.
 List<String> findFieldsWithAnnotation(Class<? extends Annotation> annotationClass)
          Generates a list of the names of declared instance fields that have the indicated annotation.
 List<TransformMethodSignature> findMethods(MethodFilter filter)
          Finds all methods matched by the provided filter.
 List<TransformMethodSignature> findMethodsWithAnnotation(Class<? extends Annotation> annotationClass)
          Finds all methods defined in the class that are marked with the provided annotation.
 List<String> findUnclaimedFields()
          Finds any declared instance fields that have not been claimed (via claimField(String, Object)) and returns the names of those fields.
 String getClassName()
          Returns the fully qualified class name of the class being transformed.
<T extends Annotation>
T
getFieldAnnotation(String fieldName, Class<T> annotationClass)
          Finds an annotation on a declared instance field.
 int getFieldModifiers(String fieldName)
          Returns the modifiers for the named field.
 String getFieldType(String fieldName)
          Obtains the type of a declared instance field.
 org.slf4j.Logger getLogger()
          Returns a logger, based on the class name being transformed, to which warnings or errors concerning the class being transformed may be logged.
<T extends Annotation>
T
getMethodAnnotation(TransformMethodSignature method, Class<T> annotationClass)
          Finds an annotation on a declared method.
 String getMethodIdentifier(TransformMethodSignature signature)
          Converts a signature to a string used to identify the method; this consists of the TransformMethodSignature.getMediumDescription() appended with source file information and line number information (when available).
 String getResourcesFieldName()
          Returns the name of a field that provides the ComponentResources for the transformed component.
 void injectField(String fieldName, Object value)
          Converts the field into a read only field whose value is the provided value.
 boolean isField(String fieldName)
          Returns true if the indicated name is a private instance field.
 boolean isMethodOverride(TransformMethodSignature methodSignature)
          Returns true if the method is an override of a method from the parent class.
 boolean isRootTransformation()
          Returns true if this transformation represents a root class (one that extends directly from Object), or false if this transformation is an extension of another transformed class.
 void makeReadOnly(String fieldName)
          Changes the field to be read only.
 String newMemberName(String suggested)
          Returns the name of a new member (field or method).
 String newMemberName(String prefix, String baseName)
          As with newMemberName(String), but the suggested name is constructed from the prefix and base name.
 void prefixMethod(TransformMethodSignature methodSignature, String methodBody)
          Inserts code at the beginning of a method body (i.e.
 void removeField(String fieldName)
          Removes a field entirely; this is useful for fields that are replaced entirely by computed values.
 void replaceReadAccess(String fieldName, String methodName)
          Replaces all read-references to the specified field with invocations of the specified method name.
 void replaceWriteAccess(String fieldName, String methodName)
          Replaces all write accesses to the specified field with invocations of the specified method name.
 Class toClass(String type)
          Converts a type name into a corresponding class (possibly, a transformed class).
 
Methods inherited from interface org.apache.tapestry5.ioc.AnnotationProvider
getAnnotation
 

Method Detail

getClassName

String getClassName()
Returns the fully qualified class name of the class being transformed.


newMemberName

String newMemberName(String suggested)
Returns the name of a new member (field or method). Ensures that the resulting name does not conflict with any existing member (declared by the underlying class, or inherited from a base class).

Parameters:
suggested - the suggested value for the member
Returns:
a unique name for the member

newMemberName

String newMemberName(String prefix,
                     String baseName)
As with newMemberName(String), but the suggested name is constructed from the prefix and base name. An underscore will seperate the prefix from the base name.

Parameters:
prefix - for the generated name
baseName - an name, often of an existing field or method
Returns:
a unique name

findFieldsWithAnnotation

List<String> findFieldsWithAnnotation(Class<? extends Annotation> annotationClass)
Generates a list of the names of declared instance fields that have the indicated annotation. Non-private and static fields are ignored. Only the names of private instance fields are returned.


findMethodsWithAnnotation

List<TransformMethodSignature> findMethodsWithAnnotation(Class<? extends Annotation> annotationClass)
Finds all methods defined in the class that are marked with the provided annotation.

Parameters:
annotationClass -
Returns:
a list of method signature (which may be empty) in ascending order
See Also:
findMethods(MethodFilter)

findMethods

List<TransformMethodSignature> findMethods(MethodFilter filter)
Finds all methods matched by the provided filter.

Parameters:
filter - Passed each method signature, it may include or exclude each potential
Returns:
a list of matching method signatures (which may be empty) in ascending order (by method name), but descending order (by parameter count) within overrides of a single method name.

findFields

List<String> findFields(FieldFilter filter)
Finds all unclaimed fields matched by the provided filter. Only considers private instance fields.

Parameters:
filter - passed each field name and field type
Returns:
the names of all matched fields, in ascending order

getFieldAnnotation

<T extends Annotation> T getFieldAnnotation(String fieldName,
                                            Class<T> annotationClass)
Finds an annotation on a declared instance field.

Type Parameters:
T - constrains parameter and return value to Annotation types
Parameters:
fieldName - the name of the field, which must exist
annotationClass - the type of annotation to access
Returns:
the annotation if present, or null otherwise
Throws:
IllegalArgumentException - if the fieldName does not correspond to a declared field

getMethodAnnotation

<T extends Annotation> T getMethodAnnotation(TransformMethodSignature method,
                                             Class<T> annotationClass)
Finds an annotation on a declared method.

Type Parameters:
T - constrains parameter and return value to Annotation types
Parameters:
method - the method signature to search
annotationClass - the type of annotation to access
Returns:
the annotation if present, or null otherwise
Throws:
IllegalArgumentException - if the method signature does not correspond to a declared method

claimField

void claimField(String fieldName,
                Object tag)
Claims a field so as to ensure that only a single annotation is applied to any single field. When a transformation occurs (driven by a field annotation), the field is claimed (using the annotation object as the tag). If a field has multiple conflicting annotations, this will be discovered when the code attempts to claim the field a second time.

Parameters:
fieldName - the name of the field that is being claimed
tag - a non-null object that represents why the field is being tagged (this is typically a specific annotation on the field)
Throws:
IllegalArgumentException - if the fieldName does not correspond to a declared instance field
IllegalStateException - if the field is already claimed for some other tag

makeReadOnly

void makeReadOnly(String fieldName)
Changes the field to be read only. Any existing code that changes the field will cause a runtime exception.

Parameters:
fieldName - name of field to so change

findUnclaimedFields

List<String> findUnclaimedFields()
Finds any declared instance fields that have not been claimed (via claimField(String, Object)) and returns the names of those fields. May return an empty array.


getFieldType

String getFieldType(String fieldName)
Obtains the type of a declared instance field.

Parameters:
fieldName -
Returns:
the type of the field, as a string
Throws:
IllegalArgumentException - if the fieldName does not correspond to a declared instance field

isField

boolean isField(String fieldName)
Returns true if the indicated name is a private instance field.

Parameters:
fieldName -
Returns:
true if field exists

addField

String addField(int modifiers,
                String type,
                String suggestedName)
Defines a new declared field for the class. The suggestedName may be modified to ensure uniqueness.

Parameters:
modifiers - modifiers for the field (typically, Modifier.PRIVATE)
type - the type for the field, as a string
suggestedName - the desired name for the field, which may be modified (for uniqueness) when returned
Returns:
the (uniqued) name for the field

addInjectedField

String addInjectedField(Class type,
                        String suggestedName,
                        Object value)
Defines a new protected instance variable whose initial value is provided statically, via a constructor parameter. The transformation caches the result, so calling this method repeatedly with the same type and value will return the same field name. Caching extends to the parent transformation, so that a value injected into a parent class will be available (via the protected instance variable) to subclasses.

Parameters:
type - the type of object to inject
suggestedName - the suggested name for the new field
value - to be injected. This value is retained.
Returns:
the actual name of the injected field

injectField

void injectField(String fieldName,
                 Object value)
Converts the field into a read only field whose value is the provided value. This is used when converting an existing field into a read-only injected value.

Parameters:
fieldName - name of field to convert
value - the value provided by the field

addImplementedInterface

void addImplementedInterface(Class interfaceClass)
Transforms the class to implement the indicated interface. If the class (or its super class) does not already implement the interface, then the interface is added, and default implementations of any methods of the interface are added.

TODO: Checking that the names of methods in the interface do not conflict with the names of methods present in the (unmodified) class.

Parameters:
interfaceClass - the interface to be implemented by the class
Throws:
IllegalArgumentException - if the interfaceClass argument does not represent an interface

extendMethod

void extendMethod(TransformMethodSignature methodSignature,
                  String methodBody)
Extends an existing method. The provided method body is inserted at the end of the existing method (i.e. CtBehavior.insertAfter(java.lang.String)). To access or change the return value, use the $_ pseudo variable.

The method may be declared in the class, or may be inherited from a super-class. For inherited methods, a method is added that first invokes the super implementation. Use addMethod(TransformMethodSignature, String) when it is necessary to control when the super-class method is invoked.

The extended method is considered new. New methods are not scanned for removeField(String) removed}, replaceReadAccess(String, String) read replaced}, or write replaced fields. Generally that's what you want!

Parameters:
methodSignature - the signature of the method to extend
methodBody - the body of code
Throws:
MethodCompileException - if the provided Javassist method body can not be compiled
See Also:
extendExistingMethod(TransformMethodSignature, String)

extendExistingMethod

void extendExistingMethod(TransformMethodSignature methodSignature,
                          String methodBody)
Like extendMethod(TransformMethodSignature, String), but the extension does not mark the method as new, and field changes will be processed.

Parameters:
methodSignature - signature of the method to extend
methodBody - the body of code
Throws:
MethodCompileException - if the provided method body can not be compiled
See Also:
prefixMethod(TransformMethodSignature, String)

prefixMethod

void prefixMethod(TransformMethodSignature methodSignature,
                  String methodBody)
Inserts code at the beginning of a method body (i.e. CtBehavior.insertBefore(String).

The method may be declared in the class, or may be inherited from a super-class. For inherited methods, a method is added that first invokes the super implementation. Use addMethod(TransformMethodSignature, String) when it is necessary to control when the super-class method is invoked.

Like extendExistingMethod(TransformMethodSignature, String), this method is generally used to "wrap" an existing method adding additional functionality such as caching or transaction support.

Parameters:
methodSignature -
methodBody -
Throws:
MethodCompileException - if the provided method body can not be compiled

getResourcesFieldName

String getResourcesFieldName()
Returns the name of a field that provides the ComponentResources for the transformed component. This will be a protected field, accessible to the class and subclasses.

Returns:
name of field

addMethod

void addMethod(TransformMethodSignature signature,
               String methodBody)
Adds a new method to the transformed class. Replaces any existing method declared for the class. When overriding a super-class method, you should use extendMethod(TransformMethodSignature, String), or you should remember to invoke the super class implemetation explicitly. Use this method to control when the super-class implementation is invoked.


addTransformedMethod

void addTransformedMethod(TransformMethodSignature methodSignature,
                          String methodBody)
As with addMethod(TransformMethodSignature, String), but field references inside the method will be transformed, and the method must not already exist.


extendConstructor

void extendConstructor(String statement)
Adds a statement to the constructor. The statement is added as is, though a newline is added.

Parameters:
statement - the statement to add, which should end with a semicolon

replaceReadAccess

void replaceReadAccess(String fieldName,
                       String methodName)
Replaces all read-references to the specified field with invocations of the specified method name. Replacements do not occur in methods added via addMethod(TransformMethodSignature, String) or extendMethod(TransformMethodSignature, String).


replaceWriteAccess

void replaceWriteAccess(String fieldName,
                        String methodName)
Replaces all write accesses to the specified field with invocations of the specified method name. The method should take a single parameter of the same type as the field. Replacements do not occur in methods added via addMethod(TransformMethodSignature, String) or extendMethod(TransformMethodSignature, String).


removeField

void removeField(String fieldName)
Removes a field entirely; this is useful for fields that are replaced entirely by computed values.

Parameters:
fieldName - the name of the field to remove
See Also:
replaceReadAccess(String, String), replaceWriteAccess(String, String)

toClass

Class toClass(String type)
Converts a type name into a corresponding class (possibly, a transformed class). Primitive type names are returned as wrapper types.


getLogger

org.slf4j.Logger getLogger()
Returns a logger, based on the class name being transformed, to which warnings or errors concerning the class being transformed may be logged.


getFieldModifiers

int getFieldModifiers(String fieldName)
Returns the modifiers for the named field.


getMethodIdentifier

String getMethodIdentifier(TransformMethodSignature signature)
Converts a signature to a string used to identify the method; this consists of the TransformMethodSignature.getMediumDescription() appended with source file information and line number information (when available).

Parameters:
signature -
Returns:
a string that identifies the class, method name, types of parameters, source file and source line number

isRootTransformation

boolean isRootTransformation()
Returns true if this transformation represents a root class (one that extends directly from Object), or false if this transformation is an extension of another transformed class.

Returns:
true if root class, false if sub-class

addCatch

void addCatch(TransformMethodSignature methodSignature,
              String exceptionType,
              String body)
Adds a catch block to the method. The body should end with a return or a throw. The special Javassist variable $e is the exception instance.

Parameters:
methodSignature - method to be extended.
exceptionType - fully qualified class name of exception
body - code to execute

advise

void advise(TransformMethodSignature methodSignature,
            ComponentMethodAdvice advice)
Adds method advice for the indicated method.


isMethodOverride

boolean isMethodOverride(TransformMethodSignature methodSignature)
Returns true if the method is an override of a method from the parent class.

Parameters:
methodSignature - signature of method to check
Returns:
true if the parent class contains a method with the name signature


Copyright © 2006-2009 Apache Software Foundation. All Rights Reserved.