Author: hlship
Date: Sun Mar  2 15:13:54 2008
New Revision: 632867

URL: http://svn.apache.org/viewvc?rev=632867&view=rev
Log:
TAPESTRY-1605: The request encoding (for component action requests) occurs too 
late; after query parameters of the request have been accessed, which prevents 
the proper request encoding from being used

Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.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/LinkFactoryImpl.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/services/TapestryModule.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/LinkFactoryImplTest.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java?rev=632867&r1=632866&r2=632867&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
 Sun Mar  2 15:13:54 2008
@@ -48,11 +48,11 @@
     public static final String PAGE_CONTEXT_NAME = "t:ac";
 
     /**
-     * The name of a query parameter that stores the active page (used in 
action links when the page containing the
-     * component is not the same as the page that was rendering).
+     * The name of a query parameter that stores the containing page (used in 
action links when the page containing the
+     * component is not the same as the page that was rendering). The active 
page (the page which initiated the render)
+     * is encoded into the URL, and the containing page is tacked on as this 
query parameter.
      */
-    public static final String ACTIVE_PAGE_NAME = "t:ap";
-
+    public static final String CONTAINER_PAGE_NAME = "t:cp";
 
     public static final String OBJECT_RENDER_DIV_SECTION = 
"t-env-data-section";
 

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=632867&r1=632866&r2=632867&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
 Sun Mar  2 15:13:54 2008
@@ -51,15 +51,19 @@
 
     private final ContextValueEncoder _contextValueEncoder;
 
+    private final RequestEncodingInitializer _requestEncodingInitializer;
+
     private final EventContext _emptyContext = new EmptyEventContext();
 
-    public ComponentEventDispatcher(ComponentEventRequestHandler 
componentEventRequestHandler,
+    public ComponentEventDispatcher(@Traditional ComponentEventRequestHandler 
componentEventRequestHandler,
                                     ComponentClassResolver 
componentClassResolver,
-                                    ContextValueEncoder contextValueEncoder)
+                                    ContextValueEncoder contextValueEncoder,
+                                    RequestEncodingInitializer 
requestEncodingInitializer)
     {
         _componentEventRequestHandler = componentEventRequestHandler;
         _componentClassResolver = componentClassResolver;
         _contextValueEncoder = contextValueEncoder;
+        _requestEncodingInitializer = requestEncodingInitializer;
     }
 
     // A beast that recognizes all the elements of a path in a single go.
@@ -97,7 +101,7 @@
 
         if (!matcher.matches()) return false;
 
-        String containingPageName = matcher.group(LOGICAL_PAGE_NAME);
+        String activePageName = matcher.group(LOGICAL_PAGE_NAME);
 
         String nestedComponentId = matcher.group(NESTED_ID);
 
@@ -105,10 +109,15 @@
 
         if (nestedComponentId == null && eventType == null) return false;
 
-        if (!_componentClassResolver.isPageName(containingPageName)) return 
false;
+        if (!_componentClassResolver.isPageName(activePageName)) return false;
 
         EventContext eventContext = decodeContext(matcher.group(CONTEXT));
 
+        // Initialize the request encoding BEFORE accessing any query 
parameters
+        // (TAPESTRY-1605)
+
+        _requestEncodingInitializer.initializeRequestEncoding(activePageName);
+        
         EventContext activationContext = 
decodeContext(request.getParameter(InternalConstants.PAGE_CONTEXT_NAME));
 
         // The event type is often omitted, and defaults to "action".
@@ -117,10 +126,9 @@
 
         if (nestedComponentId == null) nestedComponentId = "";
 
-        String activePageName = 
request.getParameter(InternalConstants.ACTIVE_PAGE_NAME);
-
-        if (activePageName == null) activePageName = containingPageName;
+        String containingPageName = 
request.getParameter(InternalConstants.CONTAINER_PAGE_NAME);
 
+        if (containingPageName == null) containingPageName = activePageName;
 
         ComponentEventRequestParameters parameters = new 
