Author: hlship
Date: Tue Jan 26 16:02:54 2010
New Revision: 903293

URL: http://svn.apache.org/viewvc?rev=903293&view=rev
Log:
Build new methods onto ClassTransformation to match fields and methods, 
returning TransformFields and TransformMethods
Add assignIndirect() methods to TransformField
Add extend() method to TransformMethod

Removed:
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/MixinWorkerTest.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
    
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/internal/transform/ComponentWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldFilter.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodFilter.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/TextOnlyOnDisabledTextField.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
 Tue Jan 26 16:02:54 2010
@@ -25,6 +25,7 @@
 import org.apache.tapestry5.services.ComponentValueProvider;
 import org.apache.tapestry5.services.InjectionProvider;
 import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformMethod;
 
 /**
  * Identifies fields of type {...@link Block} that have the {...@link Inject} 
annotation and converts them
@@ -57,8 +58,10 @@
             }
         };
 
-        transformation.assignFieldIndirect(fieldName,
-                TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE, 
provider);
+        TransformMethod method = transformation
+                
.getMethod(TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE);
+
+        transformation.getField(fieldName).assignIndirect(method, provider);
 
         return true; // claim the field
     }

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=903293&r1=903292&r2=903293&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:54 2010
@@ -17,6 +17,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Inherited;
 import java.lang.reflect.Modifier;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Formatter;
 import java.util.List;
@@ -29,6 +30,7 @@
 
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.ioc.Predicate;
 import org.apache.tapestry5.ioc.internal.services.CtClassSource;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.Defense;
@@ -93,6 +95,11 @@
 
         }
 
+        public int compareTo(TransformMethod o)
+        {
+            return sig.compareTo(o.getSignature());
+        }
+
         public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
         {
             if (annotations == null)
@@ -101,11 +108,27 @@
             return findAnnotationInList(annotationClass, annotations);
         }
 
-        @Override
         public TransformMethodSignature getSignature()
         {
             return sig;
         }
+
+        public void extend(String body)
+        {
+            failIfFrozen();
+
+            try
+            {
+                method.insertAfter(body);
+            }
+            catch (CannotCompileException ex)
+            {
+                throw new MethodCompileException(
+                        ServicesMessages.methodCompileError(sig, body, ex), 
body, ex);
+            }
+
+            addMethodToDescription("extend", sig, body);
+        }
     }
 
     class TransformFieldImpl implements TransformField
@@ -142,6 +165,11 @@
             primitive = ClassFabUtils.isPrimitiveType(type);
         }
 
+        public int compareTo(TransformField o)
+        {
+            return name.compareTo(o.getName());
+        }
+
         public String getName()
         {
             return name;
@@ -228,6 +256,40 @@
 
             removeField(name);
         }
+
+        public <T> void assignIndirect(TransformMethod method, 
ComponentValueProvider<T> provider)
+        {
+            Defense.notNull(method, "method");
+            Defense.notNull(provider, "provider");
+
+            String providerFieldName = 
addInjectedField(ComponentValueProvider.class, name
+                    + "$provider", provider);
+
+            CtClass fieldType = null;
+
+            try
+            {
+                fieldType = field.getType();
+            }
+            catch (NotFoundException ex)
+            {
+                throw new RuntimeException(ex);
+            }
+
+            String body = String.format("%s = (%s) %s.get(%s);", name, 
fieldType.getName(),
+                    providerFieldName, resourcesFieldName);
+
+            extendMethod(method.getSignature(), body);
+
+            makeReadOnly(name);
+        }
+
+        @Override
+        public <T> void assignIndirect(TransformMethodSignature signature,
+                ComponentValueProvider<T> provider)
+        {
+            assignIndirect(getMethod(signature), provider);
+        }
     }
 
     private final Map<TransformMethodSignature, TransformMethodImpl> methods = 
CollectionFactory
@@ -485,17 +547,7 @@
     public <T extends Annotation> T 
getMethodAnnotation(TransformMethodSignature signature,
             Class<T> annotationClass)
     {
-        failIfFrozen();
-
-        CtMethod method = findDeclaredOrSuperclassMethod(signature);
-
-        if (method == null)
-            throw new IllegalArgumentException(ServicesMessages
-                    .noDeclaredMethod(ctClass, signature));
-
-        List<Annotation> annotations = findMethodAnnotations(method);
-
-        return findAnnotationInList(annotationClass, annotations);
+        return getMethod(signature).getAnnotation(annotationClass);
     }
 
     /**
@@ -527,20 +579,6 @@
         return findAnnotationInList(annotationClass, getClassAnnotations());
     }
 
-    private List<Annotation> findMethodAnnotations(CtMethod method)
-    {
-        List<Annotation> annotations = methodAnnotations.get(method);
-
-        if (annotations == null)
-        {
-            annotations = extractAnnotations(method);
-
-            methodAnnotations.put(method, annotations);
-        }
-
-        return annotations;
-    }
-
     private List<Annotation> extractAnnotations(CtMember member)
     {
         try
@@ -713,11 +751,13 @@
         }
     }
 
-    private void recordMethod(CtMethod method, boolean asNew)
+    private TransformMethodImpl recordMethod(CtMethod method, boolean asNew)
     {
         TransformMethodImpl tmi = new TransformMethodImpl(method, asNew);
 
         methods.put(tmi.getSignature(), tmi);
+
+        return tmi;
     }
 
     /**
@@ -891,40 +931,12 @@
 
     public void extendMethod(TransformMethodSignature methodSignature, String 
methodBody)
     {
-        failIfFrozen();
-
-        CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
-
-        try
-        {
-            method.insertAfter(methodBody);
-        }
-        catch (CannotCompileException ex)
-        {
-            throw new 
MethodCompileException(ServicesMessages.methodCompileError(methodSignature,
-                    methodBody, ex), methodBody, ex);
-        }
-
-        addMethodToDescription("extend", methodSignature, methodBody);
+        getMethod(methodSignature).extend(methodBody);
     }
 
     public void extendExistingMethod(TransformMethodSignature methodSignature, 
String methodBody)
     {
-        failIfFrozen();
-
-        CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
-
-        try
-        {
-            method.insertAfter(methodBody);
-        }
-        catch (CannotCompileException ex)
-        {
-            throw new 
MethodCompileException(ServicesMessages.methodCompileError(methodSignature,
-                    methodBody, ex), methodBody, ex);
-        }
-
-        addMethodToDescription("extend existing", methodSignature, methodBody);
+        extendMethod(methodSignature, methodBody);
     }
 
     public void copyMethod(TransformMethodSignature sourceMethod, int 
modifiers,
@@ -935,7 +947,10 @@
         CtClass returnType = findCtClass(sourceMethod.getReturnType());
         CtClass[] parameters = 
buildCtClassList(sourceMethod.getParameterTypes());
         CtClass[] exceptions = 
buildCtClassList(sourceMethod.getExceptionTypes());
-        CtMethod source = findDeclaredOrSuperclassMethod(sourceMethod);
+
+        TransformMethodImpl tmi = findOrOverrideMethod(sourceMethod);
+
+        CtMethod source = tmi.method;
 
         try
         {
@@ -971,12 +986,12 @@
     {
         failIfFrozen();
 
-        CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
+        TransformMethodImpl tmi = findOrOverrideMethod(methodSignature);
         CtClass exceptionCtType = findCtClass(exceptionType);
 
         try
         {
-            method.addCatch(body, exceptionCtType);
+            tmi.method.addCatch(body, exceptionCtType);
         }
         catch (CannotCompileException ex)
         {
@@ -991,11 +1006,11 @@
     {
         failIfFrozen();
 
-        CtMethod method = findDeclaredOrSuperclassMethod(methodSignature);
+        TransformMethodImpl tmi = findOrOverrideMethod(methodSignature);
 
         try
         {
-            method.insertBefore(methodBody);
+            tmi.method.insertBefore(methodBody);
         }
         catch (CannotCompileException ex)
         {
@@ -1037,33 +1052,35 @@
         formatter.format("\n%s\n\n", methodBody);
     }
 
-    private CtMethod findDeclaredOrSuperclassMethod(TransformMethodSignature 
methodSignature)
+    public TransformMethod getMethod(TransformMethodSignature signature)
     {
-        CtMethod method = findDeclaredMethod(methodSignature);
+        failIfFrozen();
 
-        if (method != null)
-            return method;
+        return findOrOverrideMethod(signature);
+    }
 
-        CtMethod result = addOverrideOfSuperclassMethod(methodSignature);
+    private TransformMethodImpl findOrOverrideMethod(TransformMethodSignature 
signature)
+    {
+        TransformMethodImpl result = methods.get(signature);
 
         if (result != null)
             return result;
 
-        throw new 
IllegalArgumentException(ServicesMessages.noDeclaredMethod(ctClass,
-                methodSignature));
-    }
+        result = addOverrideOfSuperclassMethod(signature);
 
-    private CtMethod findDeclaredMethod(TransformMethodSignature 
methodSignature)
-    {
-        TransformMethodImpl tmi = methods.get(methodSignature);
+        if (result != null)
+            return result;
+
+        throw new IllegalArgumentException(String.format("Class %s does not 
declare method '%s'.",
+                ctClass.getName(), signature));
 
-        return tmi == null ? null : tmi.method;
     }
 
     // TODO: Rework this method for efficiency, i.e., so that we can leverage 
the methods
     // map in parent InternalClassTransformImpls, rather than the exhaustive
     // search.
-    private CtMethod addOverrideOfSuperclassMethod(TransformMethodSignature 
methodSignature)
+    private TransformMethodImpl addOverrideOfSuperclassMethod(
+            TransformMethodSignature methodSignature)
     {
         try
         {
@@ -1073,15 +1090,14 @@
                 {
                     if (match(method, methodSignature))
                     {
-                        // TODO: If the method is not overridable (i.e. 
private, or final)?
+                        // TODO: What 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;
+                        // Record it as a new method.
+                        return recordMethod(newMethod, true);
                     }
                 }
             }
@@ -1150,7 +1166,7 @@
         return findFields(filter);
     }
 
-    public List<String> findFields(FieldFilter filter)
+    public List<String> findFields(final FieldFilter filter)
     {
         failIfFrozen();
 
@@ -1169,48 +1185,67 @@
         return result;
     }
 
-    public List<TransformMethodSignature> findMethodsWithAnnotation(
-            final Class<? extends Annotation> annotationClass)
+    public List<TransformField> matchFields(Predicate<TransformField> 
predicate)
     {
         failIfFrozen();
 
-        List<TransformMethodSignature> result = CollectionFactory.newList();
+        return InternalUtils.matchAndSort(fields.values(), predicate);
+    }
 
-        for (CtMethod method : ctClass.getDeclaredMethods())
+    @Override
+    public List<TransformField> matchFieldsWithAnnotation(
+            final Class<? extends Annotation> annotationClass)
+    {
+        return matchFields(new Predicate<TransformField>()
         {
-            List<Annotation> annotations = findMethodAnnotations(method);
-
-            if (findAnnotationInList(annotationClass, annotations) != null)
+            @Override
+            public boolean accept(TransformField field)
             {
-                TransformMethodSignature sig = getMethodSignature(method);
-                result.add(sig);
+                return field.getAnnotation(annotationClass) != null;
             }
-        }
+        });
+    }
 
-        Collections.sort(result);
+    public List<TransformMethodSignature> findMethodsWithAnnotation(
+            final Class<? extends Annotation> annotationClass)
+    {
+        List<TransformMethod> methods = matchMethods(new 
Predicate<TransformMethod>()
+        {
+            public boolean accept(TransformMethod method)
+            {
+                return method.getAnnotation(annotationClass) != null;
+            };
+        });
 
-        return result;
+        return toMethodSignatures(methods);
     }
 
-    public List<TransformMethodSignature> findMethods(MethodFilter filter)
+    public List<TransformMethodSignature> findMethods(final MethodFilter 
filter)
     {
         Defense.notNull(filter, "filter");
 
-        List<TransformMethodSignature> result = CollectionFactory.newList();
-
-        for (TransformMethodSignature sig : methods.keySet())
+        List<TransformMethod> methods = matchMethods(new 
Predicate<TransformMethod>()
         {
-            if (filter.accept(sig))
-                result.add(sig);
-        }
+            public boolean accept(TransformMethod object)
+            {
+                return filter.accept(object.getSignature());
+            };
+        });
 
-        Collections.sort(result);
+        return toMethodSignatures(methods);
+    }
 
-        return result;
+    public List<TransformMethod> matchMethods(final Predicate<TransformMethod> 
predicate)
+    {
+        failIfFrozen();
+
+        return InternalUtils.matchAndSort(methods.values(), predicate);
     }
 
     private TransformMethodSignature getMethodSignature(CtMethod method)
     {
+        failIfFrozen();
+
         TransformMethodSignature result = methodSignatures.get(method);
         if (result == null)
         {
@@ -1393,7 +1428,7 @@
     {
         Defense.notNull(type, "type");
         Defense.notNull(provider, "provider");
-        
+
         TransformField field = addTransformField(Modifier.PRIVATE | 
Modifier.FINAL, type.getName(),
                 suggestedName);
 
@@ -1503,7 +1538,7 @@
     {
         Defense.notNull(signature, "signature");
 
-        return findDeclaredMethod(signature) != null;
+        return methods.containsKey(signature);
     }
 
     /**
@@ -2072,7 +2107,8 @@
     {
         Defense.notNull(signature, "signature");
 
-        CtMethod method = findDeclaredOrSuperclassMethod(signature);
+        TransformMethodImpl tmi = findOrOverrideMethod(signature);
+        CtMethod method = tmi.method;
 
         int lineNumber = method.getMethodInfo2().getLineNumber(0);
         CtClass enclosingClass = method.getDeclaringClass();
@@ -2103,23 +2139,27 @@
         return "$" + constructorArgs.size();
     }
 
-    public <T> void assignFieldIndirect(String fieldName, 
TransformMethodSignature methodSig,
-            ComponentValueProvider<T> provider)
+    private static List<TransformMethodSignature> 
toMethodSignatures(List<TransformMethod> input)
     {
-        Defense.notBlank(fieldName, "fieldName");
-        Defense.notNull(methodSig, "methodSig");
-        Defense.notNull(provider, "provider");
+        List<TransformMethodSignature> result = CollectionFactory.newList();
 
-        String providerFieldName = 
addInjectedField(ComponentValueProvider.class, fieldName
-                + "$provider", provider);
+        for (TransformMethod m : input)
+        {
+            result.add(m.getSignature());
+        }
 
-        CtClass fieldType = getFieldCtType(fieldName);
+        return result;
+    }
 
-        String body = String.format("%s = (%s) %s.get(%s);", fieldName, 
fieldType.getName(),
-                providerFieldName, resourcesFieldName);
+    private static List<String> toFieldNames(List<TransformField> fields)
+    {
+        List<String> result = CollectionFactory.newList();
 
-        extendMethod(methodSig, body);
+        for (TransformField f : fields)
+        {
+            result.add(f.getName());
+        }
 
-        makeReadOnly(fieldName);
+        return result;
     }
 }

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=903293&r1=903292&r2=903293&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:54 2010
@@ -52,11 +52,6 @@
         return MESSAGES.format("error-adding-method", ctClass.getName(), 
methodName, cause);
     }
 
-    static String noDeclaredMethod(CtClass ctClass, TransformMethodSignature 
methodSignature)
-    {
-        return MESSAGES.format("no-declared-method", ctClass.getName(), 
methodSignature);
-    }
-
     static String classNotTransformed(String className)
     {
         return MESSAGES.format("class-not-transformed", className);

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java
 Tue Jan 26 16:02:54 2010
@@ -35,12 +35,13 @@
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
 import org.apache.tapestry5.services.ComponentValueProvider;
 import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformField;
 
 /**
  * Finds fields with the {...@link org.apache.tapestry5.annotations.Component} 
annotation and updates
  * the model. Also
- * checks for the {...@link Mixins} and {...@link MixinClasses} annotations 
and uses them to update the
- * {...@link ComponentModel}.
+ * checks for the {...@link Mixins} and {...@link MixinClasses} annotations 
and uses them to update the {...@link ComponentModel}
+ * .
  */
 public class ComponentWorker implements ComponentClassTransformWorker
 {
@@ -53,18 +54,20 @@
 
     public void transform(ClassTransformation transformation, 
MutableComponentModel model)
     {
-        for (String fieldName : 
transformation.findFieldsWithAnnotation(Component.class))
+        for (TransformField field : 
transformation.matchFieldsWithAnnotation(Component.class))
         {
-            Component annotation = 
transformation.getFieldAnnotation(fieldName, Component.class);
+            Component annotation = field.getAnnotation(Component.class);
 
-            transformation.claimField(fieldName, annotation);
+            field.claim(annotation);
 
             String annotationId = annotation.id();
 
+            String fieldName = field.getName();
+
             final String id = InternalUtils.isNonBlank(annotationId) ? 
annotationId : InternalUtils
                     .stripMemberName(fieldName);
 
-            String type = transformation.getFieldType(fieldName);
+            String type = field.getType();
 
             Location location = new StringLocation(String.format("%s.%s", 
transformation
                     .getClassName(), fieldName), 0);
@@ -82,25 +85,23 @@
             }
 
             ComponentValueProvider<Object> provider = new 
ComponentValueProvider<Object>()
-            {                
+            {
                 public Object get(ComponentResources resources)
                 {
                     return resources.getEmbeddedComponent(id);
                 }
             };
 
-            transformation.assignFieldIndirect(fieldName,
-                    TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, 
provider);
+            
field.assignIndirect(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, 
provider);
 
-            addMixinClasses(fieldName, transformation, embedded);
-            addMixinTypes(fieldName, transformation, embedded);
+            addMixinClasses(field, embedded);
+            addMixinTypes(field, embedded);
         }
     }
 
-    private void addMixinClasses(String fieldName, ClassTransformation 
transformation,
-            MutableEmbeddedComponentModel model)
+    private void addMixinClasses(TransformField field, 
MutableEmbeddedComponentModel model)
     {
-        MixinClasses annotation = transformation.getFieldAnnotation(fieldName, 
MixinClasses.class);
+        MixinClasses annotation = field.getAnnotation(MixinClasses.class);
 
         if (annotation == null)
             return;
@@ -109,7 +110,7 @@
 
         if (!orderEmpty && annotation.order().length != 
annotation.value().length)
             throw new 
TapestryException(TransformMessages.badMixinConstraintLength(annotation,
-                    fieldName), model, null);
+                    field.getName()), model, null);
 
         for (int i = 0; i < annotation.value().length; i++)
         {
@@ -120,10 +121,9 @@
         }
     }
 
