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);