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:03:17 UTC

svn commit: r903296 - in /tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5: internal/services/InternalClassTransformationImpl.java services/ClassTransformation.java services/ComponentMethodAdvice.java services/TransformMethod.java

Author: hlship
Date: Tue Jan 26 16:03:17 2010
New Revision: 903296

URL: http://svn.apache.org/viewvc?rev=903296&view=rev
Log:
Move method advice from ClassTransformation to TransformMethod

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/services/ClassTransformation.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java

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=903296&r1=903295&r2=903296&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:03:17 2010
@@ -17,8 +17,6 @@
 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;
 import java.util.Map;
@@ -87,6 +85,8 @@
 
         private final boolean added;
 
+        private ComponentMethodInvocationBuilder builder;
+
         TransformMethodImpl(CtMethod method, boolean added)
         {
             this.method = method;
@@ -113,6 +113,18 @@
             return sig;
         }
 
+        public void advise(ComponentMethodAdvice advice)
+        {
+            failIfFrozen();
+
+            Defense.notNull(advice, "advice");
+
+            if (builder == null)
+                builder = createBuilder(sig);
+
+            builder.addAdvice(advice);
+        }
+
         public void extend(String body)
         {
             failIfFrozen();
@@ -129,6 +141,15 @@
 
             addMethodToDescription("extend", sig, body);
         }
+
+        void doFinish()
+        {
+            if (builder != null)
+            {
+                builder.commit();
+                builder = null;
+            }
+        }
     }
 
     class TransformFieldImpl implements TransformField
@@ -365,15 +386,6 @@
 
     private List<Annotation> classAnnotations;
 
-    // Cache of method annotation
-
-    private Map<CtMethod, List<Annotation>> methodAnnotations = CollectionFactory.newMap();
-
-    private Map<CtMethod, TransformMethodSignature> methodSignatures = CollectionFactory.newMap();
-
-    private Map<TransformMethodSignature, ComponentMethodInvocationBuilder> methodToInvocationBuilder = CollectionFactory
-            .newMap();
-
     // Key is field name, value is expression used to replace read access
 
     private Map<String, String> fieldReadTransforms;
@@ -516,13 +528,10 @@
         fields = null;
 
         classAnnotations = null;
-        methodAnnotations = null;
-        methodSignatures = null;
         fieldReadTransforms = null;
         fieldWriteTransforms = null;
         constructor = null;
         formatter = null;
-        methodToInvocationBuilder = null;
     }
 
     public String getResourcesFieldName()
@@ -779,11 +788,9 @@
 
             ctClass.addMethod(newMethod);
 
-            recordMethod(newMethod, true);
-
-            TransformMethodSignature sig = getMethodSignature(newMethod);
+            TransformMethod tm = recordMethod(newMethod, true);
 