-    private void addMixinTypes(String fieldName, ClassTransformation 
transformation,
-            MutableEmbeddedComponentModel model)
+    private void addMixinTypes(TransformField field, 
MutableEmbeddedComponentModel model)
     {
-        Mixins annotation = transformation.getFieldAnnotation(fieldName, 
Mixins.class);
+        Mixins annotation = field.getAnnotation(Mixins.class);
 
         if (annotation == null)
             return;

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectContainerWorker.java
 Tue Jan 26 16:02:54 2010
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry5.internal.transform;
 
-import java.util.List;
-
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.annotations.InjectContainer;
 import org.apache.tapestry5.internal.services.ComponentClassCache;
@@ -25,6 +23,7 @@
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
 import org.apache.tapestry5.services.ComponentValueProvider;
 import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformField;
 
 /**
  * Identifies the {...@link org.apache.tapestry5.annotations.InjectContainer} 
annotation and adds code
@@ -42,11 +41,12 @@
 
     public void transform(ClassTransformation transformation, 
MutableComponentModel model)
     {
-        List<String> names = 
transformation.findFieldsWithAnnotation(InjectContainer.class);
-
-        for (final String fieldName : names)
+        for (final TransformField field : transformation
+                .matchFieldsWithAnnotation(InjectContainer.class))
         {
-            final String fieldTypeName = 
transformation.getFieldType(fieldName);
+            final String fieldName = field.getName();
+
+            final String fieldTypeName = field.getType();
 
             final String componentClassName = model.getComponentClassName();
 
@@ -72,8 +72,7 @@
                 }
             };
 
-            transformation.assignFieldIndirect(fieldName,
-                    TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, 
provider);
+            
field.assignIndirect(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, 
provider);
         }
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/MixinWorker.java
 Tue Jan 26 16:02:54 2010
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry5.internal.transform;
 
-import java.util.List;
-
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.annotations.Mixin;
 import org.apache.tapestry5.internal.InternalComponentResources;
@@ -26,6 +24,7 @@
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
 import org.apache.tapestry5.services.ComponentValueProvider;
 import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformField;
 
 /**
  * Supports the {...@link org.apache.tapestry5.annotations.Mixin} annotation, 
which allows a mixin to
@@ -45,19 +44,17 @@
 
     public void transform(ClassTransformation transformation, 
MutableComponentModel model)
     {
-        List<String> fields = 
transformation.findFieldsWithAnnotation(Mixin.class);
-
-        for (String fieldName : fields)
+        for (TransformField field : 
transformation.matchFieldsWithAnnotation(Mixin.class))
         {
-            Mixin annotation = transformation.getFieldAnnotation(fieldName, 
Mixin.class);
+            Mixin annotation = field.getAnnotation(Mixin.class);
 
-            transformation.claimField(fieldName, annotation);
+            field.claim(annotation);
 
             String mixinType = annotation.value();
 
             String[] order = annotation.order();
 
-            String fieldType = transformation.getFieldType(fieldName);
+            String fieldType = field.getType();
 
             final String mixinClassName = InternalUtils.isBlank(mixinType) ? 
fieldType : resolver
                     .resolveMixinTypeToClassName(mixinType);
@@ -74,8 +71,7 @@
                 }
             };
 
-            transformation.assignFieldIndirect(fieldName,
-                    TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, 
provider);
+            
field.assignIndirect(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, 
provider);
         }
     }
 }

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=903293&r1=903292&r2=903293&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:54 2010
@@ -14,14 +14,17 @@
 
 package org.apache.tapestry5.services;
 
+import java.lang.annotation.Annotation;
+import java.util.List;
+
 import javassist.CtBehavior;
 
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.Predicate;
 import org.slf4j.Logger;
 
-import java.lang.annotation.Annotation;
-import java.util.List;
+import com.sun.source.tree.MethodTree;
 
 /**
  * Contains class-specific information used when transforming a raw component 
class into an
@@ -87,10 +90,20 @@
      * 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.
+     * 
+     * @deprecated Use {...@link #matchFieldsWithAnnotation(Class)} instead
      */
     List<String> findFieldsWithAnnotation(Class<? extends Annotation> 
annotationClass);
 
     /**
+     * Returns a sorted list of declared instance fields with the indicated 
annotation. Non-private
+     * and static fields are ignored. Claimed fields are also ignored.
+     * 
+     * @since 5.2.0
+     */
+    List<TransformField> matchFieldsWithAnnotation(Class<? extends Annotation> 
annotationClass);
+
+    /**
      * Finds all methods defined in the class that are marked with the 
provided annotation.
      * 
      * @param annotationClass
@@ -108,20 +121,42 @@
      * @return 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.
+     * @deprecated Use {...@link #matchMethods(Predicate)} instead
      */
     List<TransformMethodSignature> findMethods(MethodFilter filter);
 
     /**
+     * Finds all methods matched by the provided predicate.
+     * 
+     * @param predicate
+     *            Used to filter the list
+     * @return a list of matching methods (which may be empty) in ascending 
order (by
+     *         method name), but descending order (by parameter count) within 
overrides of a single method name.
+     */
+    List<TransformMethod> matchMethods(Predicate<TransformMethod> predicate);
+
+    /**
      * Finds all unclaimed fields matched by the provided filter. Only 
considers private instance
      * fields.
      * 
      * @param filter
      *            passed each field name and field type
      * @return the names of all matched fields, in ascending order
+     * @deprecated Use {...@link #matchFields(Predicate)} instead
      */
     List<String> findFields(FieldFilter filter);
 
     /**
+     * Finds all unclaimed fields matched by the provided predicate. Only 
considers instance fields.
+     * 
+     * @param predicate
+     *            used for matching
+     * @return sorted list of matching fields
+     * @since 5.2.0
+     */
+    List<TransformField> matchFields(Predicate<TransformField> predicate);
+
+    /**
      * Finds an annotation on a declared instance field.
      * 
      * @param <T>
@@ -342,14 +377,15 @@
      *            the body of code
      * @throws org.apache.tapestry5.internal.services.MethodCompileException
      *             if the provided Javassist method body can not be compiled
-     * @see #extendExistingMethod(TransformMethodSignature, String)
+     * @deprecated Use {...@link TransformMethod#extend(String)} instead
      */
     void extendMethod(TransformMethodSignature methodSignature, String 
methodBody);
 
     /**
      * Like {...@link #extendMethod(TransformMethodSignature, String)}, but 
the extension does not mark
      * the method as new,
-     * and field changes <em>will</em> be processed.
+     * and field changes <em>will</em> be processed. Note: at some point, this 
is not longer true; extend and
+     * extendMethod work identically.
      * 
      * @param methodSignature
      *            signature of the method to extend
@@ -358,6 +394,7 @@
      * @throws org.apache.tapestry5.internal.services.MethodCompileException
      *             if the provided method body can not be compiled
      * @see #prefixMethod(TransformMethodSignature, String)
+     * @deprecated Use {...@link TransformMethod#extend(String) instead}
      */
     void extendExistingMethod(TransformMethodSignature methodSignature, String 
methodBody);
 
@@ -510,21 +547,16 @@
     boolean isMethodOverride(TransformMethodSignature methodSignature);
 
     /**
-     * Uses {...@link #extendMethod(TransformMethodSignature, String)} to make 
an assignment to
-     * a field within the provided method. In addition, the field is marked as 
read-only. This
-     * is an alternative to {...@link #injectFieldIndirect(String, 
ComponentValueProvider)} for values
-     * that <em>can not</em> be calculated at the constructor.
+     * Locates and returns the method if declared in this class; if not, 
locates
+     * a super-class method that is implemented into this class. In the latter
+     * case, the method will be considered "new" (i.e., no field 
transformations),
+     * as with {...@link #extendMethod(TransformMethodSignature, String)}).
      * 
-     * @param <T>
-     * @param fieldName
-     *            name of field to assign
-     * @param methodSig
-     *            identifies the method where the assignment will occur, often 
this is
-     *            {...@link 
TransformConstants#CONTAINING_PAGE_DID_LOAD_SIGNATURE}
-     * @param provider
-     *            provides the value of the field
+     * @param signature
+     *            identifies the method to obtain
+     * @throw RuntimeException if the signature does not match a declared 
method of this
+     *        class, or a overridable method of a superclass
      * @since 5.2.0
      */
-    <T> void assignFieldIndirect(String fieldName, TransformMethodSignature 
methodSig,
-            ComponentValueProvider<T> provider);
- }
+    TransformMethod getMethod(TransformMethodSignature signature);
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldFilter.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldFilter.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldFilter.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldFilter.java
 Tue Jan 26 16:02:54 2010
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 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.
@@ -14,8 +14,12 @@
 
 package org.apache.tapestry5.services;
 
