Author: hlship
Date: Tue Feb 23 20:36:59 2010
New Revision: 915507

URL: http://svn.apache.org/viewvc?rev=915507&view=rev
Log:
TAP5-961: ComponentEventLinkEncoderMethodAdvice#rewriteIfNeeded drops 
parameters when rewriting links

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java
   (with props)
Removed:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventLinkEncoderMethodAdvice.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/TestableRequestImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/DelegatingRequest.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java?rev=915507&r1=915506&r2=915507&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RequestImpl.java
 Tue Feb 23 20:36:59 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -26,8 +26,8 @@
 import java.util.Locale;
 
 /**
- * Basic implementation of {...@link org.apache.tapestry5.services.Request} 
that wraps around an {...@link
- * javax.servlet.http.HttpServletRequest}.
+ * Basic implementation of {...@link org.apache.tapestry5.services.Request} 
that wraps around an
+ * {...@link javax.servlet.http.HttpServletRequest}.
  */
 public class RequestImpl implements Request
 {
@@ -45,8 +45,7 @@
 
     private Session session;
 
-    public RequestImpl(HttpServletRequest request, String requestEncoding,
-                       SessionPersistedObjectAnalyzer analyzer)
+    public RequestImpl(HttpServletRequest request, String requestEncoding, 
SessionPersistedObjectAnalyzer analyzer)
     {
         this.request = request;
         this.requestEncoding = requestEncoding;
@@ -88,7 +87,8 @@
     {
         String pathInfo = request.getPathInfo();
 
-        if (pathInfo == null) return request.getServletPath();
+        if (pathInfo == null)
+            return request.getServletPath();
 
         // Websphere 6.1 is a bit wonky (see TAPESTRY-1713), and tends to 
return the empty string
         // for the servlet path, and return the true path in pathInfo.
@@ -113,7 +113,8 @@
             }
         }
 
-        if (!create && session != null && session.isInvalidated()) return null;
+        if (!create && session != null && session.isInvalidated())
+            return null;
 
         return session;
     }