ComponentEventRequestParameters(activePageName,
                                                                                
          containingPageName,

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=632867&r1=632866&r2=632867&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
 Sun Mar  2 15:13:54 2008
@@ -124,17 +124,15 @@
         notNull(page, "page");
         notBlank(eventType, "action");
 
-        String logicalPageName = page.getLogicalName();
-
-        ActionLinkTarget target = new ActionLinkTarget(eventType, 
logicalPageName, nestedId);
-
-        String[] contextStrings = toContextStrings(context);
-
         Page activePage = _pageRenderQueue.getRenderingPage();
 
         // See TAPESTRY-2184
         if (activePage == null) activePage = page;
 
+        ActionLinkTarget target = new ActionLinkTarget(eventType, 
activePage.getLogicalName(), nestedId);
+
+        String[] contextStrings = toContextStrings(context);
+
         String[] activationContext = 
collectActivationContextForPage(activePage);
 
         ComponentInvocation invocation = new ComponentInvocationImpl(target, 
contextStrings, activationContext);
@@ -147,7 +145,7 @@
         // need to differentiate that.
 
         if (activePage != page)
-            link.addParameter(InternalConstants.ACTIVE_PAGE_NAME, 
activePage.getLogicalName().toLowerCase());
+            link.addParameter(InternalConstants.CONTAINER_PAGE_NAME, 
page.getLogicalName().toLowerCase());
 
         // Now see if the page has an activation context.
 
@@ -253,16 +251,17 @@
 
         String[] result = new String[context.length];
 
-        for (int i = 0; i < context.length; i++)    {
+        for (int i = 0; i < context.length; i++)
+        {
 
             Object value = context[i];
 
             String encoded = value == null ? null : 
_contextValueEncoder.toClient(value);
 
             if (InternalUtils.isBlank(encoded))
-            throw new 
RuntimeException(ServicesMessages.contextValueMayNotBeNull());
+                throw new 
RuntimeException(ServicesMessages.contextValueMayNotBeNull());
 
-            result[i]= encoded;
+            result[i] = encoded;
         }
 
         return result;

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=632867&r1=632866&r2=632867&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
 Sun Mar  2 15:13:54 2008
@@ -16,6 +16,8 @@
 
 import org.apache.tapestry.EventContext;
 import org.apache.tapestry.internal.EmptyEventContext;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.annotations.Symbol;
 import org.apache.tapestry.services.*;
 
 import java.io.IOException;
@@ -37,7 +39,11 @@
     private final PageRenderRequestParameters _parameters;
 
     public RootPathDispatcher(ComponentClassResolver componentClassResolver,
-                              PageRenderRequestHandler handler, String 
startPageName)
+
+                              PageRenderRequestHandler handler,
+
+                              @Inject @Symbol("tapestry.start-page-name")
+                              String startPageName)
     {
         _componentClassResolver = componentClassResolver;
         _handler = handler;

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=632867&r1=632866&r2=632867&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
 Sun Mar  2 15:13:54 2008
@@ -1187,44 +1187,27 @@
      * ComponentEventRequestHandler}</dd> </dl>
      */
     public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> 
configuration,
-
-                                           ClasspathAssetAliasManager 
aliasManager,
-
-                                           ResourceCache resourceCache,
-
-                                           ResourceStreamer streamer,
-
-                                           PageRenderRequestHandler 
pageRenderRequestHandler,
-
-                                           @Traditional 
ComponentEventRequestHandler componentEventRequestHandler,
-
-                                           ComponentClassResolver 
componentClassResolver,
-
-                                           ContextValueEncoder 
contextValueEncoder,
-
-                                           @Symbol("tapestry.start-page-name")
-                                           String startPageName)
+                                           ObjectLocator locator)
     {
         // Looks for the root path and renders the start page. This is 
maintained for compatibility
         // with earlier versions of Tapestry 5, it is recommended that an 
Index page be used instead.
 
         configuration.add("RootPath",
-                          new RootPathDispatcher(componentClassResolver, 
pageRenderRequestHandler, startPageName),
+                          locator.autobuild(RootPathDispatcher.class),
                           "before:Asset");
 
         // This goes first because an asset to be streamed may have an file 
extension, such as
         // ".html", that will confuse the later dispatchers.
 
-        configuration.add("Asset", new AssetDispatcher(streamer, aliasManager, 
resourceCache), "before:ComponentEvent");
+        configuration.add("Asset",
+                          locator.autobuild(AssetDispatcher.class), 
"before:ComponentEvent");
 
 
-        configuration.add("ComponentEvent",
-                          new 
ComponentEventDispatcher(componentEventRequestHandler, componentClassResolver,
-                                                       contextValueEncoder),
+        configuration.add("ComponentEvent", 
locator.autobuild(ComponentEventDispatcher.class),
                           "before:PageRender");
 
-        configuration.add("PageRender", new 
PageRenderDispatcher(componentClassResolver, pageRenderRequestHandler,
-                                                                 
contextValueEncoder));
+        configuration.add("PageRender",
+                          locator.autobuild(PageRenderDispatcher.class));
     }
 
     /**
@@ -2088,7 +2071,7 @@
     }
 
     /**
-     * Contributes filters: <dl> <dt>SetRequestEncode</dt> <dd>Sets the 
request encoding (before:*)</dd> <dt>Ajax</dt>
+     * Contributes filters: <dl> <dt>Ajax</dt>
      * <dd>Determines if the request is Ajax oriented, and redirects to an 
alternative handler if so</dd>
      * <dt>ImmediateRender</dt> <dd>When [EMAIL PROTECTED] 
org.apache.tapestry.TapestryConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS_SYMBOL
      * immediate action response rendering} is enabled, generates the markup 
response (instead of a page redirect
@@ -2096,22 +2079,10 @@
      * accesses a secure page</dd></dl>
      */
     public void 
contributeComponentEventRequestHandler(OrderedConfiguration<ComponentEventRequestFilter>
 configuration,
-                                                       final 
RequestEncodingInitializer encodingInitializer,
                                                        final 
RequestSecurityManager requestSecurityManager,
                                                        @Ajax 
ComponentEventRequestHandler ajaxHandler,
                                                        ObjectLocator locator)
     {
-        ComponentEventRequestFilter requestEncodingFilter = new 
ComponentEventRequestFilter()
-        {
-            public void handle(ComponentEventRequestParameters parameters, 
ComponentEventRequestHandler handler)
-                    throws IOException
-            {
-                
encodingInitializer.initializeRequestEncoding(parameters.getActivePageName());
-
-                handler.handle(parameters);
-            }
-        };
-
         ComponentEventRequestFilter secureFilter = new 
ComponentEventRequestFilter()
         {
             public void handle(ComponentEventRequestParameters parameters, 
ComponentEventRequestHandler handler)
@@ -2122,8 +2093,6 @@
                 handler.handle(parameters);
             }
         };
-
-        configuration.add("SetRequestEncoding", requestEncodingFilter, 
"before:*");
 
         configuration.add("Ajax", new AjaxFilter(_request, ajaxHandler));
 

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=632867&r1=632866&r2=632867&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
 Sun Mar  2 15:13:54 2008
@@ -41,18 +41,24 @@
         ComponentEventRequestHandler handler = 
newComponentEventRequestHandler();
         Request request = mockRequest();
         Response response = mockResponse();
+        RequestEncodingInitializer requestEncodingInitializer = 
mockRequestEncodingInitializer();
 
         train_getPath(request, "/foo/bar/baz");
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, null, 
null);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, null, 
null, requestEncodingInitializer);
 
         assertFalse(dispatcher.dispatch(request, response));
 
         verify();
     }
 