+import org.apache.tapestry5.ioc.Predicate;
+
 /**
  * Used by {...@link ClassTransformation#findFields(FieldFilter)} to identify 
which fields to keep.
+ * 
+ * @deprecated New APIs use {...@link Predicate} instead
  */
 public interface FieldFilter
 {

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodFilter.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodFilter.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodFilter.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/MethodFilter.java
 Tue Jan 26 16:02:54 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 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
+// 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,
@@ -14,8 +14,12 @@
 
 package org.apache.tapestry5.services;
 
+import org.apache.tapestry5.ioc.Predicate;
+
 /**
  * Used by {...@link ClassTransformation#findMethods(MethodFilter)} to accept 
or reject each method.
+ * 
+ * @deprecated New APIs use {...@link Predicate} instead
  */
 public interface MethodFilter
 {

Modified: 
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=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
 Tue Jan 26 16:02:54 2010
@@ -23,7 +23,7 @@
  * 
  * @since 5.2.0
  */
-public interface TransformField extends AnnotationProvider
+public interface TransformField extends AnnotationProvider, 
Comparable<TransformField>
 {
     /**
      * Returns the name of the field.
@@ -72,4 +72,25 @@
      *            identifies the field containing (via injection) an instance 
of {...@link FieldValueConduit}
      */
     void replaceAccess(TransformField conduitField);
+
+    /**
+     * Extends the indicated method to add an assignment of the field with
+     * the value obtained by the provider. This is used when a value
+     * to be provided can not be provided from within the transformed class'
+     * constructor.
+     * 
+     * @param <T>
+     * @param method
+     *            identifies the method where the assignment will occur, often 
this is
+     *            {...@link 
TransformConstants#CONTAINING_PAGE_DID_LOAD_SIGNATURE}
+     * @param provider
+     *            provides the value of the field
+     */
+    <T> void assignIndirect(TransformMethod method, ComponentValueProvider<T> 
provider);
+
+    /**
+     * Alternate version of {...@link #assignIndirect(TransformMethod, 
ComponentValueProvider)} that operates using a
+     * method signature.
+     */
+    <T> void assignIndirect(TransformMethodSignature signature, 
ComponentValueProvider<T> provider);
 }

Modified: 
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=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
 Tue Jan 26 16:02:54 2010
@@ -19,14 +19,34 @@
 /**
  * A method defined by (or created within) a {...@link ClassTransformation}, 
allowing
  * for access and manipulation of the method.
+ * <p>
+ * The natural sorting order of TransformMethods is the same as {...@link 
TransformMethodSignature}.
  * 
  * @since 5.2.0
  */
-public interface TransformMethod extends AnnotationProvider
+public interface TransformMethod extends AnnotationProvider, 
Comparable<TransformMethod>
 {
     /**
      * @return the signature for the method, defining name, visibility, return 
type, parameter types and thrown
      *         exceptions
      */
     TransformMethodSignature getSignature();
+
+    /**
+     * Extends an existing method. The provided method body is inserted at the 
end of the existing
+     * 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.
+     * <p/>
+     * The extended method is considered <em>new</em>. New methods <em>are 
not</em> scanned for removed fields, field
+     * access changes, etc.
+     * 
+     * @param body
+     *            the body of Javassist psuedo-code
+     * @throws RuntimeException
+     *             if the provided Javassist method body can not be compiled
+     */
+    void extend(String body);
 }

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=903293&r1=903292&r2=903293&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:54 2010
@@ -17,7 +17,6 @@
   The current element is established with the first call to element() and is \
   maintained across subsequent calls. 
 error-adding-method=Error adding method %s to class %s: %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.
 content-inside-body-not-allowed=Content inside a Tapestry body element is not 
allowed (at %s). The content has been ignored.

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/TextOnlyOnDisabledTextField.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/TextOnlyOnDisabledTextField.java?rev=903293&r1=903292&r2=903293&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/TextOnlyOnDisabledTextField.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/TextOnlyOnDisabledTextField.java
 Tue Jan 26 16:02:54 2010
@@ -1,10 +1,10 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 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.
 // You may obtain a copy of the License at
 //
-//      http://www.apache.org/licenses/LICENSE-2.0
+// 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,
@@ -14,17 +14,13 @@
 
 package org.apache.tapestry5.integration.app1.components;
 
-import org.apache.tapestry5.corelib.components.TextField;
 import org.apache.tapestry5.annotations.Mixin;
-import org.apache.tapestry5.integration.app1.mixins.TextOnlyOnDisabled;
+import org.apache.tapestry5.corelib.components.TextField;
 
-/**
- *
- */
 public class TextOnlyOnDisabledTextField extends TextField
 {
+    @SuppressWarnings("unused")
+    @Mixin(value = "textonlyondisabled", order = "after:*")
+    private Object theMixin;
 
-    @Mixin(order = "after:*")
-    private TextOnlyOnDisabled theMixin;
-    
 }


Reply via email to