Author: hlship
Date: Thu Jun  2 20:03:36 2011
New Revision: 1130771

URL: http://svn.apache.org/viewvc?rev=1130771&view=rev
Log:
TAP5-1528: Rewrite OnEventWorker to implement ComponentClassTransformWorker2

Modified:
    
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java

Modified: 
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java?rev=1130771&r1=1130770&r2=1130771&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
 (original)
+++ 
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
 Thu Jun  2 20:03:36 2011
@@ -221,5 +221,25 @@ public class MethodDescription implement
         return builder.toString();
     }
 
-    // TODO: convienience methods: isStatic(), isPrivate()
+    /**
+     * A string used to identify the method, containing just the method name 
and argument types
+     * (but ignoring visibility, return type and thrown exceptions).
+     * 
+     * @return method identifier
+     */
+    public String toShortString()
+    {
+        StringBuilder builder = new StringBuilder(methodName).append("(");
+
+        String sep = "";
+
+        for (String name : argumentTypes)
+        {
+            builder.append(sep).append(name);
+
+            sep = ", ";
+        }
+
+        return builder.append(")").toString();
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java?rev=1130771&r1=1130770&r2=1130771&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java
 Thu Jun  2 20:03:36 2011
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2011 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.
@@ -15,10 +15,10 @@
 package org.apache.tapestry5.internal.transform;
 
 import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.plastic.MethodHandle;
+import org.apache.tapestry5.plastic.MethodInvocationResult;
+import org.apache.tapestry5.plastic.PlasticMethod;
 import org.apache.tapestry5.runtime.ComponentEvent;
-import org.apache.tapestry5.services.MethodAccess;
-import org.apache.tapestry5.services.MethodInvocationResult;
-import org.apache.tapestry5.services.TransformMethod;
 
 /**
  * Base class for invoking event handler methods that also serves when 
invoking an
@@ -28,7 +28,7 @@ import org.apache.tapestry5.services.Tra
  */
 public class BaseEventHandlerMethodInvoker implements EventHandlerMethodInvoker
 {
-    private final MethodAccess access;
+    private final MethodHandle handle;
 
     private final String identifier;
 
@@ -36,20 +36,21 @@ public class BaseEventHandlerMethodInvok
 
     private final String componentId;
 
-    public BaseEventHandlerMethodInvoker(TransformMethod method, String 
eventType, String componentId)
+    public BaseEventHandlerMethodInvoker(PlasticMethod method, String 
eventType, String componentId)
     {
         this.eventType = eventType;
         this.componentId = componentId;
 
-        access = method.getAccess();
-        identifier = method.getMethodIdentifier();
+        handle = method.getHandle();
+        identifier = String.format("%s.%s", 
method.getPlasticClass().getClassName(), method.getDescription()
+                .toShortString());
     }
 
     public void invokeEventHandlerMethod(ComponentEvent event, Object instance)
     {
         event.setMethodDescription(identifier);
 
-        MethodInvocationResult result = access.invoke(instance, 
constructParameters(event));
+        MethodInvocationResult result = handle.invoke(instance, 
constructParameters(event));
 
         result.rethrow();
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java?rev=1130771&r1=1130770&r2=1130771&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
 Thu Jun  2 20:03:36 2011
@@ -1,5 +1,5 @@
 //
-// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 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
@@ -22,28 +22,33 @@ import org.apache.tapestry5.EventContext
 import org.apache.tapestry5.ValueEncoder;
 import org.apache.tapestry5.annotations.OnEvent;
 import org.apache.tapestry5.annotations.RequestParameter;
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Flow;
+import org.apache.tapestry5.func.Mapper;
 import org.apache.tapestry5.func.Predicate;
+import org.apache.tapestry5.func.Worker;
 import org.apache.tapestry5.internal.services.ComponentClassCache;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.plastic.MethodAdvice;
+import org.apache.tapestry5.plastic.MethodDescription;
+import org.apache.tapestry5.plastic.MethodInvocation;
+import org.apache.tapestry5.plastic.PlasticClass;
+import org.apache.tapestry5.plastic.PlasticMethod;
 import org.apache.tapestry5.runtime.ComponentEvent;
-import org.apache.tapestry5.services.ClassTransformation;
-import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import org.apache.tapestry5.services.ComponentMethodAdvice;
-import org.apache.tapestry5.services.ComponentMethodInvocation;
 import org.apache.tapestry5.services.Request;
 import org.apache.tapestry5.services.TransformConstants;
-import org.apache.tapestry5.services.TransformMethod;
-import org.apache.tapestry5.services.TransformMethodSignature;
 import org.apache.tapestry5.services.ValueEncoderSource;
+import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
+import org.apache.tapestry5.services.transform.TransformationSupport;
 
 /**
  * Provides implementations of the
  * {@link 
org.apache.tapestry5.runtime.Component#dispatchComponentEvent(org.apache.tapestry5.runtime.ComponentEvent)}
  * method, based on {@link org.apache.tapestry5.annotations.OnEvent} 
annotations.
  */
-public class OnEventWorker implements ComponentClassTransformWorker
+public class OnEventWorker implements ComponentClassTransformWorker2
 {
 
     private final Request request;
@@ -98,33 +103,34 @@ public class OnEventWorker implements Co
         this.classCache = classCache;
     }
 
-    public void transform(ClassTransformation transformation, 
MutableComponentModel model)
+    public void transform(PlasticClass plasticClass, TransformationSupport 
support, MutableComponentModel model)
     {
-        List<TransformMethod> methods = 
matchEventHandlerMethods(transformation);
+        Flow<PlasticMethod> methods = matchEventHandlerMethods(plasticClass);
 
         if (methods.isEmpty())
             return;
 
-        List<EventHandlerMethodInvoker> invokers = 
toInvokers(transformation.getClassName(), methods);
+        Flow<EventHandlerMethodInvoker> invokers = 
toInvokers(plasticClass.getClassName(), methods);
 
         updateModelWithHandledEvents(model, invokers);
 
-        adviseDispatchComponentEventMethod(transformation, invokers);
+        adviseDispatchComponentEventMethod(plasticClass, invokers);
     }
 
-    private void adviseDispatchComponentEventMethod(ClassTransformation 
transformation,
-            List<EventHandlerMethodInvoker> invokers)
+    private void adviseDispatchComponentEventMethod(PlasticClass plasticClass, 
Flow<EventHandlerMethodInvoker> invokers)
     {
-        ComponentMethodAdvice advice = 
createDispatchComponentEventAdvice(invokers);
+        MethodAdvice advice = createDispatchComponentEventAdvice(invokers);
 
-        
transformation.getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(advice);
+        
plasticClass.introduceMethod(TransformConstants.DISPATCH_COMPONENT_EVENT_DESCRIPTION).addAdvice(advice);
     }
 
-    private ComponentMethodAdvice createDispatchComponentEventAdvice(final 
List<EventHandlerMethodInvoker> invokers)
+    private MethodAdvice 
createDispatchComponentEventAdvice(Flow<EventHandlerMethodInvoker> invokers)
     {
-        return new ComponentMethodAdvice()
+        final EventHandlerMethodInvoker[] invokersArray = 
invokers.toArray(EventHandlerMethodInvoker.class);
+
+        return new MethodAdvice()
         {
-            public void advise(ComponentMethodInvocation invocation)
+            public void advise(MethodInvocation invocation)
             {
                 // Invoke the super-class implementation first. If no 
super-class,
                 // this will do nothing and return false.
@@ -134,7 +140,7 @@ public class OnEventWorker implements Co
                 ComponentEvent event = (ComponentEvent) 
invocation.getParameter(0);
 
                 if (invokeEventHandlers(event, invocation.getInstance()))
-                    invocation.overrideResult(true);
+                    invocation.setReturnValue(true);
             }
 
             private boolean invokeEventHandlers(ComponentEvent event, Object 
instance)
@@ -147,7 +153,7 @@ public class OnEventWorker implements Co
 
                 boolean didInvokeSomeHandler = false;
 
-                for (EventHandlerMethodInvoker invoker : invokers)
+                for (EventHandlerMethodInvoker invoker : invokersArray)
                 {
                     if (event.matches(invoker.getEventType(), 
invoker.getComponentId(),
                             invoker.getMinContextValueCount()))
@@ -166,60 +172,63 @@ public class OnEventWorker implements Co
         };
     }
 
-    private void updateModelWithHandledEvents(MutableComponentModel model,
-            final List<EventHandlerMethodInvoker> invokers)
+    private void updateModelWithHandledEvents(final MutableComponentModel 
model,
+            Flow<EventHandlerMethodInvoker> invokers)
     {
-        for (EventHandlerMethodInvoker invoker : invokers)
+        invokers.each(new Worker<EventHandlerMethodInvoker>()
         {
-            model.addEventHandler(invoker.getEventType());
-        }
+            public void work(EventHandlerMethodInvoker value)
+            {
+                model.addEventHandler(value.getEventType());
+            }
+        });
     }
 
-    private List<TransformMethod> matchEventHandlerMethods(ClassTransformation 
transformation)
+    private Flow<PlasticMethod> matchEventHandlerMethods(PlasticClass 
plasticClass)
     {
-        return transformation.matchMethods(new Predicate<TransformMethod>()
+        return F.flow(plasticClass.getMethods()).filter(new 
Predicate<PlasticMethod>()
         {
-            public boolean accept(TransformMethod method)
+            public boolean accept(PlasticMethod method)
             {
                 return (hasCorrectPrefix(method) || hasAnnotation(method)) && 
!method.isOverride();
             }
 
-            private boolean hasCorrectPrefix(TransformMethod method)
+            private boolean hasCorrectPrefix(PlasticMethod method)
             {
-                return method.getName().startsWith("on");
+                return method.getDescription().methodName.startsWith("on");
             }
 
-            private boolean hasAnnotation(TransformMethod method)
+            private boolean hasAnnotation(PlasticMethod method)
             {
-                return method.getAnnotation(OnEvent.class) != null;
+                return method.hasAnnotation(OnEvent.class);
             }
+
         });
     }
 
-    private List<EventHandlerMethodInvoker> toInvokers(String 
componentClassName, List<TransformMethod> methods)
+    private Flow<EventHandlerMethodInvoker> toInvokers(final String 
componentClassName, Flow<PlasticMethod> methods)
     {
-        List<EventHandlerMethodInvoker> result = CollectionFactory.newList();
-
-        for (TransformMethod method : methods)
+        return methods.map(new Mapper<PlasticMethod, 
EventHandlerMethodInvoker>()
         {
-            result.add(toInvoker(componentClassName, method));
-        }
-
-        return result;
+            public EventHandlerMethodInvoker map(PlasticMethod element)
+            {
+                return toInvoker(componentClassName, element);
+            }
+        });
     }
 
-    private EventHandlerMethodInvoker toInvoker(final String 
componentClassName, TransformMethod method)
+    private EventHandlerMethodInvoker toInvoker(final String 
componentClassName, PlasticMethod method)
     {
         OnEvent annotation = method.getAnnotation(OnEvent.class);
 
-        String methodName = method.getName();
+        final MethodDescription description = method.getDescription();
+
+        String methodName = description.methodName;
 
         String eventType = extractEventType(methodName, annotation);
         String componentId = extractComponentId(methodName, annotation);
 
-        final TransformMethodSignature signature = method.getSignature();
-
-        String[] parameterTypes = signature.getParameterTypes();
+        String[] parameterTypes = description.argumentTypes;
 
         if (parameterTypes.length == 0)
             return new BaseEventHandlerMethodInvoker(method, eventType, 
componentId);
@@ -242,13 +251,13 @@ public class OnEventWorker implements Co
                 continue;
             }
 
-            RequestParameter parameterAnnotation = 
method.getParameterAnnotation(i, RequestParameter.class);
+            RequestParameter parameterAnnotation = 
method.getParameters().get(i).getAnnotation(RequestParameter.class);
 
             if (parameterAnnotation != null)
             {
                 String parameterName = parameterAnnotation.value();
 
-                sources.add(createQueryParameterSource(componentClassName, 
signature, i, parameterName, type,
+                sources.add(createQueryParameterSource(componentClassName, 
description, i, parameterName, type,
                         parameterAnnotation.allowBlank()));
                 continue;
             }
@@ -265,7 +274,7 @@ public class OnEventWorker implements Co
     }
 
     private EventHandlerMethodParameterSource createQueryParameterSource(final 
String componentClassName,
-            final TransformMethodSignature signature, final int 
parameterIndex, final String parameterName,
+            final MethodDescription description, final int parameterIndex, 
final String parameterName,
             final String parameterTypeName, final boolean allowBlank)
     {
         return new EventHandlerMethodParameterSource()
@@ -301,14 +310,14 @@ public class OnEventWorker implements Co
                     throw new RuntimeException(
                             String.format(
                                     "Unable process query parameter '%s' as 
parameter #%d of event handler method %s (in class %s): %s",
-                                    parameterName, parameterIndex + 1, 
signature, componentClassName,
+                                    parameterName, parameterIndex + 1, 
description, componentClassName,
                                     InternalUtils.toMessage(ex)), ex);
                 }
             }
         };
     }
 
-    private EventHandlerMethodInvoker createInvoker(TransformMethod method, 
String eventType, String componentId,
+    private EventHandlerMethodInvoker createInvoker(PlasticMethod method, 
String eventType, String componentId,
             final int minContextCount, final 
List<EventHandlerMethodParameterSource> sources)
     {
         return new BaseEventHandlerMethodInvoker(method, eventType, 
componentId)

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=1130771&r1=1130770&r2=1130771&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
 Thu Jun  2 20:03:36 2011
@@ -639,6 +639,8 @@ public final class TapestryModule
      * <dd>Supports the {@link Import} annotation</dd>
      * <dt>UnclaimedField</dt>
      * <dd>Manages unclaimed fields, storing their value in a {@link 
PerThreadValue}</dd>
+     * <dt>OnEvent</dt>
+     * <dd>Handle the @OnEvent annotation, and related naming convention</dd>
      * </ul>
      */
     @Contribute(ComponentClassTransformWorker2.class)
@@ -652,6 +654,8 @@ public final class TapestryModule
         // be converted to clear out at the end of the request.
 
         configuration.addInstance("UnclaimedField", 
UnclaimedFieldWorker.class, "after:*");
+
+        configuration.addInstance("OnEvent", OnEventWorker.class);
     }
 
     /**
@@ -724,7 +728,6 @@ public final class TapestryModule
         configuration.add("Mixin", new MixinWorker(resolver));
         configuration
                 .addInstance("ActivationRequestParameter", 
ActivationRequestParameterWorker.class, "after:OnEvent");
-        configuration.addInstance("OnEvent", OnEventWorker.class);
         configuration.add("SupportsInformalParameters", new 
SupportsInformalParametersWorker());
         configuration.addInstance("InjectPage", InjectPageWorker.class);
         configuration.addInstance("InjectContainer", 
InjectContainerWorker.class);


Reply via email to