tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject svn commit: r617866 [1/2] - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/ tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ tapestry-core/src/main/java/org/apache/tapestry/internal/ tapestry-core/src/m...
Date Sat, 02 Feb 2008 19:27:02 GMT
Author: hlship
Date: Sat Feb  2 11:26:57 2008
New Revision: 617866

URL: http://svn.apache.org/viewvc?rev=617866&view=rev
Log:
TAPESTRY-2112: Tapestry should use ValueEncoders, not simple type coercion, to convert between event context values, URL strings, and event method handler parameters

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventContextRenderer.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Sat Feb  2 11:26:57 2008
@@ -56,16 +56,22 @@
     String getCompleteId();
 
     /**
+     * A convienience for invoking {@link #triggerContextEvent(String, EventContext , ComponentEventCallback)}.
+     * Wraps the context values into an {@link EventContext}.
+     */
+    boolean triggerEvent(String eventType, Object[] contextValues, ComponentEventCallback callback);
+
+    /**
      * Triggers a component event. A search for an event handling method will occur, first in the component, then its
      * container, and so on. When a matching event handler method is located, it is invoked. If the method returns a
-     * value, the value is passed to the handler (if handler is null, then it is an error for a method to return a
+     * value, the value is passed to the callback (if callback is null, then it is an error for a method to return a
      * non-null value).
      * <p/>
      * Resolution of event type to event handler methods is case insensitive.
      *
      * @param eventType event type (as determined from the request, or otherwise by design)
      * @param context   the context (as extracted from the request, or provided by the triggering component); these
-     *                  values may be provided to event handler methods via their parameters (may be null)
+     *                  values may be provided to event handler methods via their parameters (may not be null)
      * @param callback  the handler to be informed of the result, or null if the event is a notification that does not
      *                  support return values from event handler methods (the value true is allowed even if the handler
      *                  is null).
@@ -75,7 +81,7 @@
      * @see OnEventWorker
      * @see OnEvent
      */
