You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/07/07 20:28:12 UTC
svn commit: r961463 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/internal/transform/
main/java/org/apache/tapestry5/runtime/
main/java/org/apache/tapestry5/services/ ...
Author: hlship
Date: Wed Jul 7 18:28:11 2010
New Revision: 961463
URL: http://svn.apache.org/viewvc?rev=961463&view=rev
Log:
TAP5-1199: ClassTransformation should include an API specifically for adding a component event handler to a component class
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventHandler.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.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/transform/ActivationRequestParameterWorker.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/internal/transform/PageActivationContextWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/runtime/ComponentEvent.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java?rev=961463&r1=961462&r2=961463&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventImpl.java Wed Jul 7 18:28:11 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 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,
@@ -31,16 +31,21 @@ public class ComponentEventImpl extends
private final ComponentPageElementResources elementResources;
/**
- * @param eventType non blank string used to identify the type of event that was triggered
- * @param originatingComponentId the id of the component that triggered the event
- * @param context provides access to parameter values
- * @param handler invoked when a non-null return value is obtained from an event handler method
- * @param elementResources provides access to common resources and services
- * @param logger used to log method invocations
+ * @param eventType
+ * non blank string used to identify the type of event that was triggered
+ * @param originatingComponentId
+ * the id of the component that triggered the event
+ * @param context
+ * provides access to parameter values
+ * @param handler
+ * invoked when a non-null return value is obtained from an event handler method
+ * @param elementResources
+ * provides access to common resources and services
+ * @param logger
+ * used to log method invocations
*/
public ComponentEventImpl(String eventType, String originatingComponentId, EventContext context,
- ComponentEventCallback handler,
- ComponentPageElementResources elementResources, Logger logger)
+ ComponentEventCallback handler, ComponentPageElementResources elementResources, Logger logger)
{
super(handler, logger);
@@ -50,26 +55,27 @@ public class ComponentEventImpl extends
this.context = context;
}
-
@Override
public String toString()
{
- return String.format("ComponentEvent[%s from %s]", eventType,
- originatingComponentId.length() == 0 ? "(self)" : originatingComponentId);
+ return String.format("ComponentEvent[%s from %s]", eventType, originatingComponentId.length() == 0 ? "(self)"
+ : originatingComponentId);
}
public boolean matches(String eventType, String componentId, int parameterCount)
{
- return this.eventType.equalsIgnoreCase(
- eventType) && context.getCount() >= parameterCount && (originatingComponentId.equalsIgnoreCase(
- componentId) || componentId.equals(""));
+ if (isAborted())
+ return false;
+
+ return this.eventType.equalsIgnoreCase(eventType) && context.getCount() >= parameterCount
+ && (originatingComponentId.equalsIgnoreCase(componentId) || componentId.equals(""));
}
@SuppressWarnings("unchecked")
public Object coerceContext(int index, String desiredTypeName)
{
- if (index >= context.getCount()) throw new IllegalArgumentException(ServicesMessages
- .contextIndexOutOfRange(getMethodDescription()));
+ if (index >= context.getCount())
+ throw new IllegalArgumentException(ServicesMessages.contextIndexOutOfRange(getMethodDescription()));
try
{
Class desiredType = elementResources.toClass(desiredTypeName);
@@ -78,8 +84,8 @@ public class ComponentEventImpl extends
}
catch (Exception ex)
{
- throw new IllegalArgumentException(
- ServicesMessages.exceptionInMethodParameter(getMethodDescription(), index, ex), ex);
+ throw new IllegalArgumentException(ServicesMessages.exceptionInMethodParameter(getMethodDescription(),
+ index, ex), ex);
}
}
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=961463&r1=961462&r2=961463&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 Wed Jul 7 18:28:11 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@ import org.apache.tapestry5.ioc.util.IdA
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.runtime.ComponentEvent;
import org.apache.tapestry5.services.*;
import org.slf4j.Logger;
@@ -335,8 +336,8 @@ public final class InternalClassTransfor
String methodName = newMemberName("access", sig.getMethodName());
TransformMethodSignature accessMethodSignature = new TransformMethodSignature(Modifier.PUBLIC
- + Modifier.STATIC, sig.getReturnType(), methodName, parameterTypes.toArray(new String[0]), sig
- .getExceptionTypes());
+ + Modifier.STATIC, sig.getReturnType(), methodName, parameterTypes.toArray(new String[0]),
+ sig.getExceptionTypes());
boolean isVoid = sig.getReturnType().equals("void");
@@ -726,7 +727,7 @@ public final class InternalClassTransfor
private final List<Object> constructorArgs;
- private final ComponentModel componentModel;
+ private final MutableComponentModel componentModel;
private final String resourcesFieldName;
@@ -758,7 +759,7 @@ public final class InternalClassTransfor
* This is a constructor for a base class.
*/
public InternalClassTransformationImpl(ClassFactory classFactory, CtClass ctClass,
- ComponentClassCache componentClassCache, ComponentModel componentModel, CtClassSource classSource)
+ ComponentClassCache componentClassCache, MutableComponentModel componentModel, CtClassSource classSource)
{
this.ctClass = ctClass;
this.componentClassCache = componentClassCache;
@@ -796,7 +797,7 @@ public final class InternalClassTransfor
*/
private InternalClassTransformationImpl(CtClass ctClass, InternalClassTransformation parentTransformation,
ClassFactory classFactory, CtClassSource classSource, ComponentClassCache componentClassCache,
- ComponentModel componentModel)
+ MutableComponentModel componentModel)
{
this.ctClass = ctClass;
this.componentClassCache = componentClassCache;
@@ -1877,8 +1878,8 @@ public final class InternalClassTransfor
// Replace the constructor body with one that fails. This leaves, as an open question,
// what to do about any other constructors.
- String body = String.format("throw new RuntimeException(\"%s\");", ServicesMessages
- .forbidInstantiateComponentClass(getClassName()));
+ String body = String.format("throw new RuntimeException(\"%s\");",
+ ServicesMessages.forbidInstantiateComponentClass(getClassName()));
defaultConstructor.setBody(body);
}
@@ -1911,15 +1912,15 @@ public final class InternalClassTransfor
// Pass $1 (the InternalComponentResources object) and the constructorArgs (from the AbstractIntantiator
// base class) into the new component instance's constructor
- cf.addMethod(Modifier.PUBLIC, NEW_INSTANCE_SIGNATURE, String.format("return new %s($1, constructorArgs);",
- componentClassName));
+ cf.addMethod(Modifier.PUBLIC, NEW_INSTANCE_SIGNATURE,
+ String.format("return new %s($1, constructorArgs);", componentClassName));
Class instantiatorClass = cf.createClass();
try
{
- Object instance = instantiatorClass.getConstructors()[0].newInstance(componentModel, String.format(
- "Instantiator[%s]", componentClassName), componentConstructorArgs);
+ Object instance = instantiatorClass.getConstructors()[0].newInstance(componentModel,
+ String.format("Instantiator[%s]", componentClassName), componentConstructorArgs);
return (Instantiator) instance;
}
@@ -2125,8 +2126,8 @@ public final class InternalClassTransfor
String fieldName = access.getFieldName();
CtMethod method = (CtMethod) where;
- formatter.format("Checking field %s %s in method %s(): ", isRead ? "read" : "write", fieldName, method
- .getName());
+ formatter.format("Checking field %s %s in method %s(): ", isRead ? "read" : "write", fieldName,
+ method.getName());
// Ignore any methods to were added as part of the transformation.
// If we reference the field there, we really mean the field.
@@ -2306,4 +2307,41 @@ public final class InternalClassTransfor
};
}
+ public void addComponentEventHandler(String eventType, int minContextValues, String methodDescription,
+ ComponentEventHandler handler)
+ {
+ Defense.notBlank(eventType, "eventType");
+ Defense.notBlank(methodDescription, "methodDescription");
+ Defense.notNull(handler, "handler");
+
+ componentModel.addEventHandler(eventType);
+
+ getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(
+ createEventHandlerAdvice(eventType, minContextValues, methodDescription, handler));
+
+ }
+
+ private static ComponentMethodAdvice createEventHandlerAdvice(final String eventType, final int minContextValues,
+ final String methodDescription, final ComponentEventHandler handler)
+ {
+ return new ComponentMethodAdvice()
+ {
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ ComponentEvent event = (ComponentEvent) invocation.getParameter(0);
+
+ if (event.matches(eventType, "", minContextValues))
+ {
+ event.setMethodDescription(methodDescription);
+
+ handler.handleEvent(invocation.getInstance(), event);
+
+ invocation.overrideResult(true);
+ }
+
+ if (!event.isAborted())
+ invocation.proceed();
+ }
+ };
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ActivationRequestParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ActivationRequestParameterWorker.java?rev=961463&r1=961462&r2=961463&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ActivationRequestParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ActivationRequestParameterWorker.java Wed Jul 7 18:28:11 2010
@@ -33,6 +33,7 @@ import org.apache.tapestry5.services.*;
* @see ActivationRequestParameter
* @since 5.2.0
*/
+@SuppressWarnings("all")
public class ActivationRequestParameterWorker implements ComponentClassTransformWorker
{
private final Request request;
@@ -41,11 +42,6 @@ public class ActivationRequestParameterW
private final ValueEncoderSource valueEncoderSource;
- interface EventHandler
- {
- void invoke(Component component, ComponentEvent event);
- }
-
public ActivationRequestParameterWorker(Request request, ComponentClassCache classCache,
ValueEncoderSource valueEncoderSource)
{
@@ -62,7 +58,6 @@ public class ActivationRequestParameterW
}
}
- @SuppressWarnings("unchecked")
private void mapFieldToQueryParameter(TransformField field, ClassTransformation transformation,
MutableComponentModel model)
{
@@ -70,8 +65,6 @@ public class ActivationRequestParameterW
String parameterName = getParameterName(field, annotation);
- TransformMethod dispatchMethod = transformation.getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT);
-
// Assumption: the field type is not one that's loaded by the component class loader, so it's safe
// to convert to a hard type during class transformation.
@@ -81,16 +74,16 @@ public class ActivationRequestParameterW
FieldAccess access = field.getAccess();
- setValueFromInitializeEventHandler(access, parameterName, encoder, dispatchMethod, model);
- decorateLinks(access, parameterName, encoder, dispatchMethod, model);
- preallocateName(parameterName, dispatchMethod, model);
+ setValueFromInitializeEventHandler(transformation, access, parameterName, encoder);
+ decorateLinks(transformation, access, parameterName, encoder);
+ preallocateName(transformation, parameterName);
}
- private void preallocateName(final String parameterName, TransformMethod dispatchMethod, MutableComponentModel model)
+ private static void preallocateName(ClassTransformation transformation, final String parameterName)
{
- EventHandler handler = new EventHandler()
+ ComponentEventHandler handler = new ComponentEventHandler()
{
- public void invoke(Component component, ComponentEvent event)
+ public void handleEvent(Component instance, ComponentEvent event)
{
IdAllocator idAllocator = event.getEventContext().get(IdAllocator.class, 0);
@@ -98,16 +91,18 @@ public class ActivationRequestParameterW
}
};
- add(dispatchMethod, model, EventConstants.PREALLOCATE_FORM_CONTROL_NAMES, handler);
+ transformation.addComponentEventHandler(EventConstants.PREALLOCATE_FORM_CONTROL_NAMES, 1,
+ "ActivationRequestParameterWorker preallocate form control name '" + parameterName + "' event handler",
+ handler);
}
- @SuppressWarnings("unchecked")
- private void setValueFromInitializeEventHandler(final FieldAccess access, final String parameterName,
- final ValueEncoder encoder, TransformMethod dispatchMethod, MutableComponentModel model)
+ @SuppressWarnings("all")
+ private void setValueFromInitializeEventHandler(ClassTransformation transformation, final FieldAccess access,
+ final String parameterName, final ValueEncoder encoder)
{
- EventHandler handler = new EventHandler()
+ ComponentEventHandler handler = new ComponentEventHandler()
{
- public void invoke(Component component, ComponentEvent event)
+ public void handleEvent(Component instance, ComponentEvent event)
{
String clientValue = request.getParameter(parameterName);
@@ -116,22 +111,23 @@ public class ActivationRequestParameterW
Object value = encoder.toValue(clientValue);
- access.write(component, value);
+ access.write(instance, value);
}
};
- add(dispatchMethod, model, EventConstants.ACTIVATE, handler);
+ transformation.addComponentEventHandler(EventConstants.ACTIVATE, 0,
+ "ActivationRequestParameterWorker activate event handler", handler);
}
- @SuppressWarnings("unchecked")
- private void decorateLinks(final FieldAccess access, final String parameterName, final ValueEncoder encoder,
- TransformMethod dispatchMethod, MutableComponentModel model)
+ @SuppressWarnings("all")
+ private static void decorateLinks(ClassTransformation transformation, final FieldAccess access,
+ final String parameterName, final ValueEncoder encoder)
{
- EventHandler handler = new EventHandler()
+ ComponentEventHandler handler = new ComponentEventHandler()
{
- public void invoke(Component component, ComponentEvent event)
+ public void handleEvent(Component instance, ComponentEvent event)
{
- Object value = access.read(component);
+ Object value = access.read(instance);
if (value == null)
return;
@@ -144,29 +140,11 @@ public class ActivationRequestParameterW
}
};
- add(dispatchMethod, model, EventConstants.DECORATE_COMPONENT_EVENT_LINK, handler);
- add(dispatchMethod, model, EventConstants.DECORATE_PAGE_RENDER_LINK, handler);
- }
-
- private void add(TransformMethod dispatchMethod, MutableComponentModel model, final String eventType,
- final EventHandler handler)
- {
- dispatchMethod.addAdvice(new ComponentMethodAdvice()
- {
- public void advise(ComponentMethodInvocation invocation)
- {
- ComponentEvent event = (ComponentEvent) invocation.getParameter(0);
-
- if (event.matches(eventType, "", 0))
- {
- handler.invoke(invocation.getInstance(), event);
- }
-
- invocation.proceed();
- }
- });
+ transformation.addComponentEventHandler(EventConstants.DECORATE_COMPONENT_EVENT_LINK, 0,
+ "ActivationRequestParameterWorker decorate component event link event handler", handler);
- model.addEventHandler(eventType);
+ transformation.addComponentEventHandler(EventConstants.DECORATE_PAGE_RENDER_LINK, 0,
+ "ActivationRequestParameterWorker decorate page render link event handler", handler);
}
private String getParameterName(TransformField field, ActivationRequestParameter annotation)
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=961463&r1=961462&r2=961463&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 Wed Jul 7 18:28:11 2010
@@ -149,8 +149,8 @@ public class OnEventWorker implements Co
for (EventHandlerMethodInvoker invoker : invokers)
{
- if (event.matches(invoker.getEventType(), invoker.getComponentId(), invoker
- .getMinContextValueCount()))
+ if (event.matches(invoker.getEventType(), invoker.getComponentId(),
+ invoker.getMinContextValueCount()))
{
didInvokeSomeHandler = true;
@@ -290,21 +290,19 @@ public class OnEventWorker implements Co
if (parameterType.isPrimitive() && value == null)
throw new RuntimeException(
- String
- .format(
- "Query parameter '%s' evaluates to null, but the event method parameter is type %s, a primitive.",
- parameterName, parameterType.getName()));
+ String.format(
+ "Query parameter '%s' evaluates to null, but the event method parameter is type %s, a primitive.",
+ parameterName, parameterType.getName()));
return value;
}
catch (Exception ex)
{
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,
- InternalUtils.toMessage(ex)), ex);
+ String.format(
+ "Unable process query parameter '%s' as parameter #%d of event handler method %s (in class %s): %s",
+ parameterName, parameterIndex + 1, signature, componentClassName,
+ InternalUtils.toMessage(ex)), ex);
}
}
};
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java?rev=961463&r1=961462&r2=961463&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageActivationContextWorker.java Wed Jul 7 18:28:11 2010
@@ -19,9 +19,11 @@ import java.util.List;
import org.apache.tapestry5.EventConstants;
import org.apache.tapestry5.annotations.PageActivationContext;
import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.runtime.ComponentEvent;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
+import org.apache.tapestry5.services.ComponentEventHandler;
import org.apache.tapestry5.services.ComponentMethodAdvice;
import org.apache.tapestry5.services.ComponentMethodInvocation;
import org.apache.tapestry5.services.FieldAccess;
@@ -59,76 +61,46 @@ public class PageActivationContextWorker
{
PageActivationContext annotation = field.getAnnotation(PageActivationContext.class);
- TransformMethod dispatchEventMethod = transformation
- .getOrCreateMethod(TransformConstants.DISPATCH_COMPONENT_EVENT);
-
FieldAccess access = field.getAccess();
if (annotation.activate())
{
- dispatchEventMethod.addAdvice(createActivateAdvice(field.getType(), access));
- model.addEventHandler(EventConstants.ACTIVATE);
+ transformation.addComponentEventHandler(EventConstants.ACTIVATE, 1,
+ "PageActivationContextWorker activate event handler",
+ createActivationHandler(field.getType(), access));
}
if (annotation.passivate())
{
- dispatchEventMethod.addAdvice(createPassivateAdvice(access));
- model.addEventHandler(EventConstants.PASSIVATE);
+ transformation.addComponentEventHandler(EventConstants.PASSIVATE, 0,
+ "PageActivationContextWorker passivate event handler", createPassivateHandler(access));
}
// We don't claim the field, and other workers may even replace it with a FieldValueConduit.
}
- private static ComponentMethodAdvice createActivateAdvice(final String fieldType, final FieldAccess access)
+ private static ComponentEventHandler createActivationHandler(final String fieldType, final FieldAccess access)
{
- return new ComponentMethodAdvice()
+ return new ComponentEventHandler()
{
- public void advise(ComponentMethodInvocation invocation)
+ public void handleEvent(Component instance, ComponentEvent event)
{
- ComponentEvent event = (ComponentEvent) invocation.getParameter(0);
-
- if (event.isAborted())
- return;
-
- if (event.matches(EventConstants.ACTIVATE, "", 1))
- {
- event.setMethodDescription(access.toString());
-
- Object value = event.coerceContext(0, fieldType);
-
- access.write(invocation.getInstance(), value);
-
- invocation.overrideResult(true);
- }
+ Object value = event.coerceContext(0, fieldType);
- invocation.proceed();
+ access.write(instance, value);
}
};
}
- private static ComponentMethodAdvice createPassivateAdvice(final FieldAccess access)
+ private static ComponentEventHandler createPassivateHandler(final FieldAccess access)
{
- return new ComponentMethodAdvice()
+ return new ComponentEventHandler()
{
- public void advise(ComponentMethodInvocation invocation)
+ public void handleEvent(Component instance, ComponentEvent event)
{
- ComponentEvent event = (ComponentEvent) invocation.getParameter(0);
-
- if (event.isAborted())
- return;
-
- if (event.matches(EventConstants.PASSIVATE, "", 0))
- {
- event.setMethodDescription(access.toString());
-
- Object value = access.read(invocation.getInstance());
-
- event.storeResult(value);
-
- invocation.overrideResult(true);
- }
+ Object value = access.read(instance);
- invocation.proceed();
+ event.storeResult(value);
}
};
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/runtime/ComponentEvent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/runtime/ComponentEvent.java?rev=961463&r1=961462&r2=961463&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/runtime/ComponentEvent.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/runtime/ComponentEvent.java Wed Jul 7 18:28:11 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 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,
@@ -20,28 +20,33 @@ import org.apache.tapestry5.EventContext
/**
* An event that may originate in application logic, or as a result of a client interaction (a GET or POST from the
* client).
- *
+ *
* @see ComponentResourcesCommon#triggerEvent(String, Object[], org.apache.tapestry5.ComponentEventCallback)
* @see org.apache.tapestry5.ComponentEventCallback
*/
public interface ComponentEvent extends Event
{
/**
- * Returns true if the event matches the provided criteria.
- *
- * @param eventType the type of event (case insensitive match)
- * @param componentId component is to match against (case insensitive), or the empty string
- * @param parameterCount minimum number of context values
- * @return true if the event matches.
+ * Returns true if the event matches the provided criteria and the event has not yet been aborted.
+ *
+ * @param eventType
+ * the type of event (case insensitive match)
+ * @param componentId
+ * component is to match against (case insensitive), or the empty string
+ * @param parameterCount
+ * minimum number of context values
+ * @return true if the event matches (and has not yet been aborted)
*/
boolean matches(String eventType, String componentId, int parameterCount);
/**
* Coerces a context value to a particular type. The context is an array of objects; typically it is an array of
* strings of extra path information encoded into the action URL.
- *
- * @param index the index of the context value
- * @param desiredTypeName the desired type
+ *
+ * @param index
+ * the index of the context value
+ * @param desiredTypeName
+ * the desired type
* @return the coerced value (a wrapper type if the desired type is a primitive)
*/
Object coerceContext(int index, String desiredTypeName);
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=961463&r1=961462&r2=961463&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 Wed Jul 7 18:28:11 2010
@@ -23,6 +23,9 @@ import org.apache.tapestry5.ComponentRes
import org.apache.tapestry5.func.Predicate;
import org.apache.tapestry5.internal.transform.ReadOnlyFieldValueConduit;
import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.runtime.Event;
import org.slf4j.Logger;
/**
@@ -616,4 +619,24 @@ public interface ClassTransformation ext
* @return true if a such a method exists
*/
boolean isDeclaredMethod(TransformMethodSignature signature);
+
+ /**
+ * Adds advice to the {@link Component#dispatchComponentEvent(org.apache.tapestry5.runtime.ComponentEvent)} method.
+ * If the handler is invoked,
+ * the return value of the method will be overriden to true. The invocation will proceeed either way (whether the
+ * handler is invoked or not). Updates {@linkplain MutableComponentModel#addEventHandler(String) the model} to
+ * indicate that there is a handler for the named event.
+ *
+ * @param eventType
+ * name of event to be handled
+ * @param minContextValues
+ * minimum number of event context values required to invoke the method
+ * @param methodDescription
+ * Text description of what the handler does (used with {@link Event#setMethodDescription(String)})
+ * @param handler
+ * the handler to invoke
+ * @since 5.2.0
+ */
+ void addComponentEventHandler(String eventType, int minContextValues, String methodDescription,
+ ComponentEventHandler handler);
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventHandler.java?rev=961463&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventHandler.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventHandler.java Wed Jul 7 18:28:11 2010
@@ -0,0 +1,29 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.services;
+
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.runtime.ComponentEvent;
+
+/**
+ * Interface used with {@link ClassTransformation#addComponentEventHandler(String, int, String, ComponentEventHandler)}.
+ *
+ * @since 5.2.0
+ */
+public interface ComponentEventHandler
+{
+ /** Handles the event. */
+ void handleEvent(Component instance, ComponentEvent event);
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentEventHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java?rev=961463&r1=961462&r2=961463&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java Wed Jul 7 18:28:11 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 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,
@@ -66,6 +66,31 @@ public class ComponentEventImplTest exte
verify();
}
+ /** @since 5.2.0 */
+ @Test
+ public void no_match_one_event_is_aborted()
+ {
+ ComponentEventCallback handler = mockComponentEventHandler();
+ EventContext context = mockEventContext();
+ Logger logger = mockLogger();
+ Object result = new Object();
+
+ train_isDebugEnabled(logger, false);
+
+ train_handleResult(handler, result, true);
+
+ replay();
+
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, logger);
+
+ event.storeResult(result);
+
+ assertFalse(event.matches("eventType", "someId", 0));
+
+ verify();
+
+ }
+
@Test
public void event_type_match_is_case_insensitive()
{
@@ -178,7 +203,7 @@ public class ComponentEventImplTest exte
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(),
- "Method foo.Bar.baz() has more parameters than there are context values for this component event.");
+ "Method foo.Bar.baz() has more parameters than there are context values for this component event.");
}
verify();
@@ -334,8 +359,7 @@ public class ComponentEventImplTest exte
}
catch (IllegalStateException ex)
{
- assertEquals(ex.getMessage(), ServicesMessages
- .componentEventIsAborted("foo.Bar.biff()"));
+ assertEquals(ex.getMessage(), ServicesMessages.componentEventIsAborted("foo.Bar.biff()"));
}
verify();