-            addMethodToDescription("add default", sig, "<default>");
+            addMethodToDescription("add default", tm.getSignature(), "<default>");
         }
         catch (CannotCompileException ex)
         {
@@ -1196,33 +1203,24 @@
 
     public List<String> findFieldsWithAnnotation(final Class<? extends Annotation> annotationClass)
     {
-        Defense.notNull(annotationClass, "annotationClass");
-
-        FieldFilter filter = new FieldFilter()
-        {
-            public boolean accept(String fieldName, String fieldType)
-            {
-                return getFieldAnnotation(fieldName, annotationClass) != null;
-            }
-        };
-
-        return findFields(filter);
+        return toFieldNames(matchFieldsWithAnnotation(annotationClass));
     }
 
     public List<String> findFields(final FieldFilter filter)
     {
         Defense.notNull(filter, "filter");
 
-        List<TransformField> fields2 = matchFields(new Predicate<TransformField>()
+        failIfFrozen();
+
+        List<TransformField> fields = matchFields(new Predicate<TransformField>()
         {
-            @Override
             public boolean accept(TransformField object)
             {
                 return filter.accept(object.getName(), object.getType());
             }
         });
 
-        return toFieldNames(fields2);
+        return toFieldNames(fields);
     }
 
     public List<TransformField> matchFields(Predicate<TransformField> predicate)
@@ -1232,13 +1230,11 @@
         return InternalUtils.matchAndSort(fields.values(), predicate);
     }
 
-    @Override
     public List<TransformField> matchFieldsWithAnnotation(
             final Class<? extends Annotation> annotationClass)
     {
         return matchFields(new Predicate<TransformField>()
         {
-            @Override
             public boolean accept(TransformField field)
             {
                 return field.getAnnotation(annotationClass) != null;
@@ -1282,21 +1278,6 @@
         return InternalUtils.matchAndSort(methods.values(), predicate);
     }
 
-    private TransformMethodSignature getMethodSignature(CtMethod method)
-    {
-        failIfFrozen();
-
-        TransformMethodSignature result = methodSignatures.get(method);
-        if (result == null)
-        {
-            result = toMethodSignature(method);
-
-            methodSignatures.put(method, result);
-        }
-
-        return result;
-    }
-
     private TransformMethodSignature toMethodSignature(CtMethod method)
     {
         try
@@ -1326,28 +1307,20 @@
 
     public List<String> findUnclaimedFields()
     {
-        failIfFrozen();
-
-        List<String> names = CollectionFactory.newList();
-
-        for (TransformFieldImpl f : fields.values())
-        {
-            if (f.added || f.removed || f.isClaimed())
-                continue;
-
-            names.add(f.getName());
-        }
-
-        Collections.sort(names);
-
-        return names;
+        return toFieldNames(matchUnclaimedFields());
     }
 
-    private boolean isInstanceField(CtField field)
+    public List<TransformField> matchUnclaimedFields()
     {
-        int modifiers = field.getModifiers();
+        return matchFields(new Predicate<TransformField>()
+        {
+            public boolean accept(TransformField object)
+            {
+                TransformFieldImpl tmi = (TransformFieldImpl) object;
 
-        return Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers);
+                return !(tmi.added || tmi.removed || tmi.isClaimed());
+            }
+        });
     }
 
     public String getFieldType(String fieldName)
@@ -1370,20 +1343,6 @@
         return getField(fieldName).getModifiers();
     }
 
-    private CtClass getFieldCtType(String fieldName)
-    {
-        try
-        {
-            CtField field = ctClass.getDeclaredField(fieldName);
-
-            return field.getType();
-        }
-        catch (NotFoundException ex)
-        {
-            throw new RuntimeException(ex);
-        }
-    }
-
     public String addField(int modifiers, String type, String suggestedName)
     {
         return addTransformField(modifiers, type, suggestedName).getName();
@@ -1425,6 +1384,7 @@
         return result;
     }
 
+    // Returns String for backwards compatibility reasons
     public String addInjectedField(Class type, String suggestedName, Object value)
     {
         Defense.notNull(type, "type");
@@ -1517,19 +1477,7 @@
 
     public void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice)
     {
-        Defense.notNull(methodSignature, "methodSignature");
-        Defense.notNull(advice, "advice");
-
-        ComponentMethodInvocationBuilder builder = methodToInvocationBuilder.get(methodSignature);
-
-        if (builder == null)
-        {
-            builder = new ComponentMethodInvocationBuilder(this, componentClassCache,
-                    methodSignature, classSource);
-            methodToInvocationBuilder.put(methodSignature, builder);
-        }
-
-        builder.addAdvice(advice);
+        getMethod(methodSignature).advise(advice);
     }
 
     public boolean isMethodOverride(TransformMethodSignature methodSignature)
@@ -1598,9 +1546,14 @@
     {
         failIfFrozen();
 
-        for (ComponentMethodInvocationBuilder builder : methodToInvocationBuilder.values())
+        // doFinish() will sometimes create new methods on the ClassTransformation, yielding
+        // a concurrent modification exception, so do a defensive copy.
+
+        List<TransformMethodImpl> tmis = CollectionFactory.newList(methods.values());
+
+        for (TransformMethodImpl tmi : tmis)
         {
-            builder.commit();
+            tmi.doFinish();
         }
 
         String initializer = convertConstructorToMethod();
@@ -2144,4 +2097,10 @@
 
         return result;
     }
+
+    private ComponentMethodInvocationBuilder createBuilder(TransformMethodSignature signature)
+    {
+        return new ComponentMethodInvocationBuilder(this, componentClassCache, signature,
+                classSource);
+    }
 }

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=903296&r1=903295&r2=903296&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:03:17 2010
@@ -76,7 +76,7 @@
     /**
      * As with {@link #newMemberName(String)}, but the suggested name is constructed from the prefix
      * and base name. An
-     * underscore will seperate the prefix from the base name.
+     * underscore will separate the prefix from the base name.
      * 
      * @param prefix
      *            for the generated name
@@ -97,7 +97,7 @@
 
     /**
      * Returns a sorted list of declared instance fields with the indicated annotation. Non-private
-     * and static fields are ignored. Claimed fields are also ignored.
+     * and static fields are ignored.
      * 
      * @since 5.2.0
      */
@@ -148,6 +148,7 @@
 
     /**
      * Finds all unclaimed fields matched by the provided predicate. Only considers instance fields.
+     * Added, removed and claimed fields are excluded.
      * 
      * @param predicate
      *            used for matching
@@ -234,10 +235,19 @@
     /**
      * Finds any declared <em>instance</em> fields that have not been claimed (via {@link #claimField(String, Object)})
      * and have not been either added or deleted, and returns the names of those fields. May return an empty array.
+     * 
+     * @deprecated Use {@link #matchUnclaimedFields()} instead
      */
     List<String> findUnclaimedFields();
 
     /**
+     * Matches all fields that are not claimed (or added or removed).
+     * 
+     * @since 5.2.0
+     */
+    List<TransformField> matchUnclaimedFields();
+
+    /**
      * Obtains the type of a declared instance field.
      * 
      * @param fieldName
@@ -523,6 +533,8 @@
 
     /**
      * Adds method advice for the indicated method.
+     * 
+     * @deprecated Use {@link TransformMethod#advise(ComponentMethodAdvice)} instead
      */
     void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java?rev=903296&r1=903295&r2=903296&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMethodAdvice.java Tue Jan 26 16:03:17 2010
@@ -1,10 +1,10 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 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,
@@ -16,10 +16,10 @@
 
 /**
  * An object that receives control around an "advised" method of a component. The advise can query or even replace
- * method parameters.  After invoking {@link org.apache.tapestry5.services.ComponentMethodInvocation#proceed()}, the
- * advise may query and override thrown exceptions or the return value of the invocation.
- *
- * @see ClassTransformation#advise(TransformMethodSignature, ComponentMethodAdvice)
+ * method parameters. After invoking {@link org.apache.tapestry5.services.ComponentMethodInvocation#proceed()}, the
+ * advice may query and override thrown exceptions or the return value of the invocation.
+ * 
+ * @see TransformMethod#advise(ComponentMethodAdvice)
  */
 public interface ComponentMethodAdvice
 {

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=903296&r1=903295&r2=903296&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:03:17 2010
@@ -42,6 +42,9 @@
      * <p/>
      * The extended method is considered <em>new</em>. New methods <em>are not</em> scanned for removed fields, field
      * access changes, etc.
+     * <p>
+     * This method will eventually be removed, using {@link #advise(ComponentMethodAdvice)} or some other alternative is
+     * preferred.
      * 
      * @param body
      *            the body of Javassist psuedo-code
@@ -49,4 +52,15 @@
      *             if the provided Javassist method body can not be compiled
      */
     void extend(String body);
+
+    /**
+     * Add advice for the method; the advice will be threaded into method invocations of the indicated method.
+     * A method may be given multiple advice; each advice will recieve control in turn (assuming
+     * the previous advice invokes {@link ComponentMethodInvocation#proceed()}) in the order the advice
+     * is added. The last advice will proceed to the original method implementation.
+     * 
+     * @param advice
+     *            to receive control when the method is invoked
+     */
+    void advise(ComponentMethodAdvice advice);
 }