-    boolean triggerEvent(String eventType, Object[] context, ComponentEventCallback callback);
+    boolean triggerContextEvent(String eventType, EventContext context, ComponentEventCallback callback);
 
     /**
      * Returns true if the component is currently rendering, false otherwise. This is most often used to determine if

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,40 @@
+// Copyright 2008 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.tapestry;
+
+/**
+ * A collection of parameters that may eventually be passed to an event handler method.  Includes the ability to
+ * coerce or encode parameters as needed.
+ *
+ * @see org.apache.tapestry.ioc.services.TypeCoercer
+ * @see org.apache.tapestry.ValueEncoder
+ */
+public interface EventContext
+{
+    /**
+     * Returns the number of parameter values that can be extracted.
+     */
+    int getCount();
+
+    /**
+     * Extracts a parameter value and coerces or decodes it to the desired type.
+     *
+     * @param desiredType the type of value required
+     * @param index       identifies which parameter value to extract
+     * @return the value extracted and converted or coerced
+     * @throws RuntimeException if the value can't be converted or the index is out of range
+     */
+    <T> T get(Class<T> desiredType, int index);
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java Sat Feb  2 11:26:57 2008
@@ -75,7 +75,7 @@
 
     final ValueEncoder defaultEncoder()
     {
-        return _valueEncoderSource.createEncoder("value", _resources);
+        return _valueEncoderSource.getEncoderForParameter("value", _resources);
     }
 
     private static class Setup implements ComponentAction<RadioGroup>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java Sat Feb  2 11:26:57 2008
@@ -163,7 +163,7 @@
     @SuppressWarnings("unchecked")
     ValueEncoder defaultEncoder()
     {
-        return _valueEncoderSource.createEncoder("value", _resources);
+        return _valueEncoderSource.getEncoderForParameter("value", _resources);
     }
 
     @SuppressWarnings("unchecked")

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,39 @@
+// Copyright 2008 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.tapestry.internal;
+
+import org.apache.tapestry.EventContext;
+
+/**
+ * Placeholder used when no context is available.
+ */
+public class EmptyEventContext implements EventContext
+{
+    /**
+     * Always returns zero.
+     */
+    public int getCount()
+    {
+        return 0;
+    }
+
+    /**
+     * This should never be called because the count is always zero.
+     */
+    public <T> T get(Class<T> desiredType, int index)
+    {
+        return null;
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,46 @@
+// Copyright 2008 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.tapestry.internal;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.services.ContextValueEncoder;
+
+/**
+ * Implementation based on values extracted from the URL (an event context, or a page activation context)
+ * that uses a {@link org.apache.tapestry.services.ContextValueEncoder} to convert from string values
+ * to the desired values.
+ */
+public class URLEventContext implements EventContext
+{
+    private final ContextValueEncoder _valueEncoder;
+
+    private final String[] _values;
+
+    public URLEventContext(ContextValueEncoder valueEncoder, String[] values)
+    {
+        _valueEncoder = valueEncoder;
+        _values = values;
+    }
+
+    public int getCount()
+    {
+        return _values.length;
+    }
+
+    public <T> T get(Class<T> desiredType, int index)
+    {
+        return _valueEncoder.toValue(desiredType, _values[index]);
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java Sat Feb  2 11:26:57 2008
@@ -57,8 +57,8 @@
 
         ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(_resultProcessor);
 
-        activePage.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT,
-                                                 parameters.getPageActivationContext(), callback);
+        activePage.getRootElement().triggerContextEvent(TapestryConstants.ACTIVATE_EVENT,
+                                                        parameters.getPageActivationContext(), callback);
 
         if (callback.isAborted()) return;
 
@@ -75,7 +75,7 @@
 
         ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
 
-        element.triggerEvent(parameters.getEventType(), parameters.getEventContext(), callback);
+        element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
 
         if (callback.isAborted()) return;
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java Sat Feb  2 11:26:57 2008
@@ -14,9 +14,12 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.internal.EmptyEventContext;
 import org.apache.tapestry.internal.InternalConstants;
 import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.URLEventContext;
 import org.apache.tapestry.services.*;
 
 import java.io.IOException;
@@ -27,7 +30,6 @@
  * Processes component action events sent as requests from the client. Action events include an event type, identify a
  * page and a component, and may provide additional context strings.
  * <p/>
- * <p/>
  * Forms: <ul> <li>/context/pagename:eventname -- event on the page, no action context</li>
  * <li>/context/pagename:eventname/foo/bar -- event on the page with action context "foo", "bar"</li>
  * <li>/context/pagename.foo.bar -- event on component foo.bar within the page, default event, no action context</li>
@@ -35,12 +37,9 @@
  * context "baz", "gnu"</li> <li>/context/pagename.bar.baz:eventname/foo/gnu -- event on component bar.baz within the
  * page with action context "foo" , "gnu"</li> </ul>
  * <p/>
- * <p/>
  * The page name portion may itself consist of a series of folder names, i.e., "admin/user/create".  The context portion
  * isn't the concern of this code, since {@link org.apache.tapestry.services.Request#getPath()} will already have
  * stripped that off.  We can act as if the context is always "/" (the path always starts with a slash).
- * <p/>
- * <p/>
  *
  * @see LinkFactory#createActionLink(org.apache.tapestry.internal.structure.Page, String, String,boolean, Object...)
  */
@@ -50,13 +49,17 @@
 
     private final ComponentEventRequestHandler _componentEventRequestHandler;
 
-    private final String[] _emptyString = new String[0];
+    private final ContextValueEncoder _contextValueEncoder;
+
+    private final EventContext _emptyContext = new EmptyEventContext();
 
     public ComponentEventDispatcher(ComponentEventRequestHandler componentEventRequestHandler,
-                                    ComponentClassResolver componentClassResolver)
+                                    ComponentClassResolver componentClassResolver,
+                                    ContextValueEncoder contextValueEncoder)
     {
         _componentEventRequestHandler = componentEventRequestHandler;
         _componentClassResolver = componentClassResolver;
+        _contextValueEncoder = contextValueEncoder;
     }
 
     // A beast that recognizes all the elements of a path in a single go.
@@ -104,12 +107,9 @@
 
         if (!_componentClassResolver.isPageName(containingPageName)) return false;
 
-        String[] eventContext = decodeContext(matcher.group(CONTEXT));
-
-        String activationContextValue = request.getParameter(InternalConstants.PAGE_CONTEXT_NAME);
+        EventContext eventContext = decodeContext(matcher.group(CONTEXT));
 
-        String[] activationContext = activationContextValue == null ? _emptyString : decodeContext(
-                activationContextValue);
+        EventContext activationContext = decodeContext(request.getParameter(InternalConstants.PAGE_CONTEXT_NAME));
 
         // The event type is often omitted, and defaults to "action".
 
@@ -133,18 +133,19 @@
         return true;
     }
 
-    private String[] decodeContext(String input)
+
+    private EventContext decodeContext(String input)
     {
-        if (input == null) return _emptyString;
+        if (input == null) return _emptyContext;
 
-        String[] result = SLASH_PATTERN.split(input);
+        String[] values = SLASH_PATTERN.split(input);
 
-        for (int i = 0; i < result.length; i++)
+        for (int i = 0; i < values.length; i++)
         {
-            result[i] = TapestryInternalUtils.unescapePercentAndSlash(result[i]);
+            values[i] = TapestryInternalUtils.unescapePercentAndSlash(values[i]);
         }
 
-        return result;
+        return new URLEventContext(_contextValueEncoder, values);
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java Sat Feb  2 11:26:57 2008
@@ -15,6 +15,7 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.internal.structure.PageResources;
 import org.apache.tapestry.runtime.ComponentEvent;
 
@@ -24,7 +25,7 @@
 
     private final String _originatingComponentId;
 
-    private final Object[] _context;
+    private final EventContext _context;
 
     private final PageResources _pageResources;
 
@@ -32,12 +33,11 @@
      * @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 (this will likely need to change
      *                               somewhat)
-     * @param context                an array of values that can be made available to handler methods via method
-     *                               parameters
+     * @param context                provides access to parameter values
      * @param handler                invoked when a non-null return value is obtained from an event handler method
      * @param pageResources          provides access to common resources and services
      */
-    public ComponentEventImpl(String eventType, String originatingComponentId, Object[] context,
+    public ComponentEventImpl(String eventType, String originatingComponentId, EventContext context,
                               ComponentEventCallback handler, PageResources pageResources)
     {
         super(handler);
@@ -45,26 +45,27 @@
         _eventType = eventType;
         _originatingComponentId = originatingComponentId;
         _pageResources = pageResources;
-        _context = context != null ? context : new Object[0];
+        _context = context;
     }
 
     public boolean matches(String eventType, String componentId, int parameterCount)
     {
         return _eventType.equalsIgnoreCase(
-                eventType) && _context.length >= parameterCount && (_originatingComponentId.equalsIgnoreCase(
+                eventType) && _context.getCount() >= parameterCount && (_originatingComponentId.equalsIgnoreCase(
                 componentId) || componentId.equals(""));
     }
 
     @SuppressWarnings("unchecked")
     public Object coerceContext(int index, String desiredTypeName)
     {
-        if (index >= _context.length) throw new IllegalArgumentException(ServicesMessages
+        if (index >= _context.getCount()) throw new IllegalArgumentException(ServicesMessages
                 .contextIndexOutOfRange(getMethodDescription()));
         try
         {
             Class desiredType = _pageResources.toClass(desiredTypeName);
 
-            return _pageResources.coerce(_context[index], desiredType);
+            return _context.get(desiredType, index);
+
         }
         catch (Exception ex)
         {
@@ -75,6 +76,13 @@
 
     public Object[] getContext()
     {
-        return _context;
+        int count = _context.getCount();
+
+        Object[] result = new Object[count];
+
+        for (int i = 0; i < count; i++)
+            result[i] = _context.get(Object.class, i);
+
+        return result;
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java Sat Feb  2 11:26:57 2008
@@ -50,8 +50,8 @@
         // If activating the page returns a "navigational result", then don't trigger the action
         // on the component.
 
-        activePage.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT,
-                                                 parameters.getPageActivationContext(), callback);
+        activePage.getRootElement().triggerContextEvent(TapestryConstants.ACTIVATE_EVENT,
+                                                        parameters.getPageActivationContext(), callback);
 
         if (callback.isAborted()) return;
 
@@ -59,7 +59,7 @@
 
         ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
 
-        element.triggerEvent(parameters.getEventType(), parameters.getEventContext(), callback);
+        element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
 
         if (callback.isAborted()) return;
 

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,49 @@
+// Copyright 2008 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.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.ValueEncoderSource;
+
+public class ContextValueEncoderImpl implements ContextValueEncoder
+{
+    private final ValueEncoderSource _valueEncoderSource;
+
+    public ContextValueEncoderImpl(ValueEncoderSource valueEncoderSource)
+    {
+        _valueEncoderSource = valueEncoderSource;
+    }
+
+    public String toClient(Object value)
+    {
+        Defense.notNull(value, "value");
+
+        ValueEncoder encoder = _valueEncoderSource.getEncoderForType(value.getClass());
+
+        return encoder.toClient(value);
+    }
+
+
+    public <T> T toValue(Class<T> requiredType, String clientValue)
+    {
+        Defense.notNull(requiredType, "requiredType");
+
+        ValueEncoder<T> encoder = _valueEncoderSource.getEncoderForType(requiredType);
+
+        return encoder.toValue(clientValue);
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventContextRenderer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventContextRenderer.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventContextRenderer.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventContextRenderer.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,54 @@
+// Copyright 2008 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.tapestry.internal.services;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.annotations.Primary;
+import org.apache.tapestry.services.ObjectRenderer;
+
+/**
+ * Renders out the values stored inside a {@link EventContext}.
+ */
+public class EventContextRenderer implements ObjectRenderer<EventContext>
+{
+    private final ObjectRenderer _masterRenderer;
+
+    public EventContextRenderer(@Primary ObjectRenderer masterRenderer)
+    {
+        _masterRenderer = masterRenderer;
+    }
+
+
+    public void render(EventContext object, MarkupWriter writer)
+    {
+        int count = object.getCount();
+
+        if (count == 0) return;
+
+        writer.element("ul", "class", "t-data-list");
+
+        for (int i = 0; i < count; i++)
+        {
+            writer.element("li");
+
+            _masterRenderer.render(object.get(Object.class, i), writer);
+
+            writer.end();
+        }
+
+        writer.end();
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java Sat Feb  2 11:26:57 2008
@@ -24,8 +24,8 @@
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
 import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
-import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.services.ContextValueEncoder;
 import org.apache.tapestry.services.Request;
 import org.apache.tapestry.services.Response;
 
@@ -44,7 +44,7 @@
 
     private final RequestPageCache _pageCache;
 
-    private final TypeCoercer _typeCoercer;
+    private final ContextValueEncoder _contextValueEncoder;
 
     private final RequestPathOptimizer _optimizer;
 
@@ -61,26 +61,19 @@
     }
 
     public LinkFactoryImpl(Request request,
-
                            Response encoder,
-
                            ComponentInvocationMap componentInvocationMap,
-
                            RequestPageCache pageCache,
-
-                           TypeCoercer typeCoercer,
-
                            RequestPathOptimizer optimizer,
-
-                           PageRenderQueue pageRenderQueue)
+                           PageRenderQueue pageRenderQueue, ContextValueEncoder contextValueEncoder)
     {
         _request = request;
         _response = encoder;
         _componentInvocationMap = componentInvocationMap;
         _pageCache = pageCache;
-        _typeCoercer = typeCoercer;
         _optimizer = optimizer;
         _pageRenderQueue = pageRenderQueue;
+        _contextValueEncoder = contextValueEncoder;
 
         Map<Class, PassivateContextHandler> registrations = newMap();
 
@@ -233,7 +226,7 @@
         String[] result = new String[context.length];
 
         for (int i = 0; i < context.length; i++)
-            result[i] = _typeCoercer.coerce(context[i], String.class);
+            result[i] = _contextValueEncoder.toClient(context[i]);
 
         return result;
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java Sat Feb  2 11:26:57 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -14,7 +14,9 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.URLEventContext;
 import org.apache.tapestry.services.*;
 
 import java.io.IOException;
@@ -31,10 +33,14 @@
 
     private final PageRenderRequestHandler _handler;
 
-    public PageRenderDispatcher(ComponentClassResolver componentClassResolver, PageRenderRequestHandler handler)
+    private final ContextValueEncoder _contextValueEncoder;
+
+    public PageRenderDispatcher(ComponentClassResolver componentClassResolver, PageRenderRequestHandler handler,
+                                ContextValueEncoder contextValueEncoder)
     {
         _componentClassResolver = componentClassResolver;
         _handler = handler;
+        _contextValueEncoder = contextValueEncoder;
     }
 
     public boolean dispatch(Request request, final Response response) throws IOException
@@ -63,7 +69,12 @@
                 String[] context = atEnd ? new String[0] : convertActivationContext(path
                         .substring(nextslashx + 1));
 
-                _handler.handle(pageName, context);
+                EventContext activationContext
+                        = new URLEventContext(_contextValueEncoder, context);
+
+                PageRenderRequestParameters parameters = new PageRenderRequestParameters(pageName, activationContext);
+
+                _handler.handle(parameters);
 
                 return true;
             }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java Sat Feb  2 11:26:57 2008
@@ -18,6 +18,7 @@
 import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.services.ComponentEventResultProcessor;
 import org.apache.tapestry.services.PageRenderRequestHandler;
+import org.apache.tapestry.services.PageRenderRequestParameters;
 import org.apache.tapestry.services.Traditional;
 
 import java.io.IOException;
@@ -42,13 +43,14 @@
         _pageResponseRenderer = pageResponseRenderer;
     }
 
-    public void handle(String logicalPageName, String[] context) throws IOException
+    public void handle(PageRenderRequestParameters parameters) throws IOException
     {
-        Page page = _cache.get(logicalPageName);
+        Page page = _cache.get(parameters.getLogicalPageName());
 
         ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(_resultProcessor);
 
-        page.getRootElement().triggerEvent(TapestryConstants.ACTIVATE_EVENT, context, callback);
+        page.getRootElement().triggerContextEvent(TapestryConstants.ACTIVATE_EVENT, parameters.getActivationContext(),
+                                                  callback);
 
         // The handler will have asked the result processor to send a response.
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java Sat Feb  2 11:26:57 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.internal.services;
 
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.EmptyEventContext;
 import org.apache.tapestry.services.*;
 
 import java.io.IOException;
@@ -28,28 +30,29 @@
 
     private final PageRenderRequestHandler _handler;
 
-
     private final String _startPageName;
 
-    private final String[] _emptyContext = new String[0];
+    private static final EventContext EMPTY_CONTEXT = new EmptyEventContext();
+
+    private final PageRenderRequestParameters _parameters;
 
-    public RootPathDispatcher(final ComponentClassResolver componentClassResolver,
-                              final PageRenderRequestHandler handler, final String startPageName)
+    public RootPathDispatcher(ComponentClassResolver componentClassResolver,
+                              PageRenderRequestHandler handler, String startPageName)
     {
         _componentClassResolver = componentClassResolver;
         _handler = handler;
         _startPageName = startPageName;
+
+        _parameters = new PageRenderRequestParameters(_startPageName, EMPTY_CONTEXT);
     }
 
     public boolean dispatch(Request request, final Response response) throws IOException
     {
         // Only match the root path
 
-        if (!request.getPath().equals("/")) return false;
-
-        if (_componentClassResolver.isPageName(_startPageName))
+        if (request.getPath().equals("/") && _componentClassResolver.isPageName(_startPageName))
         {
-            _handler.handle(_startPageName, _emptyContext);
+            _handler.handle(_parameters);
 
             return true;
         }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java Sat Feb  2 11:26:57 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -17,6 +17,8 @@
 import org.apache.tapestry.ComponentResources;
 import org.apache.tapestry.ValueEncoder;
 import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
 import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 import org.apache.tapestry.ioc.util.StrategyRegistry;
@@ -29,13 +31,15 @@
 {
     private final StrategyRegistry<ValueEncoderFactory> _registry;
 
+    private final Map<Class, ValueEncoder> _cache = CollectionFactory.newConcurrentMap();
+
     public ValueEncoderSourceImpl(Map<Class, ValueEncoderFactory> configuration)
     {
         _registry = StrategyRegistry.newInstance(ValueEncoderFactory.class, configuration);
     }
 
     @SuppressWarnings("unchecked")
-    public ValueEncoder createEncoder(String parameterName, ComponentResources resources)
+    public ValueEncoder getEncoderForParameter(String parameterName, ComponentResources resources)
     {
         notBlank(parameterName, "parameterName");
         notNull(resources, "resources");
@@ -44,13 +48,31 @@
 
         if (parameterType == null) return null;
 
-        ValueEncoderFactory factory = _registry.get(parameterType);
+        return getEncoderForType(parameterType);
+    }
+
+    @SuppressWarnings({"unchecked"})
+    public <T> ValueEncoder<T> getEncoderForType(Class<T> type)
+    {
+        Defense.notNull(type, "type");
+
+        ValueEncoder<T> result = _cache.get(type);
+
+        if (result == null)
+        {
+            ValueEncoderFactory<T> factory = _registry.get(type);
+
+            result = factory.create(type);
+
+            _cache.put(type, result);
+        }
 
-        return factory.create(parameterType);
+        return result;
     }
 
     public void objectWasInvalidated()
     {
         _registry.clearCache();
+        _cache.clear();
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Sat Feb  2 11:26:57 2008
@@ -26,6 +26,7 @@
 import org.apache.tapestry.ioc.Location;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.Defense;
 import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.internal.util.TapestryException;
@@ -928,8 +929,36 @@
         return String.format("ComponentPageElement[%s]", _completeId);
     }
 
-    public boolean triggerEvent(String eventType, Object[] context, ComponentEventCallback callback)
+    public boolean triggerEvent(String eventType, Object[] contextValues, ComponentEventCallback callback)
     {
+        return triggerContextEvent(eventType,
+                                   createParameterContext(contextValues == null ? new Object[0] : contextValues),
+                                   callback);
+    }
+
+    private EventContext createParameterContext(final Object... values)
+    {
+
+        return new EventContext()
+        {
+            public int getCount()
+            {
+                return values.length;
+            }
+
+            public <T> T get(Class<T> desiredType, int index)
+            {
+                return _pageResources.coerce(values[index], desiredType);
+            }
+        };
+    }
+
+
+    public boolean triggerContextEvent(String eventType, EventContext context, ComponentEventCallback callback)
+    {
+        Defense.notBlank(eventType, "eventType");
+        Defense.notNull(context, "context");
+
         boolean result = false;
 
         ComponentPageElement component = this;
@@ -957,7 +986,7 @@
         // Because I don't like to reassign parameters.
 
         String currentEventType = eventType;
-        Object[] currentContext = context;
+        EventContext currentContext = context;
 
         while (component != null)
         {
@@ -991,7 +1020,7 @@
                 // threw the exception.
 
                 currentEventType = "exception";
-                currentContext = new Object[]{rootException};
+                currentContext = createParameterContext(rootException);
 
                 continue;
             }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Sat Feb  2 11:26:57 2008
@@ -154,6 +154,11 @@
         return _element.triggerEvent(eventType, context, handler);
     }
 
+    public boolean triggerContextEvent(String eventType, EventContext context, ComponentEventCallback callback)
+    {
+        return _element.triggerContextEvent(eventType, context, callback);
+    }
+
     public String getNestedId()
     {
         return _element.getNestedId();

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java Sat Feb  2 11:26:57 2008
@@ -16,12 +16,13 @@
 
 import org.apache.tapestry.ioc.Messages;
 import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ContextValueEncoder;
 
 /**
  * Provides access to common methods of various services, needed by implementations of {@link ComponentPageElement} and
  * {@link org.apache.tapestry.internal.InternalComponentResources}.
  */
-public interface PageResources
+public interface PageResources extends ContextValueEncoder
 {
     /**
      * Used to obtain a {@link org.apache.tapestry.ioc.Messages} instance for a particular component. If the component

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java Sat Feb  2 11:26:57 2008
@@ -19,6 +19,7 @@
 import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.services.ComponentMessagesSource;
+import org.apache.tapestry.services.ContextValueEncoder;
 
 import java.util.Locale;
 
@@ -32,13 +33,16 @@
 
     private final ComponentClassCache _componentClassCache;
 
+    private final ContextValueEncoder _contextValueEncoder;
+
     public PageResourcesImpl(Locale locale, ComponentMessagesSource componentMessagesSource, TypeCoercer typeCoercer,
-                             ComponentClassCache componentClassCache)
+                             ComponentClassCache componentClassCache, ContextValueEncoder contextValueEncoder)
     {
         _componentMessagesSource = componentMessagesSource;
         _locale = locale;
         _typeCoercer = typeCoercer;
         _componentClassCache = componentClassCache;
+        _contextValueEncoder = contextValueEncoder;
     }
 
     public Messages getMessages(ComponentModel componentModel)
@@ -54,5 +58,15 @@
     public Class toClass(String className)
     {
         return _componentClassCache.forName(className);
+    }
+
+    public String toClient(Object value)
+    {
+        return _contextValueEncoder.toClient(value);
+    }
+
+    public <T> T toValue(Class<T> requiredType, String clientValue)
+    {
+        return _contextValueEncoder.toValue(requiredType, clientValue);
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java Sat Feb  2 11:26:57 2008
@@ -19,6 +19,7 @@
 import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.services.ComponentMessagesSource;
+import org.apache.tapestry.services.ContextValueEncoder;
 
 import java.util.Locale;
 import java.util.Map;
@@ -33,12 +34,15 @@
 
     private final ComponentClassCache _componentClassCache;
 
+    private final ContextValueEncoder _contextValueEncoder;
+
     public PageResourcesSourceImpl(ComponentMessagesSource componentMessagesSource, TypeCoercer typeCoercer,
-                                   ComponentClassCache componentClassCache)
+                                   ComponentClassCache componentClassCache, ContextValueEncoder contextValueEncoder)
     {
         _componentMessagesSource = componentMessagesSource;
         _typeCoercer = typeCoercer;
         _componentClassCache = componentClassCache;
+        _contextValueEncoder = contextValueEncoder;
     }
 
     public PageResources get(Locale locale)
@@ -49,7 +53,8 @@
 
         if (result == null)
         {
-            result = new PageResourcesImpl(locale, _componentMessagesSource, _typeCoercer, _componentClassCache);
+            result = new PageResourcesImpl(locale, _componentMessagesSource, _typeCoercer, _componentClassCache,
+                                           _contextValueEncoder);
 
             // Small race condition here, where we may create two instances of PRI for the same locale,
             // but that's not worth worrying about.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java Sat Feb  2 11:26:57 2008
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry.Link;
 import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.internal.URLEventContext;
 import org.apache.tapestry.internal.services.ActionLinkTarget;
 import org.apache.tapestry.internal.services.ComponentInvocation;
 import org.apache.tapestry.internal.services.ComponentInvocationMap;
@@ -24,6 +25,7 @@
 import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.services.ComponentEventRequestHandler;
 import org.apache.tapestry.services.ComponentEventRequestParameters;
+import org.apache.tapestry.services.ContextValueEncoder;
 
 import java.io.IOException;
 
@@ -42,6 +44,8 @@
 
     private final TestableResponse _response;
 
+    private final ContextValueEncoder _contextValueEncoder;
+
     public ActionLinkInvoker(Registry registry, ComponentInvoker followupInvoker,
                              ComponentInvocationMap componentInvocationMap)
     {
@@ -53,6 +57,7 @@
         _response = _registry.getObject(TestableResponse.class, null);
 
         _componentInvocationMap = componentInvocationMap;
+        _contextValueEncoder = _registry.getService(ContextValueEncoder.class);
 
     }
 
@@ -96,9 +101,9 @@
 
                     actionLinkTarget.getEventType(),
 
-                    invocation.getActivationContext(),
+                    new URLEventContext(_contextValueEncoder, invocation.getActivationContext()),
 
-                    invocation.getContext());
+                    new URLEventContext(_contextValueEncoder, invocation.getContext()));
 
             _componentEventRequestHandler.handle(parameters);
         }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java Sat Feb  2 11:26:57 2008
@@ -14,12 +14,16 @@
 
 package org.apache.tapestry.internal.test;
 
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.internal.URLEventContext;
 import org.apache.tapestry.internal.services.ComponentInvocation;
 import org.apache.tapestry.internal.services.InvocationTarget;
 import org.apache.tapestry.internal.services.PageLinkTarget;
 import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.services.ContextValueEncoder;
 import org.apache.tapestry.services.PageRenderRequestHandler;
+import org.apache.tapestry.services.PageRenderRequestParameters;
 
 import java.io.IOException;
 
@@ -36,12 +40,16 @@
 
     private final TestableResponse _response;
 
+    private final ContextValueEncoder _contextValueEncoder;
+
     public PageLinkInvoker(Registry registry)
     {
         _registry = registry;
+
         _pageRenderRequestHandler = _registry.getService(PageRenderRequestHandler.class);
         _markupWriterFactory = _registry.getService(TestableMarkupWriterFactory.class);
         _response = _registry.getService(TestableResponse.class);
+        _contextValueEncoder = _registry.getService(ContextValueEncoder.class);
     }
 
     /**
@@ -58,7 +66,12 @@
 
             PageLinkTarget pageLinkTarget = (PageLinkTarget) target;
 
-            _pageRenderRequestHandler.handle(pageLinkTarget.getPageName(), invocation.getContext());
+            EventContext activationContext
+                    = new URLEventContext(_contextValueEncoder, invocation.getContext());
+            PageRenderRequestParameters parameters = new PageRenderRequestParameters(pageLinkTarget.getPageName(),
+                                                                                     activationContext);
+
+            _pageRenderRequestHandler.handle(parameters);
 
             return _markupWriterFactory.getLatestMarkupWriter().getDocument();
         }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java Sat Feb  2 11:26:57 2008
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.runtime;
 
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.ioc.internal.util.TapestryException;
 
 /**
@@ -25,7 +26,8 @@
 public class ComponentEventException extends TapestryException
 {
     private final String _eventType;
-    private final Object[] _context;
+
+    private final EventContext _context;
 
     /**
      * @param message   exception message
@@ -34,7 +36,8 @@
      * @param location  location of the component while failed (may be null)
      * @param cause     underlying exception
      */
-    public ComponentEventException(String message, String eventType, Object[] context, Object location, Throwable cause)
+    public ComponentEventException(String message, String eventType, EventContext context, Object location,
+                                   Throwable cause)
     {
         super(message, location, cause);
 
@@ -47,7 +50,7 @@
         return _eventType;
     }
 
-    public Object[] getContext()
+    public EventContext getContext()
     {
         return _context;
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java Sat Feb  2 11:26:57 2008
@@ -14,10 +14,9 @@
 
 package org.apache.tapestry.services;
 
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.ioc.internal.util.Defense;
 
-import java.util.Arrays;
-
 /**
  * Encapsulates all the information that may be provided in a component event request URL.
  */
@@ -27,11 +26,12 @@
     private final String _containingPageName;
     private final String _nestedComponentId;
     private final String _eventType;
-    private final String[] _pageActivationContext;
-    private final String[] _eventContext;
+    private final EventContext _pageActivationContext;
+    private final EventContext _eventContext;
 
     public ComponentEventRequestParameters(String activePageName, String containingPageName, String nestedComponentId,
-                                           String eventType, String[] pageActivationContext, String[] eventContext)
+                                           String eventType, EventContext pageActivationContext,
+                                           EventContext eventContext)
     {
         Defense.notBlank(activePageName, "activePageName");
         Defense.notBlank(containingPageName, "containingPageName");
@@ -59,11 +59,29 @@
 
         if (!_activePageName.equals(that._activePageName)) return false;
         if (!_containingPageName.equals(that._containingPageName)) return false;
-        if (!Arrays.equals(_eventContext, that._eventContext)) return false;
         if (!_eventType.equals(that._eventType)) return false;
         if (!_nestedComponentId.equals(that._nestedComponentId)) return false;
 
-        return Arrays.equals(_pageActivationContext, that._pageActivationContext);
+        if (!isEqual(_eventContext, that._eventContext)) return false;
+
+        return isEqual(_pageActivationContext, that._pageActivationContext);
+    }
+
+    private boolean isEqual(EventContext left, EventContext right)
+    {
+        if (left == right) return true;
+
+        int count = left.getCount();
+
+        if (count != right.getCount()) return false;
+
+        for (int i = 0; i < count; i++)
+        {
+            if (!left.get(Object.class, i).equals(right.get(Object.class, i)))
+                return false;
+        }
+
+        return true;
     }
 
 
@@ -106,8 +124,10 @@
 
     /**
      * The activation context for the <em>active page</em>, possibly empty (but not null).
+     *
+     * @see org.apache.tapestry.ComponentResourcesCommon#triggerContextEvent(String, org.apache.tapestry.EventContext, org.apache.tapestry.ComponentEventCallback)
      */
-    public String[] getPageActivationContext()
+    public EventContext getPageActivationContext()
     {
         return _pageActivationContext;
     }
@@ -115,10 +135,9 @@
     /**
      * The event context information passed in the URL.  Possibly empty (not not null).
      *
-     * @see org.apache.tapestry.ComponentResourcesCommon#triggerEvent(String, Object[],
-     *      org.apache.tapestry.ComponentEventCallback)
+     * @see org.apache.tapestry.ComponentResourcesCommon#triggerContextEvent(String, org.apache.tapestry.EventContext, org.apache.tapestry.ComponentEventCallback)
      */
-    public String[] getEventContext()
+    public EventContext getEventContext()
     {
         return _eventContext;
     }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,43 @@
+// Copyright 2008 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.tapestry.services;
+
+/**
+ * Used to convert values used in event contexts to client string representations and back.
+ *
+ * @See org.apache.tapestry.ValueEncoder
+ * @see org.apache.tapestry.ioc.services.TypeCoercer
+ */
+public interface ContextValueEncoder
+{
+    /**
+     * Converts a context value into a client-side string (that will utltimately be encoded into a URL).
+     *
+     * @param value to convert (may not be null)
+     * @return string representation of the value
+     * @see org.apache.tapestry.ValueEncoder#toClient(Object)
+     */
+    String toClient(Object value);
+
+    /**
+     * Converts a client value back into a server-side object.
+     *
+     * @param requiredType required type to convert the string to
+     * @param clientValue  value obtained from context passed from client
+     * @return the client value converted or coerced into a server value
+     * @see org.apache.tapestry.ValueEncoder#toValue(String)
+     */
+    <T> T toValue(Class<T> requiredType, String clientValue);
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java Sat Feb  2 11:26:57 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -24,9 +24,8 @@
      * Invoked to activate and render a page. The return value of the event handler method(s) for
      * the activate event may result in an action response generator being returned.
      *
-     * @param logicalPageName the logical name of the page to activate and render
-     * @param context         context data, supplied by the page at render time, extracted from the render URL
-     * @param handler         to delegate the invocation to
+     * @param parameters defines the page name and activation context
+     * @param handler    to delegate the invocation to
      */
-    void handle(String logicalPageName, String[] context, PageRenderRequestHandler handler);
+    void handle(PageRenderRequestParameters parameters, PageRenderRequestHandler handler);
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java Sat Feb  2 11:26:57 2008
@@ -28,8 +28,7 @@
      * {@link org.apache.tapestry.services.ComponentEventResultProcessor} may be used to send an alternate response
      * (typically, a redirect).
      *
-     * @param logicalPageName the logical name of the page to activate and render
-     * @param context         context data, supplied by the page at render time, extracted from the render URL
+     * @param parameters defines the page name and activation context
      */
-    void handle(String logicalPageName, String[] context) throws IOException;
+    void handle(PageRenderRequestParameters parameters) throws IOException;
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,49 @@
+// Copyright 2008 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.tapestry.services;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+/**
+ * Used with {@link org.apache.tapestry.services.PageRenderRequestHandler} and
+ * {@link org.apache.tapestry.services.PageRenderRequestFilter} to define
+ * the logical page name and activation context for the request.
+ */
+public class PageRenderRequestParameters
+{
+    private final String _logicalPageName;
+
+    private final EventContext _activationContext;
+
+    public PageRenderRequestParameters(String logicalPageName, EventContext activationContext)
+    {
+        Defense.notBlank(logicalPageName, "logicalPageName");
+        Defense.notNull(activationContext, "activationContext");
+
+        _logicalPageName = logicalPageName;
+        _activationContext = activationContext;
+    }
+
+    public String getLogicalPageName()
+    {
+        return _logicalPageName;
+    }
+
+    public EventContext getActivationContext()
+    {
+        return _activationContext;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Sat Feb  2 11:26:57 2008
@@ -117,6 +117,7 @@
         binder.bind(NullFieldStrategySource.class, NullFieldStrategySourceImpl.class);
         binder.bind(HttpServletRequestFilter.class, IgnoredPathsFilter.class).withId("IgnoredPathsFilter");
         binder.bind(PageResourcesSource.class, PageResourcesSourceImpl.class);
+        binder.bind(ContextValueEncoder.class, ContextValueEncoderImpl.class);
     }
 
     public static Alias build(Logger logger,
@@ -1203,6 +1204,8 @@
 
                                            ComponentClassResolver componentClassResolver,
 
+                                           ContextValueEncoder contextValueEncoder,
+
                                            @Symbol("tapestry.start-page-name")
                                            String startPageName)
     {
@@ -1217,10 +1220,12 @@
 
         configuration.add("Asset", new AssetDispatcher(streamer, aliasManager, resourceCache), "before:PageRender");
 
-        configuration.add("PageRender", new PageRenderDispatcher(componentClassResolver, pageRenderRequestHandler));
+        configuration.add("PageRender", new PageRenderDispatcher(componentClassResolver, pageRenderRequestHandler,
+                                                                 contextValueEncoder));
 
         configuration.add("ComponentEvent",
-                          new ComponentEventDispatcher(componentEventRequestHandler, componentClassResolver),
+                          new ComponentEventDispatcher(componentEventRequestHandler, componentClassResolver,
+                                                       contextValueEncoder),
                           "after:PageRender");
     }
 
@@ -1240,8 +1245,8 @@
     }
 
     /**
-     * Contributes a default object renderer for type Object, plus specialized renderers for {@link Request}, {@link
-     * Location}, {@link ComponentResources}, List, and Object[].
+     * Contributes a default object renderer for type Object, plus specialized renderers for {@link org.apache.tapestry.services.Request}, {@link
+     * org.apache.tapestry.ioc.Location}, {@link org.apache.tapestry.ComponentResources}, {@link org.apache.tapestry.EventContext}, List, and Object[].
      */
     public void contributeObjectRenderer(MappedConfiguration<Class, ObjectRenderer> configuration,
 
@@ -1279,6 +1284,7 @@
         configuration.add(List.class, locator.autobuild(ListRenderer.class));
         configuration.add(Object[].class, locator.autobuild(ObjectArrayRenderer.class));
         configuration.add(ComponentResources.class, locator.autobuild(ComponentResourcesRenderer.class));
+        configuration.add(EventContext.class, locator.autobuild(EventContextRenderer.class));
     }
 
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java Sat Feb  2 11:26:57 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -23,11 +23,19 @@
 public interface ValueEncoderSource
 {
     /**
-     * Creates a value encoder based on the <em>type</em> of the named parameter.
+     * Gets or creates a value encoder based on the <em>type</em> of the named parameter.  ValueEncoders are cached based on type.
      *
-     * @param parameterName the name of the parameter whose type is used to locate a PKE factory
+     * @param parameterName the name of the parameter whose type is used to locate a {@link org.apache.tapestry.services.ValueEncoderFactory}
      * @param resources     the resources of the component, from which parameter and its type are extracted
+     * @return the value encoder, or null if the type of the parameter is not known
+     */
+    ValueEncoder getEncoderForParameter(String parameterName, ComponentResources resources);
+
+    /**
+     * Gets or creates a value encoder for the indicated type.  ValueEncoders are cached.
+     *
+     * @param type type of value to be encoded and decoded
      * @return the value encoder
      */
-    ValueEncoder createEncoder(String parameterName, ComponentResources resources);
+    <T> ValueEncoder<T> getEncoderForType(Class<T> type);
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java Sat Feb  2 11:26:57 2008
@@ -107,7 +107,7 @@
         map.put(PageLinkTarget.class, new PageLinkInvoker(_registry));
         map.put(ActionLinkTarget.class, new ActionLinkInvoker(_registry, this, _invocationMap));
 
-        _invokerRegistry = new StrategyRegistry<ComponentInvoker>(ComponentInvoker.class, map);
+        _invokerRegistry = StrategyRegistry.newInstance(ComponentInvoker.class, map);
     }
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Sat Feb  2 11:26:57 2008
@@ -707,8 +707,8 @@
     }
 
     @SuppressWarnings("unchecked")
-    protected final void train_handleResult(ComponentEventCallback handler, Object result, Component component,
-                                            String methodDescription, boolean abort)
+    protected final void train_handleResult(ComponentEventCallback handler, Object result,
+                                            boolean abort)
     {
         expect(handler.handleResult(result)).andReturn(abort);
     }
@@ -1007,5 +1007,30 @@
     protected final NullFieldStrategy mockNullFieldStrategy()
     {
         return newMock(NullFieldStrategy.class);
+    }
+
+    protected final ValueEncoderSource mockValueEncoderSource()
+    {
+        return newMock(ValueEncoderSource.class);
+    }
+
+    protected final ValueEncoder mockValueEncoder()
+    {
+        return newMock(ValueEncoder.class);
+    }
+
+    protected final void train_toClient(ValueEncoder valueEncoder, Object value, String encoded)
+    {
+        expect(valueEncoder.toClient(value)).andReturn(encoded);
+    }
+
+    protected final void train_getEncoderForType(ValueEncoderSource source, Class type, ValueEncoder valueEncoder)
+    {
+        expect(source.getEncoderForType(type)).andReturn(valueEncoder).atLeastOnce();
+    }
+
+    protected final void train_toValue(ValueEncoder valueEncoder, String clientValue, Object value)
+    {
+        expect(valueEncoder.toValue(clientValue)).andReturn(value);
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java Sat Feb  2 11:26:57 2008
@@ -15,15 +15,26 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.TapestryConstants;
+import org.apache.tapestry.internal.EmptyEventContext;
 import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.URLEventContext;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.services.*;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import java.io.IOException;
 
 public class ComponentEventDispatcherTest extends InternalBaseTestCase
 {
+    private ContextValueEncoder _contextValueEncoder;
+
+    @BeforeClass
+    public void setup()
+    {
+        _contextValueEncoder = getService(ContextValueEncoder.class);
+    }
+
     @Test
     public void no_dot_or_colon_in_path() throws Exception
     {
@@ -35,7 +46,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, null);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, null, null);
 
         assertFalse(dispatcher.dispatch(request, response));
 
@@ -122,11 +133,15 @@
         Response response = mockResponse();
         ComponentClassResolver resolver = mockComponentClassResolver();
 
+
         ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters("mypage", "mypage", "",
                                                                                                  "eventname",
-                                                                                                 new String[]{"alpha",
-                                                                                                              "beta"},
-                                                                                                 new String[0]);
+                                                                                                 new URLEventContext(
+                                                                                                         _contextValueEncoder,
+                                                                                                         new String[]{
+                                                                                                                 "alpha",
+                                                                                                                 "beta"}),
+                                                                                                 new EmptyEventContext());
 
         train_getPath(request, "/mypage:eventname");
 
@@ -140,7 +155,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, _contextValueEncoder);
 
         assertTrue(dispatcher.dispatch(request, response));
 
@@ -157,8 +172,8 @@
 
         ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters("activepage", "mypage",
                                                                                                  "", "eventname",
-                                                                                                 new String[0],
-                                                                                                 new String[0]);
+                                                                                                 new EmptyEventContext(),
+                                                                                                 new EmptyEventContext());
 
         train_getPath(request, "/mypage:eventname");
 
@@ -172,7 +187,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, _contextValueEncoder);
 
         assertTrue(dispatcher.dispatch(request, response));
 
@@ -193,7 +208,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, null);
 
         assertFalse(dispatcher.dispatch(request, response));
 
@@ -212,8 +227,10 @@
                                                                                                  containerPageName,
                                                                                                  nestedComponentId,
                                                                                                  eventType,
-                                                                                                 new String[0],
-                                                                                                 eventContext);
+                                                                                                 new EmptyEventContext(),
+                                                                                                 new URLEventContext(
+                                                                                                         _contextValueEncoder,
+                                                                                                         eventContext));
 
         train_getPath(request, requestPath);
 
@@ -227,7 +244,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, _contextValueEncoder);
 
         assertTrue(dispatcher.dispatch(request, response));
 



Mime
View raw message