You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2010/01/26 17:02:20 UTC
svn commit: r903289 - in /tapestry/tapestry5/trunk/tapestry-core/src/main:
java/org/apache/tapestry5/internal/services/
java/org/apache/tapestry5/services/
resources/org/apache/tapestry5/internal/services/
Author: hlship
Date: Tue Jan 26 16:02:19 2010
New Revision: 903289
URL: http://svn.apache.org/viewvc?rev=903289&view=rev
Log:
Begin rebuilding the ClassTransformation API around the new TransformField and TransformMethod interfaces
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=903289&r1=903288&r2=903289&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java Tue Jan 26 16:02:19 2010
@@ -47,6 +47,8 @@
import org.apache.tapestry5.services.FieldFilter;
import org.apache.tapestry5.services.FieldValueConduit;
import org.apache.tapestry5.services.MethodFilter;
+import org.apache.tapestry5.services.TransformField;
+import org.apache.tapestry5.services.TransformMethod;
import org.apache.tapestry5.services.TransformMethodSignature;
import org.apache.tapestry5.services.TransformUtils;
import org.slf4j.Logger;
@@ -56,6 +58,7 @@
*/
public final class InternalClassTransformationImpl implements InternalClassTransformation
{
+
private static final int INIT_BUFFER_SIZE = 100;
private boolean frozen;
@@ -72,6 +75,122 @@
private final CtClass providerType;
+ class TransformMethodImpl implements TransformMethod
+ {
+ final CtMethod method;
+
+ private final TransformMethodSignature sig;
+
+ private List<Annotation> annotations;
+
+ private final boolean added;
+
+ TransformMethodImpl(CtMethod method, boolean added)
+ {
+ this.method = method;
+ this.sig = toMethodSignature(method);
+ this.added = added;
+
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ if (annotations == null)
+ annotations = extractAnnotations(method);
+
+ return findAnnotationInList(annotationClass, annotations);
+ }
+
+ @Override
+ public TransformMethodSignature getSignature()
+ {
+ return sig;
+ }
+ }
+
+ class TransformFieldImpl implements TransformField
+ {
+ private final CtField field;
+
+ private final String type;
+
+ private final boolean primitive;
+
+ private boolean added;
+
+ private List<Annotation> annotations;
+
+ private Object claimTag;
+
+ TransformFieldImpl(CtField field, boolean added)
+ {
+ this.field = field;
+ this.added = added;
+
+ try
+ {
+ type = field.getType().getName();
+ }
+ catch (NotFoundException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
+ primitive = ClassFabUtils.isPrimitiveType(type);
+ }
+
+ public String getName()
+ {
+ return field.getName();
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public boolean isPrimitive()
+ {
+ return primitive;
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ failIfFrozen();
+
+ if (annotations == null)
+ annotations = extractAnnotations(field);
+
+ return findAnnotationInList(annotationClass, annotations);
+ }
+
+ public void claim(Object tag)
+ {
+ Defense.notNull(tag, "tag");
+
+ failIfFrozen();
+
+ if (claimTag != null)
+ throw new IllegalStateException(
+ String
+ .format(
+ "Field %s of class %s is already claimed by %s and can not be claimed by %s.",
+ getName(), ctClass.getName(), claimTag, tag));
+
+ claimTag = tag;
+ }
+
+ public boolean isClaimed()
+ {
+ return claimTag != null;
+ }
+ }
+
+ private final Map<TransformMethodSignature, TransformMethodImpl> methods = CollectionFactory
+ .newMap();
+
+ private Map<String, TransformFieldImpl> fields = CollectionFactory.newMap();
+
/**
* Map, keyed on InjectKey, of field name. Injections are always added as protected (not
* private) fields to support
@@ -79,20 +198,6 @@
*/
private final Map<InjectionKey, String> injectionCache = CollectionFactory.newMap();
- /**
- * Map from a field to the annotation objects for that field.
- */
- private Map<String, List<Annotation>> fieldAnnotations = CollectionFactory.newMap();
-
- /**
- * Used to identify fields that have been "claimed" by other annotations.
- */
- private Map<String, Object> claimedFields = CollectionFactory.newMap();
-
- private Set<String> addedFieldNames = CollectionFactory.newSet();
-
- private Set<CtBehavior> addedMethods = CollectionFactory.newSet();
-
// Cache of class annotation
private List<Annotation> classAnnotations;
@@ -143,6 +248,10 @@
Component.class, "newInstance", new Class[]
{ InternalComponentResources.class }, null);
+ private static final TransformMethodSignature GET_COMPONENT_RESOURCES_SIGNATURE = new TransformMethodSignature(
+ Modifier.PUBLIC | Modifier.FINAL, ComponentResources.class.getName(),
+ "getComponentResources", null, null);
+
/**
* This is a constructor for a base class.
*/
@@ -164,7 +273,7 @@
logger = componentModel.getLogger();
- preloadMemberNames();
+ preloadMembers();
constructorArgs = CollectionFactory.newList();
constructor.append("{\n");
@@ -174,11 +283,7 @@
resourcesFieldName = addInjectedFieldUncached(InternalComponentResources.class,
"resources", null);
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC
- | Modifier.FINAL, ComponentResources.class.getName(), "getComponentResources",
- null, null);
-
- addMethod(sig, "return " + resourcesFieldName + ";");
+ addMethod(GET_COMPONENT_RESOURCES_SIGNATURE, "return " + resourcesFieldName + ";");
// The "}" will be added later, inside finish().
}
@@ -206,7 +311,7 @@
idAllocator = parentTransformation.getIdAllocator();
- preloadMemberNames();
+ preloadMembers();
constructorArgs = parentTransformation.getConstructorArgs();
@@ -247,10 +352,8 @@
// Free up stuff we don't need after freezing.
// Everything else should be final.
- fieldAnnotations = null;
- claimedFields = null;
- addedFieldNames = null;
- addedMethods = null;
+ fields = null;
+
classAnnotations = null;
methodAnnotations = null;
methodSignatures = null;
@@ -268,25 +371,33 @@
}
/**
- * Loads the names of all declared fields and methods into the idAllocator.
+ * Loads all existing fields and methods defined by the class.
*/
+ private void preloadMembers()
+ {
+ preloadFields();
+ preloadMethods();
+ }
- private void preloadMemberNames()
+ private void preloadMethods()
{
- verifyFields();
+ for (CtMethod method : ctClass.getDeclaredMethods())
+ {
+ recordMethod(method, false);
- addMemberNames(ctClass.getDeclaredFields());
- addMemberNames(ctClass.getDeclaredMethods());
+ idAllocator.allocateId(method.getName());
+ }
}
/**
- * Invoked during instance construction to check that all fields are either:
+ * Converts and stores {@link CtField} to {@link TransformField}, and checks that each field is
+ * one of:
* <ul>
* <li>private</li>
* <li>static</li>
- * <li>groovy.lang.MetaClass (for Groovy compatiblility)</li> </li>
+ * <li>groovy.lang.MetaClass (for Groovy compatibility)</li> </li>
*/
- void verifyFields()
+ private void preloadFields()
{
List<String> names = CollectionFactory.newList();
@@ -294,6 +405,10 @@
{
String name = field.getName();
+ idAllocator.allocateId(name);
+
+ fields.put(name, new TransformFieldImpl(field, false));
+
int modifiers = field.getModifiers();
// Fields must be either static or private.
@@ -318,21 +433,9 @@
throw new RuntimeException(ServicesMessages.nonPrivateFields(getClassName(), names));
}
- private void addMemberNames(CtMember[] members)
- {
- for (CtMember member : members)
- {
- idAllocator.allocateId(member.getName());
- }
- }
-
public <T extends Annotation> T getFieldAnnotation(String fieldName, Class<T> annotationClass)
{
- failIfFrozen();
-
- List<Annotation> annotations = findFieldAnnotations(fieldName);
-
- return findAnnotationInList(annotationClass, annotations);
+ return getField(fieldName).getAnnotation(annotationClass);
}
public <T extends Annotation> T getMethodAnnotation(TransformMethodSignature signature,
@@ -340,7 +443,7 @@
{
failIfFrozen();
- CtMethod method = findMethod(signature);
+ CtMethod method = findDeclaredOrSuperclassMethod(signature);
if (method == null)
throw new IllegalArgumentException(ServicesMessages
@@ -380,19 +483,6 @@
return findAnnotationInList(annotationClass, getClassAnnotations());
}
- private List<Annotation> findFieldAnnotations(String fieldName)
- {
- List<Annotation> annotations = fieldAnnotations.get(fieldName);
-
- if (annotations == null)
- {
- annotations = findAnnotationsForField(fieldName);
- fieldAnnotations.put(fieldName, annotations);
- }
-
- return annotations;
- }
-
private List<Annotation> findMethodAnnotations(CtMethod method)
{
List<Annotation> annotations = methodAnnotations.get(method);
@@ -407,13 +497,6 @@
return annotations;
}
- private List<Annotation> findAnnotationsForField(String fieldName)
- {
- CtField field = findDeclaredCtField(fieldName);
-
- return extractAnnotations(field);
- }
-
private List<Annotation> extractAnnotations(CtMember member)
{
try
@@ -454,6 +537,21 @@
}
}
+ @Override
+ public TransformField getField(String fieldName)
+ {
+ failIfFrozen();
+
+ TransformField result = fields.get(fieldName);
+
+ if (result != null)
+ return result;
+
+ throw new RuntimeException(String.format("Class %s does not contain a field named '%s'.",
+ ctClass.getName(), fieldName));
+
+ }
+
private CtField findDeclaredCtField(String fieldName)
{
try
@@ -462,8 +560,7 @@
}
catch (NotFoundException ex)
{
- throw new RuntimeException(ServicesMessages.missingDeclaredField(ctClass, fieldName),
- ex);
+ throw new RuntimeException(ex);
}
}
@@ -559,6 +656,8 @@
ctClass.addMethod(newMethod);
+ recordMethod(newMethod, true);
+
TransformMethodSignature sig = getMethodSignature(newMethod);
addMethodToDescription("add default", sig, "<default>");
@@ -570,6 +669,13 @@
}
}
+ private void recordMethod(CtMethod method, boolean asNew)
+ {
+ TransformMethodImpl tmi = new TransformMethodImpl(method, asNew);
+
+ methods.put(tmi.getSignature(), tmi);
+ }
+
/**
* Check to see if the target class (or any of its super classes) implements the provided
* interface. This is geared
@@ -595,24 +701,7 @@
public void claimField(String fieldName, Object tag)
{
- Defense.notBlank(fieldName, "fieldName");
- Defense.notNull(tag, "tag");
-
- failIfFrozen();
-
- Object existing = claimedFields.get(fieldName);
-
- if (existing != null)
- {
- String message = ServicesMessages
- .fieldAlreadyClaimed(fieldName, ctClass, existing, tag);
-
- throw new RuntimeException(message);
- }
-
- // TODO: Ensure that fieldName is a known field?
-
- claimedFields.put(fieldName, tag);
+ getField(fieldName).claim(tag);
}
public void addMethod(TransformMethodSignature signature, String methodBody)
@@ -667,8 +756,7 @@
ctClass.addMethod(method);
- if (addAsNew)
- addedMethods.add(method);
+ recordMethod(method, addAsNew);
}
catch (CannotCompileException ex)
{
@@ -719,6 +807,8 @@
method.setExceptionTypes(exceptions);
ctClass.addMethod(method);
+
+ recordMethod(method, false);
}
catch (CannotCompileException ex)
{
@@ -759,7 +849,7 @@
{
failIfFrozen();
- CtMethod method = findMethod(methodSignature);
+ CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
try
{
@@ -772,15 +862,13 @@
}
addMethodToDescription("extend", methodSignature, methodBody);
-
- addedMethods.add(method);
}
public void extendExistingMethod(TransformMethodSignature methodSignature, String methodBody)
{
failIfFrozen();
- CtMethod method = findMethod(methodSignature);
+ CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
try
{
@@ -803,7 +891,7 @@
CtClass returnType = findCtClass(sourceMethod.getReturnType());
CtClass[] parameters = buildCtClassList(sourceMethod.getParameterTypes());
CtClass[] exceptions = buildCtClassList(sourceMethod.getExceptionTypes());
- CtMethod source = findMethod(sourceMethod);
+ CtMethod source = findDeclaredOrSuperclassMethod(sourceMethod);
try
{
@@ -816,6 +904,8 @@
method.setBody(source, null);
ctClass.addMethod(method);
+
+ recordMethod(method, false);
}
catch (CannotCompileException ex)
{
@@ -837,7 +927,7 @@
{
failIfFrozen();
- CtMethod method = findMethod(methodSignature);
+ CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
CtClass exceptionCtType = findCtClass(exceptionType);
try
@@ -857,7 +947,7 @@
{
failIfFrozen();
- CtMethod method = findMethod(methodSignature);
+ CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
try
{
@@ -903,7 +993,7 @@
formatter.format("\n%s\n\n", methodBody);
}
- private CtMethod findMethod(TransformMethodSignature methodSignature)
+ private CtMethod findDeclaredOrSuperclassMethod(TransformMethodSignature methodSignature)
{
CtMethod method = findDeclaredMethod(methodSignature);
@@ -921,13 +1011,9 @@
private CtMethod findDeclaredMethod(TransformMethodSignature methodSignature)
{
- for (CtMethod method : ctClass.getDeclaredMethods())
- {
- if (match(method, methodSignature))
- return method;
- }
+ TransformMethodImpl tmi = methods.get(methodSignature);
- return null;
+ return tmi == null ? null : tmi.method;
}
private CtMethod addOverrideOfSuperclassMethod(TransformMethodSignature methodSignature)
@@ -940,12 +1026,14 @@
{
if (match(method, methodSignature))
{
- // TODO: If the moethod is not overridable (i.e. private, or final)?
+ // TODO: If the method is not overridable (i.e. private, or final)?
// Perhaps we should limit it to just public methods.
CtMethod newMethod = CtNewMethod.delegator(method, ctClass);
ctClass.addMethod(newMethod);
+ recordMethod(newMethod, true);
+
return newMethod;
}
}
@@ -1021,22 +1109,12 @@
List<String> result = CollectionFactory.newList();
- try
+ for (TransformFieldImpl field : fields.values())
{
- for (CtField field : ctClass.getDeclaredFields())
- {
- if (!isInstanceField(field))
- continue;
+ String fieldName = field.getName();
- String fieldName = field.getName();
-
- if (filter.accept(fieldName, field.getType().getName()))
- result.add(fieldName);
- }
- }
- catch (NotFoundException ex)
- {
- throw new RuntimeException(ex);
+ if (filter.accept(fieldName, field.getType()))
+ result.add(fieldName);
}
Collections.sort(result);
@@ -1073,10 +1151,8 @@
List<TransformMethodSignature> result = CollectionFactory.newList();
- for (CtMethod method : ctClass.getDeclaredMethods())
+ for (TransformMethodSignature sig : methods.keySet())
{
- TransformMethodSignature sig = getMethodSignature(method);
-
if (filter.accept(sig))
result.add(sig);
}
@@ -1091,26 +1167,31 @@
TransformMethodSignature result = methodSignatures.get(method);
if (result == null)
{
- try
- {
- String type = method.getReturnType().getName();
- String[] parameters = toTypeNames(method.getParameterTypes());
- String[] exceptions = toTypeNames(method.getExceptionTypes());
+ result = toMethodSignature(method);
- result = new TransformMethodSignature(method.getModifiers(), type,
- method.getName(), parameters, exceptions);
-
- methodSignatures.put(method, result);
- }
- catch (NotFoundException ex)
- {
- throw new RuntimeException(ex);
- }
+ methodSignatures.put(method, result);
}
return result;
}
+ private TransformMethodSignature toMethodSignature(CtMethod method)
+ {
+ try
+ {
+ String type = method.getReturnType().getName();
+ String[] parameters = toTypeNames(method.getParameterTypes());
+ String[] exceptions = toTypeNames(method.getExceptionTypes());
+
+ return new TransformMethodSignature(method.getModifiers(), type, method.getName(),
+ parameters, exceptions);
+ }
+ catch (NotFoundException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
private String[] toTypeNames(CtClass[] types)
{
String[] result = new String[types.length];
@@ -1127,22 +1208,14 @@
List<String> names = CollectionFactory.newList();
- Set<String> skipped = CollectionFactory.newSet();
-
- skipped.addAll(claimedFields.keySet());
- skipped.addAll(addedFieldNames);
-
- if (removedFieldNames != null)
- skipped.addAll(removedFieldNames);
-
- for (CtField field : ctClass.getDeclaredFields())
+ for (TransformFieldImpl f : fields.values())
{
- if (!isInstanceField(field))
+ if (f.added || f.isClaimed())
continue;
- String name = field.getName();
+ String name = f.getName();
- if (skipped.contains(name))
+ if (removedFieldNames != null && removedFieldNames.contains(name))
continue;
names.add(name);
@@ -1162,27 +1235,17 @@
public String getFieldType(String fieldName)
{
- failIfFrozen();
-
- CtClass type = getFieldCtType(fieldName);
-
- return type.getName();
+ return getField(fieldName).getType();
}
public boolean isField(String fieldName)
{
failIfFrozen();
- try
- {
- CtField field = ctClass.getDeclaredField(fieldName);
+ // Only declared instance fields end up in this map, and all
+ // fields are either static or private.
- return isInstanceField(field);
- }
- catch (NotFoundException ex)
- {
- return false;
- }
+ return fields.containsKey(fieldName);
}
public int getFieldModifiers(String fieldName)
@@ -1227,6 +1290,9 @@
field.setModifiers(modifiers);
ctClass.addField(field);
+
+ fields.put(fieldName, new TransformFieldImpl(field, true));
+
}
catch (NotFoundException ex)
{
@@ -1239,8 +1305,6 @@
formatter.format("add field: %s %s %s;\n\n", Modifier.toString(modifiers), type, fieldName);
- addedFieldNames.add(fieldName);
-
return fieldName;
}
@@ -1318,8 +1382,6 @@
addInjectToConstructor(fieldName, ctType, value);
- addedFieldNames.add(fieldName);
-
return fieldName;
}
@@ -1521,6 +1583,8 @@
ctClass.addMethod(initializerMethod);
+ recordMethod(initializerMethod, false);
+
// Replace the constructor body with one that fails. This leaves, as an open question,
// what to do about any other constructors.
@@ -1853,6 +1917,15 @@
ExprEditor editor = new ExprEditor()
{
+ private final Set<CtBehavior> addedMethods = CollectionFactory.newSet();
+
+ {
+ for (TransformMethodImpl tmi : methods.values())
+ {
+ if (tmi.added)
+ addedMethods.add(tmi.method);
+ }
+ }
public void edit(FieldAccess access) throws CannotCompileException
{
@@ -1943,7 +2016,7 @@
{
Defense.notNull(signature, "signature");
- CtMethod method = findMethod(signature);
+ CtMethod method = findDeclaredOrSuperclassMethod(signature);
int lineNumber = method.getMethodInfo2().getLineNumber(0);
CtClass enclosingClass = method.getDeclaringClass();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java?rev=903289&r1=903288&r2=903289&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java Tue Jan 26 16:02:19 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -47,21 +47,11 @@
return MESSAGES.get("markup-writer-no-current-element");
}
- static String missingDeclaredField(CtClass ctClass, String fieldName)
- {
- return MESSAGES.format("missing-declared-field", ctClass.getName(), fieldName);
- }
-
static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
{
return MESSAGES.format("error-adding-method", ctClass.getName(), methodName, cause);
}
- static String fieldAlreadyClaimed(String fieldName, CtClass ctClass, Object existingTag, Object newTag)
- {
- return MESSAGES.format("field-already-claimed", fieldName, ctClass.getName(), existingTag, newTag);
- }
-
static String noDeclaredMethod(CtClass ctClass, TransformMethodSignature methodSignature)
{
return MESSAGES.format("no-declared-method", ctClass.getName(), methodSignature);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java?rev=903289&r1=903288&r2=903289&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java Tue Jan 26 16:02:19 2010
@@ -33,22 +33,21 @@
* naming conventions. Most of the changes are provided by different implementations of
* {@link ComponentClassTransformWorker}.
* <p/>
- * Much of this information is somewhat like ordinary reflection, but applies to a class that has
- * not yet been loaded.
+ * Much of this information is somewhat like ordinary reflection, but applies to a class that has not yet been loaded.
* <p/>
- * 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.
+ * 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.
* <p/>
- * A ClassTransformation contains all the state data specific to a particular class being
- * transformed. A number of <em>workers</em> will operate upon the ClassTransformation to effect the
- * desired changes before the true class is loaded into memory.
+ * A ClassTransformation contains all the state data specific to a particular class being transformed. A number of
+ * <em>workers</em> will operate upon the ClassTransformation to effect the desired changes before the true class is
+ * loaded into memory.
* <p/>
- * 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).
+ * 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).
* <p/>
- * The majority of methods concern the <em>declared</em> members (field and methods) of a specific
- * class, rather than any fields or methods inherited from a base class.
+ * The majority of methods concern the <em>declared</em> members (field and methods) of a specific class, rather than
+ * any fields or methods inherited from a base class.
*
* @see org.apache.tapestry5.services.TapestryModule#contributeComponentClassTransformWorker(org.apache.tapestry5.ioc.OrderedConfiguration,
* org.apache.tapestry5.ioc.ObjectLocator, InjectionProvider, ComponentClassResolver)
@@ -134,10 +133,23 @@
* @return the annotation if present, or null otherwise
* @throws IllegalArgumentException
* if the fieldName does not correspond to a declared field
+ * @deprecated Use {@link TransformField#getAnnotation(Class)} instead
*/
<T extends Annotation> T getFieldAnnotation(String fieldName, Class<T> annotationClass);
/**
+ * Locates a declared field by its field name. The field must exist.
+ *
+ * @param name
+ * of declared field
+ * @return field information
+ * @throws RuntimeException
+ * if no such field
+ * @since 5.2.0
+ */
+ TransformField getField(String fieldName);
+
+ /**
* Finds an annotation on a declared method.
*
* @param <T>
@@ -185,8 +197,7 @@
void makeReadOnly(String fieldName);
/**
- * Finds any declared <em>instance</em> fields that have not been claimed (via
- * {@link #claimField(String, Object)})
+ * Finds any declared <em>instance</em> fields that have not been claimed (via {@link #claimField(String, Object)})
* and returns the names of those fields. May return an empty array.
*/
List<String> findUnclaimedFields();
@@ -196,8 +207,9 @@
*
* @param fieldName
* @return the type of the field, as a string
- * @throws IllegalArgumentException
+ * @throws RuntimeException
* if the fieldName does not correspond to a declared instance field
+ * @deprecated Use {@link TransformField#getType()} instead
*/
String getFieldType(String fieldName);
@@ -300,8 +312,8 @@
* methods of the interface
* are added.
* <p/>
- * TODO: Checking that the names of methods in the interface do not conflict with the names of
- * methods present in the (unmodified) class.
+ * TODO: Checking that the names of methods in the interface do not conflict with the names of methods present in
+ * the (unmodified) class.
*
* @param interfaceClass
* the interface to be implemented by the class
@@ -315,15 +327,14 @@
* method (i.e. {@link javassist.CtBehavior#insertAfter(java.lang.String)}). To access or change
* the return value, use the <code>$_</code> pseudo variable.
* <p/>
- * The method may be declared in the class, or may be inherited from a super-class. For
- * inherited methods, a method body is added that first invokes the super implementation. Use
- * {@link #addMethod(TransformMethodSignature, String)} when it is necessary to control when the
- * super-class method is invoked.
+ * The method may be declared in the class, or may be inherited from a super-class. For inherited methods, a method
+ * body is added that first invokes the super implementation. Use
+ * {@link #addMethod(TransformMethodSignature, String)} when it is necessary to control when the super-class method
+ * is invoked.
* <p/>
* The extended method is considered <em>new</em>. New methods <em>are not</em> scanned for
- * {@linkplain #removeField(String)} removed}, {@linkplain #replaceReadAccess(String, String)}
- * read replaced}, or {@linkplain #replaceWriteAccess(String, String) write replaced} fields.
- * Generally that's what you want!
+ * {@linkplain #removeField(String)} removed}, {@linkplain #replaceReadAccess(String, String)} read replaced}, or
+ * {@linkplain #replaceWriteAccess(String, String) write replaced} fields. Generally that's what you want!
*
* @param methodSignature
* the signature of the method to extend
@@ -353,15 +364,13 @@
/**
* Inserts code at the beginning of a method body (i.e. {@link CtBehavior#insertBefore(String)}.
* <p/>
- * 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
- * {@link #addMethod(TransformMethodSignature, String)} when it is necessary to control when the
- * super-class method is invoked.
+ * 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 {@link #addMethod(TransformMethodSignature, String)}
+ * when it is necessary to control when the super-class method is invoked.
* <p/>
* <p/>
- * Like {@link #extendExistingMethod(TransformMethodSignature, String)}, this method is
- * generally used to "wrap" an existing method adding additional functionality such as caching
- * or transaction support.
+ * Like {@link #extendExistingMethod(TransformMethodSignature, String)}, this method is generally used to "wrap" an
+ * existing method adding additional functionality such as caching or transaction support.
*
* @param methodSignature
* @param methodBody
@@ -371,8 +380,7 @@
void prefixMethod(TransformMethodSignature methodSignature, String methodBody);
/**
- * Returns the name of a field that provides the {@link org.apache.tapestry5.ComponentResources}
- * for the transformed
+ * Returns the name of a field that provides the {@link org.apache.tapestry5.ComponentResources} for the transformed
* component. This will be a protected field, accessible to the class and subclasses.
*
* @return name of field
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java?rev=903289&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java Tue Jan 26 16:02:19 2010
@@ -0,0 +1,59 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.services;
+
+import org.apache.tapestry5.ioc.AnnotationProvider;
+
+/**
+ * A field defined by (or created within) a {@link ClassTransformation},
+ * allowing the details of the field to be
+ * accessed or modified.
+ *
+ * @since 5.2.0
+ */
+public interface TransformField extends AnnotationProvider
+{
+ /**
+ * Returns the name of the field.
+ */
+ String getName();
+
+ /**
+ * Returns the field's type, either a primitive name
+ * or a fully qualified class name, or an array type name
+ * (in Java source syntax).
+ */
+ String getType();
+
+ /**
+ * True if the field is a primitive type, not an object type.
+ * Array types are object types.
+ */
+ boolean isPrimitive();
+
+ /**
+ * Claims the 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.
+ *
+ * @param tag
+ * a non-null object that represents why the field is being tagged (this is typically
+ * a specific annotation on the field)
+ * @throws IllegalStateException
+ * if the field is already claimed for some other tag
+ */
+ void claim(Object tag);
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java?rev=903289&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java Tue Jan 26 16:02:19 2010
@@ -0,0 +1,32 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.services;
+
+import org.apache.tapestry5.ioc.AnnotationProvider;
+
+/**
+ * A method defined by (or created within) a {@link ClassTransformation}, allowing
+ * for access and manipulation of the method.
+ *
+ * @since 5.2.0
+ */
+public interface TransformMethod extends AnnotationProvider
+{
+ /**
+ * @return the signature for the method, defining name, visibility, return type, parameter types and thrown
+ * exceptions
+ */
+ TransformMethodSignature getSignature();
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties?rev=903289&r1=903288&r2=903289&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties Tue Jan 26 16:02:19 2010
@@ -1,4 +1,4 @@
-# Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+# Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,9 +16,7 @@
markup-writer-no-current-element=This markup writer does not have a current element. \
The current element is established with the first call to element() and is \
maintained across subsequent calls.
-missing-declared-field=Class %s does not contain a field named '%s'.
error-adding-method=Error adding method %s to class %s: %s
-field-already-claimed=Field %s of class %s is already claimed by %s and can not be claimed by %s.
no-declared-method=Class %s does not declare method '%s'.
class-not-transformed=Class %s was not transformed for use as a component; this can happen if it is an interface, or was not in a package subject to component transformation.
missing-template-resource=Template resource %s does not exist.