@@ -130,7 +131,8 @@
 
     private void setupEncoding()
     {
-        if (encodingSet) return;
+        if (encodingSet)
+            return;
 
         try
         {
@@ -144,7 +146,6 @@
         encodingSet = true;
     }
 
-
     public boolean isXHR()
     {
         return 
XML_HTTP_REQUEST.equals(request.getHeader(REQUESTED_WITH_HEADER));
@@ -179,4 +180,10 @@
     {
         return request.getServerName();
     }
+
+    public int getLocalPort()
+    {
+        return request.getLocalPort();
+    }
+
 }

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java?rev=915507&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java
 Tue Feb 23 20:36:59 2010
@@ -0,0 +1,165 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.services;
+
+import org.apache.tapestry5.Link;
+import org.apache.tapestry5.services.ComponentEventLinkEncoder;
+import org.apache.tapestry5.services.ComponentEventRequestParameters;
+import org.apache.tapestry5.services.PageRenderRequestParameters;
+import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.URLRewriter;
+import org.apache.tapestry5.urlrewriter.SimpleRequestWrapper;
+import org.apache.tapestry5.urlrewriter.URLRewriteContext;
+
+/**
+ * An intercepter for the {...@link ComponentEventLinkEncoder} service that is 
put into use when there
+ * {...@linkplain URLRewriter#hasLinkRules() URL link rewrite rules}.
+ * 
+ * @since 5.2.0
+ */
+public class URLRewriterLinkEncoderInterceptor implements 
ComponentEventLinkEncoder
+{
+    private final URLRewriter urlRewriter;
+
+    private final Request request;
+
+    private final Response response;
+
+    private final ComponentEventLinkEncoder delegate;
+
+    public URLRewriterLinkEncoderInterceptor(URLRewriter urlRewriter, Request 
request, Response response,
+            ComponentEventLinkEncoder delegate)
+    {
+        this.urlRewriter = urlRewriter;
+        this.request = request;
+        this.response = response;
+        this.delegate = delegate;
+    }
+
+    public Link createComponentEventLink(final ComponentEventRequestParameters 
parameters, boolean forForm)
+    {
+        Link standardLink = delegate.createComponentEventLink(parameters, 
forForm);
+
+        URLRewriteContext rewriteContext = new URLRewriteContext()
+        {
+            public boolean isIncoming()
+            {
+                return false;
+            }
+
+            public PageRenderRequestParameters getPageParameters()
+            {
+                return null;
+            }
+
+            public ComponentEventRequestParameters 
getComponentEventParameters()
+            {
+                return parameters;
+            }
+        };
+
+        return rewriteIfNeeded(standardLink, rewriteContext, forForm);
+    }
+
+    public Link createPageRenderLink(final PageRenderRequestParameters 
parameters)
+    {
+        Link standardLink = delegate.createPageRenderLink(parameters);
+
+        URLRewriteContext rewriteContext = new URLRewriteContext()
+        {
+            public boolean isIncoming()
+            {
+                return false;
+            }
+
+            public PageRenderRequestParameters getPageParameters()
+            {
+                return parameters;
+            }
+
+            public ComponentEventRequestParameters 
getComponentEventParameters()
+            {
+                return null;
+            }
+        };
+
+        return rewriteIfNeeded(standardLink, rewriteContext, false);
+    }
+
+    public ComponentEventRequestParameters decodeComponentEventRequest(Request 
request)
+    {
+        return delegate.decodeComponentEventRequest(request);
+    }
+
+    public PageRenderRequestParameters decodePageRenderRequest(Request request)
+    {
+        return delegate.decodePageRenderRequest(request);
+    }
+
+    private Link rewriteIfNeeded(Link link, URLRewriteContext context, boolean 
forForm)
+    {
+        SimpleRequestWrapper fakeRequest = new SimpleRequestWrapper(request, 
link.toAbsoluteURI());
+
+        Request rewritten = urlRewriter.processLink(fakeRequest, context);
+
+        // if the original request is equal to the rewritten one, no
+        // rewriting is needed
+        if (fakeRequest != rewritten)
+        {
+            String originalServerName = request.getServerName();
+
+            String rewrittenServerName = rewritten.getServerName();
+
+            boolean absolute = originalServerName.equals(rewrittenServerName) 
== false;
+
+            String newPath = rewritten.getPath();
+
+            String newUrl = absolute ? fullUrl(rewritten) : newPath;
+
+            Link replacement = new LinkImpl(newUrl, false, forForm, response, 
null);
+
+            copyParameters(link, replacement);
+
+            return replacement;
+        }
+
+        return link;
+    }
+
+    private void copyParameters(Link link, Link replacement)
+    {
+        for (String name : link.getParameterNames())
+        {
+            replacement.addParameter(name, link.getParameterValue(name));
+        }
+    }
+
+    private String fullUrl(Request request)
+    {
+
+        String protocol = request.isSecure() ? "https://"; : "http://";;
+
+        int localPort = request.getLocalPort();
+
+        String port = localPort == 80 ? "" : ":" + localPort;
+
+        String path = request.getPath();
+        String contextPath = request.getContextPath();
+
+        return protocol + request.getServerName() + port + contextPath + path;
+    }
+
+}

Propchange: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/TestableRequestImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/TestableRequestImpl.java?rev=915507&r1=915506&r2=915507&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/TestableRequestImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/TestableRequestImpl.java
 Tue Feb 23 20:36:59 2010
@@ -1,10 +1,10 @@
-// Copyright 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2007, 2008, 2009, 2010 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -136,10 +136,12 @@
     {
         Object value = parameters.get(name);
 
-        if (value == null) return null;
+        if (value == null)
+            return null;
 
         if (value instanceof String)
-            return new String[] { (String) value };
+            return new String[]
+            { (String) value };
 
         List list = (List) value;
 
@@ -160,7 +162,8 @@
     {
         Object value = parameters.get(name);
 
-        if (value == null || value instanceof String) return (String) value;
+        if (value == null || value instanceof String)
+            return (String) value;
 
         List<String> list = (List<String>) value;
 
@@ -169,9 +172,11 @@
 
     public Session getSession(boolean create)
     {
-        if (!create) return session;
+        if (!create)
+            return session;
 
-        if (session == null) session = new PageTesterSession();
+        if (session == null)
+            session = new PageTesterSession();
 
         return session;
     }
@@ -226,4 +231,13 @@
     {
         return "POST";
     }
+
+    /**
+     * Always returns 80.
+     */
+    public int getLocalPort()
+    {
+        return 80;
+    }
+
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/DelegatingRequest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/DelegatingRequest.java?rev=915507&r1=915506&r2=915507&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/DelegatingRequest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/DelegatingRequest.java
 Tue Feb 23 20:36:59 2010
@@ -1,3 +1,17 @@
+// Copyright 2009, 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package org.apache.tapestry5.services;
 
 import java.util.List;
@@ -8,7 +22,7 @@
 import org.apache.tapestry5.services.Session;
 
 /**
- * Class that wraps an {...@linkplain Request}, delegating all its methods. 
+ * Class that wraps an {...@linkplain Request}, delegating all its methods.
  * 
  * @since 5.1.0.1
  */
@@ -20,13 +34,15 @@
     /**
      * No-arg constructor. It should only be used for testing purposes.
      */
-    public DelegatingRequest() {
+    public DelegatingRequest()
+    {
     }
-    
+
     /**
      * Constructor that receives a {...@linkplain Request}.
      * 
-     * @param request a {...@link Request}. It cannot be null.
+     * @param request
+     *            a {...@link Request}. It cannot be null.
      */
     public DelegatingRequest(Request request)
     {
@@ -35,7 +51,9 @@
 
     /**
      * Sets the delegate request.
-     * @param request a {...@link Request}. It cannot be null.
+     * 
+     * @param request
+     *            a {...@link Request}. It cannot be null.
      */
     public void setRequest(Request request)
     {
@@ -128,4 +146,9 @@
         request.setAttribute(name, value);
     }
 
-}
\ No newline at end of file
+    public int getLocalPort()
+    {
+        return request.getLocalPort();
+    }
+
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java?rev=915507&r1=915506&r2=915507&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Request.java
 Tue Feb 23 20:36:59 2010
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -30,8 +30,9 @@
     /**
      * Gets the {...@link Session}. If create is false and the session has not 
be created previously, returns null. Also,
      * if the session is invalided and create is false, returns null.
-     *
-     * @param create true to force the creation of the session
+     * 
+     * @param create
+     *            true to force the creation of the session
      * @return the session (or null if create is false the session has not 
been previously created)
      */
     Session getSession(boolean create);
@@ -76,19 +77,21 @@
 
     /**
      * Returns the value of the specified request header as a 
<code>long</code> value that represents a
-     * <code>Date</code> object. Use this method with headers that contain 
dates, such as
-     * <code>If-Modified-Since</code>.
+     * <code>Date</code> object. Use this method with headers that contain 
dates, such as <code>If-Modified-Since</code>
+     * .
      * <p/>
      * The date is returned as the number of milliseconds since January 1, 
1970 GMT. The header name is case
      * insensitive.
      * <p/>
      * If the request did not have a header of the specified name, this method 
returns -1. If the header can't be
      * converted to a date, the method throws an 
<code>IllegalArgumentException</code>.
-     *
-     * @param name a <code>String</code> specifying the name of the header
+     * 
+     * @param name
+     *            a <code>String</code> specifying the name of the header
      * @return a <code>long</code> value representing the date specified in 
the header expressed as the number of
      *         milliseconds since January 1, 1970 GMT, or -1 if the named 
header was not included with the reqest
-     * @throws IllegalArgumentException If the header value can't be converted 
to a date
+     * @throws IllegalArgumentException
+     *             If the header value can't be converted to a date
      */
     long getDateHeader(String name);
 
@@ -99,17 +102,17 @@
 
     /**
      * Returns true if the request originated on the client using 
XmlHttpRequest (the core of any Ajax behavior). Ajax
-     * action requests may behave quite differently than ordinary, page-based 
requests.  This implementation currently
+     * action requests may behave quite differently than ordinary, page-based 
requests. This implementation currently
      * depends on the client side setting a header: 
<strong>X-Requested-With=XMLHttpRequest</strong> (this is what
      * Prototype does).
-     *
+     * 
      * @return true if the request has an XmlHttpRequest origin
      */
     boolean isXHR();
 
     /**
      * Returns a boolean indicating whether this request was made using a 
secure channel, such as HTTPS.
-     *
+     * 
      * @return a boolean indicating if the request was made using a secure 
channel
      */
     public boolean isSecure();
@@ -117,26 +120,27 @@
     /**
      * Returns the host name of the server to which the request was sent. It 
is the value of the part before ":" in the
      * <code>Host</code> header, if any, or the resolved server name, or the 
server IP address.
-     *
+     * 
      * @return the name of the server
      */
     public String getServerName();
 
     /**
      * Checks whether the requested session ID is still valid.
-     *
+     * 
      * @return true if the request included a session id that is still active, 
false if the included session id has
      *         expired
      */
     boolean isRequestedSessionIdValid();
 
-
     /**
      * Returns the value of the named attribute as an <code>Object</code>, or 
<code>null</code> if no attribute of the
-     * given name exists.  Because this method is a wrapper around {...@link 
javax.servlet.ServletRequest#getAttribute(String)},
+     * given name exists. Because this method is a wrapper around
+     * {...@link javax.servlet.ServletRequest#getAttribute(String)},
      * it is case <em>sensitive</em> (unlike most of Tapestry).
-     *
-     * @param name a <code>String</code> specifying the name of the attribute
+     * 
+     * @param name
+     *            a <code>String</code> specifying the name of the attribute
      * @return an <code>Object</code> containing the value of the attribute, 
or <code>null</code> if the attribute does
      *         not exist
      */
@@ -145,16 +149,27 @@
     /**
      * Stores an attribute in this request. Attributes are reset between 
requests (and remember that in Tapestry, there
      * is usually two requests per operation: the action request that 
redirects to a render request).
-     *
-     * @param name  a <code>String</code> specifying the name of the attribute
-     * @param value the <code>Object</code> to be stored, or null to remove 
the attribute
+     * 
+     * @param name
+     *            a <code>String</code> specifying the name of the attribute
+     * @param value
+     *            the <code>Object</code> to be stored, or null to remove the 
attribute
      */
     void setAttribute(String name, Object value);
 
     /**
      * Returns the name of the HTTP method with which this request was made, 
for example, GET, POST, or PUT.
-     *
+     * 
      * @return a string specifying the name of the method with which this 
request was made
      */
     public String getMethod();
+
+    /**
+     * Returns the Internet Protocol (IP) port number of the interface
+     * on which the request was received.
+     * 
+     * @return an integer specifying the port number
+     * @since 5.2.0
+     */
+    public int getLocalPort();
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=915507&r1=915506&r2=915507&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
 Tue Feb 23 20:36:59 2010
@@ -607,7 +607,7 @@
         // annotated will
         // be converted to clear out at the end of the request.
 
-        configuration.addInstance("UnclaimedField",  
UnclaimedFieldWorker.class, "after:*");
+        configuration.addInstance("UnclaimedField", 
UnclaimedFieldWorker.class, "after:*");
 
         configuration.add("PageActivationContext", new 
PageActivationContextWorker(), "before:OnEvent");
 
@@ -2722,34 +2722,13 @@
      * @since 5.1.0.2
      */
     public static ComponentEventLinkEncoder 
decorateComponentEventLinkEncoder(ComponentEventLinkEncoder encoder,
-            URLRewriter urlRewriter, Request request, HttpServletRequest 
httpServletRequest, Response response,
-            AspectDecorator aspectDecorator) throws Exception
+            URLRewriter urlRewriter, Request request, Response response)
     {
-
         // no rules, no link rewriting.
-        if (!urlRewriter.hasLinkRules()) { return null; }
-
-        ComponentEventLinkEncoderMethodAdvice pageLinkAdvice = new 
ComponentEventLinkEncoderMethodAdvice(urlRewriter,
-                request, httpServletRequest, response, true);
-
-        ComponentEventLinkEncoderMethodAdvice eventLinkAdvice = new 
ComponentEventLinkEncoderMethodAdvice(urlRewriter,
-                request, httpServletRequest, response, false);
-
-        Class<ComponentEventLinkEncoder> clasz = 
ComponentEventLinkEncoder.class;
-
-        Method createPageRenderLink = clasz.getMethod("createPageRenderLink", 
PageRenderRequestParameters.class);
-
-        Method createComponentEventLink = 
clasz.getMethod("createComponentEventLink",
-                ComponentEventRequestParameters.class, boolean.class);
-
-        final AspectInterceptorBuilder<ComponentEventLinkEncoder> builder = 
aspectDecorator.createBuilder(clasz,
-                encoder, "Link rewriting");
-
-        builder.adviseMethod(createComponentEventLink, eventLinkAdvice);
-        builder.adviseMethod(createPageRenderLink, pageLinkAdvice);
-
-        return builder.build();
+        if (!urlRewriter.hasLinkRules())
+            return null;
 
+        return new URLRewriterLinkEncoderInterceptor(urlRewriter, request, 
response, encoder);
     }
 
     /**


Reply via email to