+    protected final RequestEncodingInitializer mockRequestEncodingInitializer()
+    {
+        return newMock(RequestEncodingInitializer.class);
+    }
+
     protected final ComponentEventRequestHandler 
newComponentEventRequestHandler()
     {
         return newMock(ComponentEventRequestHandler.class);
@@ -132,15 +138,16 @@
         Request request = mockRequest();
         Response response = mockResponse();
         ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = 
mockRequestEncodingInitializer();
 
 
         ComponentEventRequestParameters expectedParameters = new 
ComponentEventRequestParameters("mypage", "mypage", "",
                                                                                
                  "eventname",
                                                                                
                  new URLEventContext(
                                                                                
                          _contextValueEncoder,
-                                                                               
                          new String[]{
+                                                                               
                          new String[] {
                                                                                
                                  "alpha",
-                                                                               
                                  "beta"}),
+                                                                               
                                  "beta" }),
                                                                                
                  new EmptyEventContext());
 
         train_getPath(request, "/mypage:eventname");
@@ -149,13 +156,16 @@
 
         train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, 
"alpha/beta");
 
-        train_getParameter(request, InternalConstants.ACTIVE_PAGE_NAME, null);
+        train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, 
null);
+
+        requestEncodingInitializer.initializeRequestEncoding("mypage");
 
         handler.handle(expectedParameters);
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, _contextValueEncoder);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, _contextValueEncoder,
+                                                             
requestEncodingInitializer);
 
         assertTrue(dispatcher.dispatch(request, response));
 
