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 2007/01/11 02:39:15 UTC

svn commit: r495083 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/internal/structure/ main/java/org/apache/tapestry/runtime/ main/java/org/apache/tapestry/services/ main...

Author: hlship
Date: Wed Jan 10 17:39:09 2007
New Revision: 495083

URL: http://svn.apache.org/viewvc?view=rev&rev=495083
Log:
Refactor and unify event handling for both component events and render phase events.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/LifecycleEvent.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/RuntimeMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/runtime/RuntimeStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/runtime/LifecycleEventTest.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java Wed Jan 10 17:39:09 2007
@@ -14,14 +14,15 @@
 
 package org.apache.tapestry.internal.services;
 
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
 import org.apache.tapestry.ComponentEventHandler;
 import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.ioc.services.TypeCoercer;
-import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.runtime.ComponentEvent;
 
-public class ComponentEventImpl implements ComponentEvent
+public class ComponentEventImpl extends EventImpl implements ComponentEvent
 {
     private final String _eventType;
 
@@ -29,16 +30,8 @@
 
     private final Object[] _context;
 
-    private final ComponentEventHandler _handler;
-
     private final TypeCoercer _typeCoercer;
 
-    private boolean _aborted;
-
-    private Component _component;
-
-    private String _methodDescription;
-
     /**
      * @param eventType
      *            non blank string used to identify the type of event that was triggered
@@ -56,17 +49,13 @@
     public ComponentEventImpl(String eventType, String originatingComponentId, Object[] context,
             ComponentEventHandler handler, TypeCoercer typeCoercer)
     {
-        _eventType = Defense.notBlank(eventType, "eventType");
+        super(handler);
+
+        _eventType = notBlank(eventType, "eventType");
         _originatingComponentId = originatingComponentId;
         _context = context != null ? context : new Object[0];
-        _handler = Defense.notNull(handler, "handler");
-        _typeCoercer = Defense.notNull(typeCoercer, "typeCoercer");
-
-    }
+        _typeCoercer = notNull(typeCoercer, "typeCoercer");
 
-    public boolean isAborted()
-    {
-        return _aborted;
     }
 
     /**
@@ -96,37 +85,12 @@
         return false;
     }
 
-    public void setSource(Component component, String methodDescription)
-    {
-        _component = component;
-        _methodDescription = methodDescription;
-    }
-
-    @SuppressWarnings("unchecked")
-    public boolean storeResult(Object result)
-    {
-        // Given that this method is *only* invoked from code
-        // that is generated at runtime and proven to be correct,
-        // this should never, ever happen. But what the hell,
-        // let's check anyway.
-
-        if (_aborted)
-            throw new IllegalStateException(ServicesMessages
-                    .componentEventIsAborted(_methodDescription));
-
-        if (result != null)
-            
-        _aborted |= _handler.handleResult(result, _component, _methodDescription);
-
-        return _aborted;
-    }
-
     @SuppressWarnings("unchecked")
     public Object coerceContext(int index, String desiredTypeName)
     {
         if (index >= _context.length)
             throw new IllegalArgumentException(ServicesMessages
-                    .contextIndexOutOfRange(_methodDescription));
+                    .contextIndexOutOfRange(getMethodDescription()));
 
         try
         {
@@ -137,7 +101,7 @@
         catch (Exception ex)
         {
             throw new IllegalArgumentException(ServicesMessages.exceptionInMethodParameter(
-                    _methodDescription,
+                    getMethodDescription(),
                     index,
                     ex), ex);
         }
@@ -147,5 +111,4 @@
     {
         return _context;
     }
-
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java Wed Jan 10 17:39:09 2007
@@ -66,6 +66,9 @@
         _reverse = reverse;
         _lifecycleMethodName = lifecycleMethodSignature.getMethodName();
 
+        // If we ever add more parameters to the methods, then we can add more to the invocation builder.
+        // *Never* expose the Event parameter ($2), it is for internal use only.
+        
         _invocationBuilder.addParameter(MarkupWriter.class.getName(), "$1");
     }
 
@@ -81,9 +84,10 @@
         {
             public boolean accept(MethodSignature signature)
             {
-                // These methods get added to base classes and otherwise fall into this filter.  If we don't
+                // These methods get added to base classes and otherwise fall into this filter. If
+                // we don't
                 // include this filter, then we get endless loops.
-                
+
                 if (signature.equals(_lifecycleMethodSignature))
                     return false;
 
@@ -141,7 +145,14 @@
         boolean isVoid = sig.getReturnType().equals("void");
 
         if (!isVoid)
+        {
+            // If we're not going to invoke storeResult(), then there's no reason to invoke
+            // setSource().
+
+            builder.addln("$2.setSource(this, \"%s.%s\");", transformation.getClassName(), sig
+                    .getMediumDescription());
             builder.add("if ($2.storeResult(($w) ");
+        }
 
         // This is the best part; the method can even be private and this still works. It's a lot
         // like how javac enables access to private members for inner classes (by introducing
@@ -153,13 +164,10 @@
 
         if (!isVoid)
         {
-            // Complete the call to storeResult(), with a string that
-            // identifies the class and the method. Finish off the if(...) that
-            // checks the return value and returns early. The return value of
-            // LifecycleEvent.storeResult() is true if the event is aborted by the call.
+            // Complete the call to storeResult(). If storeResult() returns true, then
+            // the event is aborted and no further processing is required.
 
-            builder.addln(", \"%s.%s\")) return;", transformation.getClassName(), sig
-                    .getMediumDescription());
+            builder.addln(")) return;");
         }
         else
             builder.addln(";");

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java?view=auto&rev=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java Wed Jan 10 17:39:09 2007
@@ -0,0 +1,58 @@
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
+import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.Event;
+
+public class EventImpl implements Event
+{
+    private boolean _aborted;
+
+    private Component _component;
+
+    private String _methodDescription;
+
+    private final ComponentEventHandler _handler;
+
+    public EventImpl(ComponentEventHandler handler)
+    {
+        _handler = notNull(handler, "handler");
+    }
+
+    public boolean isAborted()
+    {
+        return _aborted;
+    }
+
+    public void setSource(Component component, String methodDescription)
+    {
+        _component = component;
+        _methodDescription = methodDescription;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean storeResult(Object result)
+    {
+        // Given that this method is *only* invoked from code
+        // that is generated at runtime and proven to be correct,
+        // this should never, ever happen. But what the hell,
+        // let's check anyway.
+
+        if (_aborted)
+            throw new IllegalStateException(ServicesMessages
+                    .componentEventIsAborted(_methodDescription));
+
+        if (result != null)
+
+            _aborted |= _handler.handleResult(result, _component, _methodDescription);
+
+        return _aborted;
+    }
+
+    protected String getMethodDescription()
+    {
+        return _methodDescription;
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Wed Jan 10 17:39:09 2007
@@ -30,6 +30,7 @@
 import org.apache.tapestry.dom.Element;
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.services.ComponentEventImpl;
+import org.apache.tapestry.internal.services.EventImpl;
 import org.apache.tapestry.internal.services.Instantiator;
 import org.apache.tapestry.internal.util.AcceptVoidEventHandler;
 import org.apache.tapestry.ioc.BaseLocatable;
@@ -42,7 +43,7 @@
 import org.apache.tapestry.model.ParameterModel;
 import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.runtime.ComponentEvent;
-import org.apache.tapestry.runtime.LifecycleEvent;
+import org.apache.tapestry.runtime.Event;
 import org.apache.tapestry.runtime.PageLifecycleListener;
 import org.apache.tapestry.runtime.RenderCommand;
 import org.apache.tapestry.runtime.RenderQueue;
@@ -110,12 +111,43 @@
         return list == null ? 0 : list.size();
     }
 
+    private static class RenderPhaseEventHandler implements ComponentEventHandler
+    {
+        private boolean _result;
+
+        public RenderPhaseEventHandler(boolean defaultResult)
+        {
+            _result = defaultResult;
+        }
+
+        boolean getResult()
+        {
+            return _result;
+        }
+
+        public boolean handleResult(Object result, Component component, String methodDescription)
+        {
+            if (result instanceof Boolean)
+            {
+                _result = (Boolean) result;
+            }
+            else
+            {
+                throw new TapestryException(StructureMessages.wrongEventResultType(
+                        methodDescription,
+                        Boolean.class), component, null);
+            }
+
+            return true; // Abort the event
+        }
+    };
+
     private final RenderCommand _afterRender = new RenderCommand()
     {
         public void render(final MarkupWriter writer, RenderQueue queue)
-
         {
-            final LifecycleEvent<Boolean> event = newEvent(false);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(false);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -127,7 +159,7 @@
 
             invoke(true, callback);
 
-            if (event.getResult())
+            if (handler.getResult())
                 queue.push(_beginRender);
         }
 
@@ -142,7 +174,8 @@
     {
         public void render(final MarkupWriter writer, RenderQueue queue)
         {
-            final LifecycleEvent<Boolean> event = newEvent(false);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(false);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -154,7 +187,7 @@
 
             invoke(true, callback);
 
-            if (event.getResult())
+            if (handler.getResult())
                 queue.push(_beforeRenderBody);
         }
 
@@ -169,7 +202,8 @@
     {
         public void render(final MarkupWriter writer, final RenderQueue queue)
         {
-            final LifecycleEvent<Boolean> event = newEvent(false);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(false);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -181,7 +215,7 @@
 
             invoke(true, callback);
 
-            if (event.getResult())
+            if (handler.getResult())
                 queue.push(_beforeRenderTemplate);
         }
 
@@ -196,7 +230,8 @@
     {
         public void render(final MarkupWriter writer, RenderQueue queue)
         {
-            final LifecycleEvent<Boolean> event = newEvent(true);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(true);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -210,7 +245,7 @@
 
             queue.push(_afterRenderBody);
 
-            if (event.getResult())
+            if (handler.getResult())
                 pushElements(queue, _body);
         }
 
@@ -225,7 +260,8 @@
     {
         public void render(final MarkupWriter writer, final RenderQueue queue)
         {
-            final LifecycleEvent<Boolean> event = newEvent(true);
+            final RenderPhaseEventHandler handler = new RenderPhaseEventHandler(true);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -239,7 +275,7 @@
 
             queue.push(_afterRenderTemplate);
 
-            if (event.getResult())
+            if (handler.getResult())
                 pushElements(queue, _template);
         }
 
@@ -254,8 +290,8 @@
     {
         public void render(final MarkupWriter writer, final RenderQueue queue)
         {
-
-            final LifecycleEvent<Boolean> event = newEvent(true);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(true);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -271,7 +307,7 @@
             // renderBody element is added as the lone element of the component's template.
             // So every component will have a non-empty template.
 
-            if (event.getResult())
+            if (handler.getResult())
             {
                 queue.push(_afterRender);
                 queue.push(_beforeRenderTemplate);
@@ -296,7 +332,8 @@
     {
         public void render(final MarkupWriter writer, RenderQueue queue)
         {
-            final LifecycleEvent<Boolean> event = newEvent(false);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(false);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -308,7 +345,7 @@
 
             invoke(true, callback);
 
-            if (event.getResult())
+            if (handler.getResult())
             {
                 queue.push(_setupRender);
             }
@@ -374,7 +411,8 @@
         {
             _rendering = true;
 
-            final LifecycleEvent<Boolean> event = newEvent(true);
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler(true);
+            final Event event = new EventImpl(handler);
 
             ComponentCallback callback = new ComponentCallback()
             {
@@ -388,7 +426,7 @@
 
             queue.push(_cleanupRender);
 
-            if (event.getResult())
+            if (handler.getResult())
                 queue.push(_beginRender);
         }
 
@@ -842,11 +880,6 @@
     public boolean isRendering()
     {
         return _rendering;
-    }
-
-    private LifecycleEvent<Boolean> newEvent(boolean defaultValue)
-    {
-        return new LifecycleEvent<Boolean>(_log, Boolean.class, defaultValue);
     }
 
     public void persistFieldChange(String fieldName, Object newValue)

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java Wed Jan 10 17:39:09 2007
@@ -12,57 +12,62 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.structure;
-
-import java.util.List;
-
+package org.apache.tapestry.internal.structure;
+
+import java.util.List;
+
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.internal.util.MessagesImpl;
-
-class StructureMessages
-{
-    private static final Messages MESSAGES = MessagesImpl.forClass(StructureMessages.class);
-
-    private StructureMessages()
-    {
-    }
-
-    static String missingParameters(List<String> parameters, ComponentPageElement element)
-    {
-        return MESSAGES.format("missing-parameters", InternalUtils.joinSorted(parameters), element
-                .getComponentResources().getComponentModel().getComponentClassName());
-    }
-
-    static String noSuchComponent(ComponentPageElement parent, String embeddedId)
-    {
-        return MESSAGES.format("no-such-component", parent.getCompleteId(), embeddedId);
-    }
-
-    static String getParameterFailure(String parameterName, String componentId, Throwable cause)
-    {
-        return MESSAGES.format("get-parameter-failure", parameterName, componentId, cause);
-    }
-
-    static String writeParameterFailure(String parameterName, String componentId, Throwable cause)
-    {
-        return MESSAGES.format("write-parameter-failure", parameterName, componentId, cause);
-    }
-
-    static String missingMixinForParameter(String componentId, String mixinName,
-            String parameterName)
-    {
-        return MESSAGES
-                .format("missing-mixin-for-parameter", componentId, mixinName, parameterName);
-    }
-
-    static String unknownMixin(String componentId, String mixinClassName)
-    {
-        return MESSAGES.format("unknown-mixin", componentId, mixinClassName);
-    }
-
-    static String detachFailure(Object listener, Throwable cause)
-    {
-        return MESSAGES.format("detach-failure", listener, cause);
-    }
-}
+
+class StructureMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(StructureMessages.class);
+
+    private StructureMessages()
+    {
+    }
+
+    static String missingParameters(List<String> parameters, ComponentPageElement element)
+    {
+        return MESSAGES.format("missing-parameters", InternalUtils.joinSorted(parameters), element
+                .getComponentResources().getComponentModel().getComponentClassName());
+    }
+
+    static String noSuchComponent(ComponentPageElement parent, String embeddedId)
+    {
+        return MESSAGES.format("no-such-component", parent.getCompleteId(), embeddedId);
+    }
+
+    static String getParameterFailure(String parameterName, String componentId, Throwable cause)
+    {
+        return MESSAGES.format("get-parameter-failure", parameterName, componentId, cause);
+    }
+
+    static String writeParameterFailure(String parameterName, String componentId, Throwable cause)
+    {
+        return MESSAGES.format("write-parameter-failure", parameterName, componentId, cause);
+    }
+
+    static String missingMixinForParameter(String componentId, String mixinName,
+            String parameterName)
+    {
+        return MESSAGES
+                .format("missing-mixin-for-parameter", componentId, mixinName, parameterName);
+    }
+
+    static String unknownMixin(String componentId, String mixinClassName)
+    {
+        return MESSAGES.format("unknown-mixin", componentId, mixinClassName);
+    }
+
+    static String detachFailure(Object listener, Throwable cause)
+    {
+        return MESSAGES.format("detach-failure", listener, cause);
+    }
+
+    static String wrongEventResultType(String method, Class expectedType)
+    {
+        return MESSAGES.format("wrong-event-result-type", method, expectedType.getName());
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java Wed Jan 10 17:39:09 2007
@@ -42,39 +42,39 @@
     /**
      * Invoked before rendering a component (or its template).
      */
-    void setupRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void setupRender(MarkupWriter writer, Event event);
 
     /**
      * Invoked to allow a component to render its tag (start tag and attributes).
      */
-    void beginRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void beginRender(MarkupWriter writer, Event event);
 
     /**
      * This phase is only invoked for components with templates.
      */
-    void beforeRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void beforeRenderTemplate(MarkupWriter writer, Event event);
 
     /** Invoked after rendering the template for a component (only for components with a template). */
-    void afterRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void afterRenderTemplate(MarkupWriter writer, Event event);
 
     /**
      * Invoked just before rendering the body of component.
      */
-    void beforeRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void beforeRenderBody(MarkupWriter writer, Event event);
 
     /** Invoked just after rendering the body of the component. */
-    void afterRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void afterRenderBody(MarkupWriter writer, Event event);
 
     /**
      * Generally used to write the close tag matching any open tag written by
      * {@link #beginRender(MarkupWriter, LifecycleEvent)}.
      */
-    void afterRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void afterRender(MarkupWriter writer, Event event);
 
     /**
      * Generally used to perform final cleanup of the component after rendering.
      */
-    void cleanupRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+    void cleanupRender(MarkupWriter writer, Event event);
 
     /**
      * Invoked to handle a component event. Methods with the {@link OnEvent} annotation will be

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java Wed Jan 10 17:39:09 2007
@@ -26,17 +26,9 @@
  *      org.apache.tapestry.ComponentEventHandler)
  * @see ComponentEventHandler
  */
-public interface ComponentEvent
+public interface ComponentEvent extends Event
 {
     /**
-     * Returns true if the event has been aborted (meaning that the return value from some event
-     * handler method was accepted, and processing of the event was terminated).
-     * 
-     * @return true if no further event handler methods should be invoked
-     */
-    boolean isAborted();
-
-    /**
      * Returns true if the component event's type matches
      * 
      * @param eventTypes
@@ -50,26 +42,6 @@
      * will never match at higher levels).
      */
     boolean matchesByComponentId(ComponentResources resources, String[] componentId);
-
-    /**
-     * Invoked before {@link #coerceContext(int, String, String)} or
-     * {@link #storeResult(Object, String)} to identify, to the event, what method is being acted
-     * upon (used for some kinds of exception reporting).
-     * 
-     * @param component
-     *            the component instance from which the result was obtained
-     * @param methodDescription
-     */
-    void setSource(Component component, String methodDescription);
-
-    /**
-     * Stores a result for the event. Storing a non-null result value will abort the event.
-     * 
-     * @param result
-     *            the result obtained from a method invocations
-     * @return true if the event is now aborted
-     */
-    boolean storeResult(Object result);
 
     /**
      * Coerces a context value to a particular type. The context is an array of objects; typically

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java?view=auto&rev=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java Wed Jan 10 17:39:09 2007
@@ -0,0 +1,41 @@
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.ComponentEventHandler;
+
+/**
+ * The core methods related to event handling. Events used in this way exist to gather data from
+ * user code, by invoking user methods and capturing the response. Return values from methods, if
+ * non-null, are passed to a {@link ComponentEventHandler}. The {@link ComponentEvent} subinterface
+ * extends this by providing access to a context, or set of information related to the event, along
+ * with additional data used, at runtime, to match events to user code methods.
+ */
+public interface Event
+{
+    /**
+     * Returns true if the event has been aborted (meaning that the return value from some event
+     * handler method was accepted, and processing of the event was terminated).
+     * 
+     * @return true if no further event handler methods should be invoked
+     */
+    boolean isAborted();
+
+    /**
+     * Invoke to identify, to the event, what component and method is being acted upon (used for
+     * some kinds of exception reporting).
+     * 
+     * @param component
+     *            the component instance from which the result was obtained
+     * @param methodDescription
+     */
+    void setSource(Component component, String methodDescription);
+
+    /**
+     * Stores a result for the event. Storing a non-null result value may abort the event (at the
+     * discretion of the {@link ComponentEventHandler}).
+     * 
+     * @param result
+     *            the result obtained from a method invocations
+     * @return true if the event is now aborted
+     */
+    boolean storeResult(Object result);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java Wed Jan 10 17:39:09 2007
@@ -18,7 +18,7 @@
 
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.runtime.ComponentEvent;
-import org.apache.tapestry.runtime.LifecycleEvent;
+import org.apache.tapestry.runtime.Event;
 
 /**
  * Constants used by implementations of
@@ -29,11 +29,10 @@
     // Shared parameters of a whole bunch of lifecycle methods, representing the different
     // component render states.
     private static final String[] RENDER_PHASE_METHOD_PARAMETERS =
-    { MarkupWriter.class.getName(), LifecycleEvent.class.getName() };
+    { MarkupWriter.class.getName(), Event.class.getName() };
 
     /**
-     * Signature for
-     * {@link org.apache.tapestry.runtime.Component#handleComponentEvent(ComponentEvent event)
+     * Signature for {@link org.apache.tapestry.runtime.Component#handleEvent(Event event)
      * 
      * @see org.apache.tapestry.annotations.OnEvent
      */
@@ -67,16 +66,14 @@
             "containingPageDidAttach");
 
     /**
-     * Signature for
-     * {@link org.apache.tapestry.runtime.Component#setupRender(MarkupWriter, LifecycleEvent)}.
+     * Signature for {@link org.apache.tapestry.runtime.Component#setupRender(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.SetupRender
      */
     public static final MethodSignature SETUP_RENDER_SIGNATURE = renderPhaseSignature("setupRender");
 
     /**
-     * Signature for
-     * {@link org.apache.tapestry.runtime.Component#beginRender(MarkupWriter, LifecycleEvent)}.
+     * Signature for {@link org.apache.tapestry.runtime.Component#beginRender(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.BeginRender
      */
@@ -84,7 +81,7 @@
 
     /**
      * Signature for
-     * {@link org.apache.tapestry.runtime.Component#beforeRenderTemplate(MarkupWriter, LifecycleEvent)}.
+     * {@link org.apache.tapestry.runtime.Component#beforeRenderTemplate(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.BeforeRenderTemplate
      */
@@ -92,7 +89,7 @@
 
     /**
      * Signature for
-     * {@link org.apache.tapestry.runtime.Component#afterRenderTemplate(MarkupWriter, LifecycleEvent)}.
+     * {@link org.apache.tapestry.runtime.Component#afterRenderTemplate(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.BeforeRenderTemplate
      */
@@ -100,7 +97,7 @@
 
     /**
      * Signature for
-     * {@link org.apache.tapestry.runtime.Component#beforeRenderBody(MarkupWriter, LifecycleEvent)}.
+     * {@link org.apache.tapestry.runtime.Component#beforeRenderBody(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.BeforeRenderBody
      */
@@ -108,15 +105,14 @@
 
     /**
      * Signature for
-     * {@link org.apache.tapestry.runtime.Component#afterRenderBody(MarkupWriter, LifecycleEvent)}.
+     * {@link org.apache.tapestry.runtime.Component#afterRenderBody(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.AfterRenderBody
      */
     public static final MethodSignature AFTER_RENDER_BODY_SIGNATURE = renderPhaseSignature("afterRenderBody");
 
     /**
-     * Signature for
-     * {@link org.apache.tapestry.runtime.Component#afterRender(MarkupWriter, LifecycleEvent)}
+     * Signature for {@link org.apache.tapestry.runtime.Component#afterRender(MarkupWriter, Event)}
      * 
      * @see org.apache.tapestry.annotations.AfterRender
      */
@@ -124,7 +120,7 @@
 
     /**
      * Signature for
-     * {@link org.apache.tapestry.runtime.Component#cleanupRender(MarkupWriter, LifecycleEvent)}.
+     * {@link org.apache.tapestry.runtime.Component#cleanupRender(MarkupWriter, Event)}.
      * 
      * @see org.apache.tapestry.annotations.CleanupRender
      */

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties Wed Jan 10 17:39:09 2007
@@ -19,3 +19,7 @@
 missing-mixin-for-parameter=Component %s does not contain a mixin named '%s' (setting parameter '%s').
 unknown-mixin=Component %s does not contain a mixin of type %s.
 detach-failure=Listener %s failed during page detach: %s
+wrong-event-result-type=Return value of method %s is not compatible with the expected return type of %s. \
+  The value has been ignored. \
+  Further lifecycle methods may be invoked, which is likely to cause incorrect application behavior. \
+  You should change the method to return the correct type. 
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java Wed Jan 10 17:39:09 2007
@@ -18,7 +18,7 @@
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.runtime.ComponentEvent;
-import org.apache.tapestry.runtime.LifecycleEvent;
+import org.apache.tapestry.runtime.Event;
 
 /**
  * For use in places where we don't want to have to transform a class just for testing purposes.
@@ -26,61 +26,61 @@
 public class DefaultComponent implements Component
 {
 
-    public void postRenderCleanup()
+    public void afterRender(MarkupWriter writer, Event event)
     {
     }
 
-    public void setupRender(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void afterRenderBody(MarkupWriter writer, Event event)
     {
     }
 
-    public void beginRender(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void afterRenderTemplate(MarkupWriter writer, Event event)
     {
     }
 
-    public void beforeRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void beforeRenderBody(MarkupWriter writer, Event event)
     {
     }
 
-    public void afterRender(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void beforeRenderTemplate(MarkupWriter writer, Event event)
     {
     }
 
-    public void cleanupRender(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void beginRender(MarkupWriter writer, Event event)
     {
     }
 
-    public ComponentResources getComponentResources()
+    public void cleanupRender(MarkupWriter writer, Event event)
     {
-        return null;
     }
 
-    public void containingPageDidLoad()
+    public boolean handleComponentEvent(ComponentEvent event)
     {
+        return false;
     }
 
-    public void containingPageDidDetach()
+    public void postRenderCleanup()
     {
     }
 
-    public void containingPageDidAttach()
+    public void setupRender(MarkupWriter writer, Event event)
     {
     }
 
-    public boolean handleComponentEvent(ComponentEvent event)
+    public ComponentResources getComponentResources()
     {
-        return false;
+        return null;
     }
 
-    public void afterRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void containingPageDidAttach()
     {
     }
 
-    public void afterRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void containingPageDidDetach()
     {
     }
 
-    public void beforeRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event)
+    public void containingPageDidLoad()
     {
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java?view=diff&rev=495083&r1=495082&r2=495083
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java Wed Jan 10 17:39:09 2007
@@ -26,6 +26,11 @@
 import org.apache.tapestry.test.TapestryTestCase;
 import org.testng.annotations.Test;
 
+/**
+ * Of course, we're committing the cardinal sin of testing the code that's generated, rather than
+ * the *behavior* of the generated code. Fortunately, we back all this up with lots and lots of
+ * integration testing.
+ */
 public class ComponentLifecycleMethodWorkerTest extends TapestryTestCase
 {
     @Test
@@ -276,7 +281,8 @@
                 "{",
                 "super.setupRender($$);",
                 "if ($2.isAborted()) return; ",
-                "if ($2.storeResult(($w) aMethod(), \"biff.Baz.aMethod()\")) return;",
+                "$2.setSource(this, \"biff.Baz.aMethod()\");",
+                "if ($2.storeResult(($w) aMethod())) return;",
                 "}");
 
         replay();
@@ -315,7 +321,8 @@
                 TransformConstants.SETUP_RENDER_SIGNATURE,
                 "{ super.setupRender($$);",
                 "if ($2.isAborted()) return;",
-                "if ($2.storeResult(($w) aMethod(), \"foo.Bar.aMethod()\")) return;",
+                "$2.setSource(this, \"foo.Bar.aMethod()\");",
+                "if ($2.storeResult(($w) aMethod())) return;",
                 "bMethod($1); }");
 
         replay();