@@ -169,25 +179,29 @@
         Request request = mockRequest();
         Response response = mockResponse();
         ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = 
mockRequestEncodingInitializer();
 
         ComponentEventRequestParameters expectedParameters = new 
ComponentEventRequestParameters("activepage", "mypage",
                                                                                
                  "", "eventname",
                                                                                
                  new EmptyEventContext(),
                                                                                
                  new EmptyEventContext());
 
-        train_getPath(request, "/mypage:eventname");
+        train_getPath(request, "/activepage:eventname");
 
-        train_isPageName(resolver, "mypage", true);
+        train_isPageName(resolver, "activepage", true);
+
+        requestEncodingInitializer.initializeRequestEncoding("activepage");
 
         train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null);
 
-        train_getParameter(request, InternalConstants.ACTIVE_PAGE_NAME, 
"activepage");
+        train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, 
"mypage");
 
         handler.handle(expectedParameters);
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, _contextValueEncoder);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, _contextValueEncoder,
+                                                             
requestEncodingInitializer);
 
         assertTrue(dispatcher.dispatch(request, response));
 
@@ -201,6 +215,7 @@
         Request request = mockRequest();
         Response response = mockResponse();
         ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = 
mockRequestEncodingInitializer();
 
         train_getPath(request, "/mypage.foo");
 
@@ -208,7 +223,7 @@
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, null);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, null, requestEncodingInitializer);
 
         assertFalse(dispatcher.dispatch(request, response));
 
@@ -222,6 +237,7 @@
         Request request = mockRequest();
         Response response = mockResponse();
         ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = 
mockRequestEncodingInitializer();
 
         ComponentEventRequestParameters expectedParameters = new 
ComponentEventRequestParameters(containerPageName,
                                                                                
                  containerPageName,
@@ -238,13 +254,16 @@
 
         train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null);
 
-        train_getParameter(request, InternalConstants.ACTIVE_PAGE_NAME, null);
+        train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, 
null);
 
+        
requestEncodingInitializer.initializeRequestEncoding(containerPageName);
+        
         handler.handle(expectedParameters);
 
         replay();
 
-        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, _contextValueEncoder);
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, 
resolver, _contextValueEncoder,
+                                                             
requestEncodingInitializer);
 
         assertTrue(dispatcher.dispatch(request, response));
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java?rev=632867&r1=632866&r2=632867&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
 Sun Mar  2 15:13:54 2008
@@ -591,7 +591,7 @@
 
         train_getBaseURL(securityManager, activePage, "http://example.org";);
 
-        train_encodeURL(response, 
"http://example.org/mypage:myaction?t:ac=foo/bar&t:ap=activepage";, ENCODED);
+        train_encodeURL(response, 
"http://example.org/activepage:myaction?t:ac=foo/bar&t:cp=mypage";, ENCODED);
 
         replay();
 


Reply via email to