tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From robertdzeig...@apache.org
Subject svn commit: r763830 - in /tapestry/tapestry5/trunk: src/site/apt/ src/site/apt/guide/ tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ tapestry-core/src/main/java/org/apache/tapestry5/services/ tapestry-core/src/main/java/org/apache/...
Date Thu, 09 Apr 2009 22:26:10 GMT
Author: robertdzeigler
Date: Thu Apr  9 22:26:09 2009
New Revision: 763830

URL: http://svn.apache.org/viewvc?rev=763830&view=rev
Log:
TAP5-612: URLRewriting should distinguish between incoming and outgoing requests

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterImpl.java
      - copied, changed from r760774, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterServiceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/URLRewriter.java
      - copied, changed from r760774, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterService.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/RewriteRuleApplicability.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriteContext.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteSuccess2.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteWithContext.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteSuccess2.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteWithContext.java
Removed:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterService.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterServiceImpl.java
Modified:
    tapestry/tapestry5/trunk/src/site/apt/guide/url-rewriting.apt
    tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventLinkEncoderMethodAdvice.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriterRule.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/services/AppModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilterTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/urlrewriter/IntegrationTests.java

Modified: tapestry/tapestry5/trunk/src/site/apt/guide/url-rewriting.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/url-rewriting.apt?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/guide/url-rewriting.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/guide/url-rewriting.apt Thu Apr  9 22:26:09 2009
@@ -4,11 +4,11 @@
  
 Tapestry URL Rewriting Support
  
-  Since 5.1.0.1, Tapestry has some basic support for URL rewriting. Incoming
-  requests and links generated by Tapestry itself can be rewritten using exactly
-  the same API. It is based in
+  Since 5.1.0.1, Tapestry has basic support for URL rewriting. Incoming
+  requests and links generated by Tapestry can be rewritten using exactly
+  the same API. It is based on
   a chain of <<<URLRewriterRule>>> interfaces. These rules are executed before
-  all the Tapestry request handling, so it does not even know that the received
+  all other Tapestry request handling, so it does not even know that the received
   request is not the original one.
    
   Each URL rewriter rule, in its
@@ -16,7 +16,7 @@
   effectively rewriting it, or returning the received request unchanged,
   meaning that this rule does not apply to that request.
   
-  To create new <<<Request>>>s easier, Tapestry provides the 
+  To create facilitate <<<Request>>> creation, Tapestry provides the
   <<<SimpleRequestWrapper>>> class. It wraps an <<<Request>>>, delegating all
   methods except <<<getPath()>>> and <<<getServerName()>>>. More request 
   wrappers may be added in the future on demand.
@@ -24,22 +24,22 @@
 Configuration
 
   Tapestry's URL rewriting support is configured by Tapestry-Ioc through contribution
-  of <<<URLRewriterRule>>>s to the <<<URLRewriterService>>> service.
+  of <<<URLRewriterRule>>>s to the <<<URLRewriter>>> service.
   The following example is part of the Tapestry's tests.
   
 Simple example of rule chaining 
 
-  This example just rewrites all requests to <<</struts>>> to <<</tapestry>>>.
+  This example just rewrites all incoming requests to <<</struts>>> to <<</tapestry>>>.
   In your <<<AppModule>>> or any other Tapestry-IoC module class: 
   
 +-----------------------------------------------------------------------+
 
-public static void contributeURLRewriterService(OrderedConfiguration<URLRewriterRule> configuration) 
+public static void contributeURLRewriter(OrderedConfiguration<URLRewriterRule> configuration)
 {
     
     URLRewriterRule rule = new URLRewriterRule() {
 
-        public Request process(Request request)
+        public Request process(Request request, URLRewriteContext context)
         {
             final String path = request.getPath();
             if (path.equals("/struts"))
@@ -50,6 +50,11 @@
             return request;
             
         }
+
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.INBOUND;
+        }
         
     };
     
@@ -63,12 +68,13 @@
   
 +-----------------------------------------------------------------------+
 
-public static void contributeURLRewriterService(OrderedConfiguration<URLRewriterRule> configuration) 
+public static void contributeURLRewriter(OrderedConfiguration<URLRewriterRule> configuration)
 {
     
-    URLRewriterRule rule1 = new URLRewriterRule() {
+    URLRewriterRule rule1 = new URLRewriterRule()
+    {
 
-        public Request process(Request request)
+        public Request process(Request request, URLRewriteContext context)
         {
             final String path = request.getPath();
             if (path.equals("/struts")) 
@@ -79,12 +85,18 @@
             return request;
             
         }
+
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.INBOUND;
+        } 
         
     };
     
-    URLRewriterRule rule2 = new URLRewriterRule() {
+    URLRewriterRule rule2 = new URLRewriterRule()
+    {
 
-        public Request process(Request request)
+        public Request process(Request request, URLRewriteContext context)
         {
             final String path = request.getPath();
             if (path.equals("/jsf")) 
@@ -95,11 +107,17 @@
             
         }
         
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.INBOUND;
+        }
+
     };
     
-    URLRewriterRule rule3 = new URLRewriterRule() {
+    URLRewriterRule rule3 = new URLRewriterRule()
+    {
 
-        public Request process(Request request)
+        public Request process(Request request, URLRewriteContext context)
         {
             String path = request.getPath();
             if (path.equals("/tapestry")) 
@@ -111,11 +129,17 @@
             
         }
         
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.INBOUND;
+        }
+
     };
     
-    URLRewriterRule rule4 = new URLRewriterRule() {
+    URLRewriterRule rule4 = new URLRewriterRule()
+    {
 
-        public Request process(Request request)
+        public Request process(Request request, URLRewriteContext context)
         {
             String serverName = request.getServerName();
             String path = request.getPath();
@@ -127,7 +151,13 @@
             return request;
             
         }
-        
+
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.OUTBOUND;
+        }
+
+
     };    
     
     configuration.add("rule1", rule1);
@@ -152,4 +182,73 @@
   Note that this applies to rewriting links generated by Tapestry too:
   a <<<PageLink>>> to the <<<urlrewritesuccess>>> page with an activation
   context of <<<login>>> (path <<</urlrewritesuccess/login>>>) will generate an <<<a>>> 
-  tag pointing to <<<http://login.domain.com>>>. 
\ No newline at end of file
+  tag pointing to <<<http://login.domain.com>>>.
+
+  The URLRewriteContext (added in 5.1.0.4) provides additional information for
+  rewriting, particularly in the context of rewriting generated link urls. In the
+  following  example, we'll reconfigure the url used to render pages.  Whereas the
+  previous examples used separate rules for handling inbound and outbound rewriting,
+  this demonstration will utilize a single rule for both scenarios. To simplify the
+  example, we will assume that every page is named "XXXPage" (UserPage,
+  TransactionPage, IndexPage, etc.). This naming convention also means that
+  we don't have to worry about tapestry's auto-stripping of "index" from urls,
+  because our page would be IndexPage, rather than Index.
+
++------------------------------------------------------------------------+
+
+public static void contributeURLRewriter(OrderedConfiguration<URLRewriterRule> configuration)
+{
+
+    URLRewriterRule rule = new URLRewriterRule() {
+
+        public Request process(Request request, URLRewriteContext context)
+        {
+            if (context.isIncoming())
+            {
+                //these look like component event requests, which we didn't rewrite, so ignore.
+                if (request.getPath().contains(".") || request.getPath().contains(":")) {
+                    return request;
+                }
+                String pageName = request.getPath().substring(1,request.getPath().indexOf('/',1));
+                return new SimpleRequest(request,path.replaceAll(pageName,pageName + "page"));
+            }
+            else
+            {
+               //if this is a component event, getPageParameters() will return null.
+               if (context.getPageParameters() != null) {
+                    String path = request.getPath();
+                    String pageName = context.getPageParameters().getLogicalPageName().toLowerCase();
+                    String newPageName = pageName.replaceAll("page$","");
+                    return new SimpleRequest(request,path.replaceAll(pageName,newPageName);
+               }
+            }
+
+        }
+
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.BOTH;
+        }
+
+    };
+
+    configuration.add("rule1",rule);
+
+}
+
++------------------------------------------------------------------------------+
+
+  In the first part of <<<process>>>, <<<context.isIncoming()>>> determines if
+  the call to <<<process>>> occured due to an inbound request.  If so,
+  the rule reverses the mapping done in the second portion of the method, so tapestry sees
+  the original request.
+
+  The second half of <<<process>>> rewrites only page links by retrieving the logical page name
+  and replacing its occurence in the url with the shortened form of the link.  This code segment
+  demonstrates how the additional information provided by <<<URLRewriteContext>>> can be used to
+  rewrite urls in a generalized manner.
+
+  Note that <<<getPageParameters()>>> will only return non-null when <<<process>>> is called due to
+  page link creation, and <<<getComponentEventParameters()>>> will only return non-null when
+  <<<process>> is called as a result of creating component event links.
+

Modified: tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/upgrade.apt?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/upgrade.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/upgrade.apt Thu Apr  9 22:26:09 2009
@@ -13,6 +13,20 @@
   You should also check the {{{release-notes.html}project-wide release notes}} for information
   about bugs fixes and other improvements.
 
+Release 5.1.0.4
+
+  Tapestry's alpha URL rewriting support (available from 5.1.0.1) has undergone some API changes:
+
+    * The core url rewriting service to which rules are contributed has changed from URLRewriterService to 
+      URLRewriter, with a corresponding change to the service id.  Modules contributing to this service will need to
+      update the corresponding contribution method names.
+
+    * The signature of the "process" method of the URLRewriterRule interface now requires an additional parameter
+      of type org.apache.tapestry5.urlrewriter.URLRewriteContext.
+
+    * URLRewriteRule implementations must now also implement the "applicability" method which determines whether
+      rules should be applied to incoming requests, outgoing urls (links), or both.
+
 Release 5.1.0.1
 
   Tapestry's client-side JavaScript relating to input field validation has changed somewhat

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventLinkEncoderMethodAdvice.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventLinkEncoderMethodAdvice.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventLinkEncoderMethodAdvice.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentEventLinkEncoderMethodAdvice.java Thu Apr  9 22:26:09 2009
@@ -20,64 +20,75 @@
 import org.apache.tapestry5.ioc.Invocation;
 import org.apache.tapestry5.ioc.MethodAdvice;
 import org.apache.tapestry5.ioc.internal.util.Defense;
-import org.apache.tapestry5.services.ComponentEventLinkEncoder;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.*;
 import org.apache.tapestry5.urlrewriter.SimpleRequestWrapper;
+import org.apache.tapestry5.urlrewriter.URLRewriteContext;
 
 /**
  * Advices
  * {@linkplain ComponentEventLinkEncoder#createComponentEventLink(org.apache.tapestry5.services.ComponentEventRequestParameters, boolean)}
  * and
  * {@linkplain ComponentEventLinkEncoder#createPageRenderLink(org.apache.tapestry5.services.PageRenderRequestParameters)}
- * to rewrites the returned links using {@linkplain URLRewriterService}.
+ * to rewrites the returned links using {@linkplain URLRewriter}.
  */
 public class ComponentEventLinkEncoderMethodAdvice implements MethodAdvice
 {
 
-    final private URLRewriterService urlRewriterService;
+    private final URLRewriter urlRewriter;
 
-    final private Request request;
+    private final Request request;
 
-    final private HttpServletRequest httpServletRequest;
+    private final HttpServletRequest httpServletRequest;
 
-    final private Response response;
+    private final Response response;
+
+    private final boolean forPageLink;
+
+    /**
+     * Index of the invocation parameter that contains either the ComponentEventRequestParameter
+     * or the PageRenderRequestParameter objects.
+     */
+    private static final int CONTEXT_PARAMETER_INDEX =0;
 
     /**
      * Single constructor of this class.
      * 
-     * @param urlRewriterService
-     *            an {@link URLRewriterService}. It cannot be null.
+     * @param urlRewriter
+     *            an {@link URLRewriter}. It cannot be null.
      * @param request
      *            a {@link Request}. It cannot be null.
      * @param httpServletRequest
      *            an {@link HttpServletRequest}. It cannot be null.
      * @param response
      *            a {@link Response}. It cannot be null.
+     * @param forPageLink
+     *            true if the advice is for page link creation, false for component event link creation.
      */
-    public ComponentEventLinkEncoderMethodAdvice(URLRewriterService urlRewriterService,
-            Request request, HttpServletRequest httpServletRequest, Response response)
+    public ComponentEventLinkEncoderMethodAdvice(URLRewriter urlRewriter,
+            Request request, HttpServletRequest httpServletRequest, Response response,
+            boolean forPageLink)
     {
 
-        Defense.notNull(urlRewriterService, "urlRewriterService");
+        Defense.notNull(urlRewriter, "urlRewriter");
         Defense.notNull(request, "request");
         Defense.notNull(httpServletRequest, "httpServletRequest");
         Defense.notNull(response, "response");
 
         this.httpServletRequest = httpServletRequest;
-        this.urlRewriterService = urlRewriterService;
+        this.urlRewriter = urlRewriter;
         this.request = request;
         this.response = response;
-
+        this.forPageLink = forPageLink;
     }
 
     public void advise(Invocation invocation)
     {
         invocation.proceed();
+        String name = invocation.getMethodName();
 
         Link link = (Link) invocation.getResult();
-
-        Link newLink = rewriteIfNeeded(link);
+        URLRewriteContext context = setupContext(invocation);
+        Link newLink = rewriteIfNeeded(link,context);
 
         if (newLink != null)
         {
@@ -86,18 +97,60 @@
 
     }
 
+    private URLRewriteContext setupContext(final Invocation invocation) {
+
+        if (forPageLink) {
+            return new URLRewriteContext()
+            {
+
+                public boolean isIncoming()
+                {
+                    return false;
+                }
+
+                public PageRenderRequestParameters getPageParameters()
+                {
+                    return (PageRenderRequestParameters) invocation.getParameter(CONTEXT_PARAMETER_INDEX);
+                }
+
+                public ComponentEventRequestParameters getComponentEventParameters()
+                {
+                    return null;
+                }
+            };
+        }
+        return new URLRewriteContext()
+        {
+
+            public boolean isIncoming()
+            {
+                return false;
+            }
+
+            public PageRenderRequestParameters getPageParameters()
+            {
+                return null;
+            }
+
+            public ComponentEventRequestParameters getComponentEventParameters()
+            {
+                return (ComponentEventRequestParameters) invocation.getParameter(CONTEXT_PARAMETER_INDEX);
+            }
+        };
+    }
+
     /**
      * Returns a rewritten Link or null.
      * 
      * @param link
      *            a {@link Link}.
      */
-    Link rewriteIfNeeded(Link link)
+    Link rewriteIfNeeded(Link link, URLRewriteContext context)
     {
         Link newLink = null;
         SimpleRequestWrapper fakeRequest = new SimpleRequestWrapper(request, link.toAbsoluteURI());
 
-        Request rewritten = urlRewriterService.process(fakeRequest);
+        Request rewritten = urlRewriter.processLink(fakeRequest,context);
 
         // if the original request is equal to the rewritten one, no
         // rewriting is needed

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java Thu Apr  9 22:26:09 2009
@@ -56,7 +56,7 @@
         int commandCount = 0;
         int maxDepth = 0;
 
-        // Seems to make sense to use one try/finally around the whole process, rather than
+        // Seems to make sense to use one try/finally around the whole processInbound, rather than
         // around each call to render() since the end result (in a failure scenario) is the same.
 
         try

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java Thu Apr  9 22:26:09 2009
@@ -416,4 +416,14 @@
     {
         return MESSAGES.get("literal-conduit-not-updateable");
     }
+
+    static String requestRewriteReturnedNull()
+    {
+        return MESSAGES.get("request-rewrite-returned-null");
+    }
+
+    static String linkRewriteReturnedNull()
+    {
+        return MESSAGES.get("link-rewrite-returned-null");
+    }
 }

Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterImpl.java (from r760774, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterServiceImpl.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterImpl.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterImpl.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterServiceImpl.java&r1=760774&r2=763830&rev=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterServiceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterImpl.java Thu Apr  9 22:26:09 2009
@@ -14,25 +14,30 @@
 
 package org.apache.tapestry5.internal.services;
 
-import java.util.Collections;
-import java.util.List;
-
 import org.apache.tapestry5.ioc.annotations.UsesOrderedConfiguration;
 import org.apache.tapestry5.ioc.internal.util.Defense;
+import org.apache.tapestry5.services.ComponentEventRequestParameters;
+import org.apache.tapestry5.services.PageRenderRequestParameters;
 import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.URLRewriter;
+import org.apache.tapestry5.urlrewriter.URLRewriteContext;
 import org.apache.tapestry5.urlrewriter.URLRewriterRule;
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 /**
- * Default {@linkplain URLRewriterService} implementation.
+ * Default {@linkplain org.apache.tapestry5.services.URLRewriter} implementation.
  *
  * @since 5.1.0.2
  */
 @UsesOrderedConfiguration(URLRewriterRule.class)
-public class URLRewriterServiceImpl implements URLRewriterService
+public class URLRewriterImpl implements URLRewriter
 {
 
-    final private List<URLRewriterRule> rules;
+    final private List<URLRewriterRule> incomingRules;
+    final private List<URLRewriterRule> outgoingRules;
 
     /**
      * Single constructor of this class.
@@ -40,32 +45,89 @@
      * @param rules
      *            a <code>List</code> of <code>URLRewriterRule</code>. It cannot be null.
      */
-    public URLRewriterServiceImpl(List<URLRewriterRule> rules)
+    public URLRewriterImpl(List<URLRewriterRule> rules)
     {
         Defense.notNull(rules, "rules");
-        this.rules = Collections.unmodifiableList(rules);
+        this.incomingRules = new ArrayList<URLRewriterRule>();
+        this.outgoingRules = new ArrayList<URLRewriterRule>();
+        for(URLRewriterRule rule : rules)
+        {
+            switch(rule.applicability())
+            {
+                case INBOUND:
+                    incomingRules.add(rule);
+                    break;
+                case OUTBOUND:
+                    outgoingRules.add(rule);
+                    break;
+                default:
+                    incomingRules.add(rule);
+                    outgoingRules.add(rule);
+            }
+        }
     }
 
-    public Request process(Request request)
+    public Request processRequest(Request request)
     {
+        request = process(request,incomingRules,new URLRewriteContext(){
+            public boolean isIncoming()
+            {
+                return true;
+            }
+
+            public PageRenderRequestParameters getPageParameters()
+            {
+                return null;
+            }
+
+            public ComponentEventRequestParameters getComponentEventParameters()
+            {
+                return null;
+            }
+        });
+        if (request == null)
+        {
+            throw new NullPointerException(
+                ServicesMessages.requestRewriteReturnedNull());
+        }
+        return request;
+    }
+
+    private Request process(Request request, List<URLRewriterRule> rules, URLRewriteContext context)
+    {
+
         for (URLRewriterRule rule : rules)
         {
 
-            request = rule.process(request);
-            if (request == null) 
-            { 
-                throw new NullPointerException(
-                    "URLRewriterRule.process() returned null."); 
+            request = rule.process(request,context);
+            if (request == null)
+            {
+                return null;
             }
 
         }
-        
+
         return request;
-        
+
     }
-    
-    public List<URLRewriterRule> getRules() {
-        return rules;
+
+    public Request processLink(Request request,URLRewriteContext context) {
+        request = process(request,outgoingRules,context);
+        if (request == null)
+        {
+            throw new NullPointerException(
+                    ServicesMessages.linkRewriteReturnedNull());
+        }
+        return request;
+    }
+
+    public boolean hasRequestRules() {
+        return !incomingRules.isEmpty();
     }
-    
+
+    public boolean hasLinkRules() {
+        return !outgoingRules.isEmpty();
+    }
+
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilter.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilter.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilter.java Thu Apr  9 22:26:09 2009
@@ -16,10 +16,7 @@
 import java.io.IOException;
 
 import org.apache.tapestry5.ioc.internal.util.Defense;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.RequestFilter;
-import org.apache.tapestry5.services.RequestHandler;
-import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.*;
 
 /**
  * <code>RequestFilter</code> that applies the URL rewriting rules to requests.
@@ -29,23 +26,23 @@
 public class URLRewriterRequestFilter implements RequestFilter
 {
 
-    final private URLRewriterService urlRewriterService;
+    final private URLRewriter urlRewriter;
 
     /**
      * Single constructor of this class.
-     * @param urlRewriterService um {@link URLRewriterService}. It cannot be null.
+     * @param urlRewriter um {@link URLRewriter}. It cannot be null.
      */
-    public URLRewriterRequestFilter(URLRewriterService urlRewriterService)
+    public URLRewriterRequestFilter(URLRewriter urlRewriter)
     {
-        Defense.notNull(urlRewriterService, "urlRewriterService");
-        this.urlRewriterService = urlRewriterService;
+        Defense.notNull(urlRewriter, "urlRewriter");
+        this.urlRewriter = urlRewriter;
     }
 
     public boolean service(Request request, Response response, RequestHandler handler)
             throws IOException
     {
 
-        request = urlRewriterService.process(request);
+        request = urlRewriter.processRequest(request);
 
         return handler.service(request, response);
 

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=763830&r1=763829&r2=763830&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 Thu Apr  9 22:26:09 2009
@@ -52,7 +52,6 @@
 import org.apache.tapestry5.runtime.RenderCommand;
 import org.apache.tapestry5.runtime.RenderQueue;
 import org.apache.tapestry5.services.ajax.MultiZoneUpdateEventResultProcessor;
-import org.apache.tapestry5.urlrewriter.URLRewriterRule;
 import org.apache.tapestry5.util.StringToEnumCoercion;
 import org.apache.tapestry5.validator.*;
 import org.slf4j.Logger;
@@ -307,6 +306,7 @@
         binder.bind(ComponentEventLinkEncoder.class, ComponentEventLinkEncoderImpl.class);
         binder.bind(PageRenderLinkSource.class, PageRenderLinkSourceImpl.class);
         binder.bind(ClientInfrastructure.class, ClientInfrastructureImpl.class);
+        binder.bind(URLRewriter.class,URLRewriterImpl.class);
     }
 
     // ========================================================================
@@ -501,7 +501,7 @@
         add(configuration, TransformConstants.AFTER_RENDER_SIGNATURE, AfterRender.class, true);
         add(configuration, TransformConstants.CLEANUP_RENDER_SIGNATURE, CleanupRender.class, true);
 
-        // Ideally, these should be ordered pretty late in the process to make sure there are no
+        // Ideally, these should be ordered pretty late in the processInbound to make sure there are no
         // side effects with other workers that do work inside the page lifecycle methods.
 
         add(configuration, PageLoaded.class, TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, "pageLoaded");
@@ -757,7 +757,7 @@
 
                                          UpdateListenerHub updateListenerHub,
 
-                                         URLRewriterService urlRewriterService)
+                                         URLRewriter urlRewriter)
     {
         RequestFilter staticFilesFilter = new StaticFilesFilter(context);
 
@@ -792,11 +792,11 @@
                                                                        checkInterval, updateTimeout), "before:*");
 
         // we just need the URLRewriterRequestFilter if we have URL rewriter rules, of course.
-        if (urlRewriterService.getRules().isEmpty() == false)
+        if (urlRewriter.hasRequestRules())
         {
 
             URLRewriterRequestFilter urlRewriterRequestFilter = new URLRewriterRequestFilter(
-                    urlRewriterService);
+                    urlRewriter);
             configuration.add("URLRewriter", urlRewriterRequestFilter, "before:StaticFiles");
 
         }
@@ -2373,43 +2373,42 @@
     }
 
     /**
-     * @since 5.1.0.2
-     */
-    public static URLRewriterService buildURLRewriterService(List<URLRewriterRule> contributions)
-    {
-        return new URLRewriterServiceImpl(contributions);
-    }
-
-    /**
      * @throws Exception
      * @since 5.1.0.2
      */
     public static ComponentEventLinkEncoder decorateComponentEventLinkEncoder(
-            ComponentEventLinkEncoder encoder, URLRewriterService urlRewriterService,
+            ComponentEventLinkEncoder encoder, URLRewriter urlRewriter,
             Request request, HttpServletRequest httpServletRequest, Response response,
             AspectDecorator aspectDecorator) throws Exception
     {
 
         // no rules, no link rewriting.
-        if (urlRewriterService.getRules().isEmpty())
+        if (!urlRewriter.hasLinkRules())
         {
             return null;
         }
 
-        ComponentEventLinkEncoderMethodAdvice advice =
-                new ComponentEventLinkEncoderMethodAdvice(urlRewriterService, request, httpServletRequest, response);
+        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, advice);
-        builder.adviseMethod(createPageRenderLink, advice);
+        builder.adviseMethod(createComponentEventLink, eventLinkAdvice);
+        builder.adviseMethod(createPageRenderLink, pageLinkAdvice);
 
         return builder.build();
 

Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/URLRewriter.java (from r760774, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterService.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/URLRewriter.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/URLRewriter.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterService.java&r1=760774&r2=763830&rev=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterService.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/URLRewriter.java Thu Apr  9 22:26:09 2009
@@ -12,23 +12,21 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry5.internal.services;
+package org.apache.tapestry5.services;
 
-import java.util.List;
-
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.urlrewriter.URLRewriterRule;
+import org.apache.tapestry5.urlrewriter.URLRewriteContext;
 
 
 /**
  * Service that implements URL and link rewriting.
  *
+ *
  * @since 5.1.0.2
  */
-public interface URLRewriterService
+public interface URLRewriter
 {
     /**
-     * Processes a {@linkplain org.apache.tapestry5.services.Request}. 
+     * Processes an incoming {@linkplain org.apache.tapestry5.services.Request}.
      * This method must check if they need to rewrite this request. If no, it must return the received
      * request unchanged. This method cannot return null.
      * 
@@ -36,13 +34,27 @@
      *            a {@link org.apache.tapestry5.services.Request}.
      * @return request a {@link org.apache.tapestry5.services.Request}. It cannot be null.
      */
-    Request process(Request request);
+    Request processRequest(Request request);
+
+    /**
+     * Processes rules for rewriting links.
+     * @param request the request to examine
+     * @param context the context providing additional information for rewriting
+     * @return the original request if the URLRewriter does nothing, a modified request otherwise, but never null
+     */
+    Request processLink(Request request, URLRewriteContext context);
     
     /**
-     * Returns the registered rewriter rules.
+     *
      * 
-     * @return a {@link List} of {@link URLRewriterRule}.
+     * @return true if the urlrewriter has any rules for rewriting inbound request urls
      */
-    List<URLRewriterRule> getRules();
-    
+    boolean hasRequestRules();
+
+
+    /**
+     * @return true if the URLRewriter has any rules for rewriting outbound links.
+     */
+    boolean hasLinkRules();
+
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/RewriteRuleApplicability.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/RewriteRuleApplicability.java?rev=763830&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/RewriteRuleApplicability.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/RewriteRuleApplicability.java Thu Apr  9 22:26:09 2009
@@ -0,0 +1,27 @@
+// Copyright 2009 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.urlrewriter;
+
+/**
+ * Defines the situations to which a URLRewriterRule will be applied (inbound, outbound, or both)
+ */
+public enum RewriteRuleApplicability {
+    /**contributed rule applies to inbound requests only*/
+    INBOUND,
+    /**contributed rule applies to "outbound" requests (link rewriting).*/
+    OUTBOUND,
+    /**contributed rule applies to both inbound and outbound requests*/
+    BOTH
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriteContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriteContext.java?rev=763830&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriteContext.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriteContext.java Thu Apr  9 22:26:09 2009
@@ -0,0 +1,47 @@
+// Copyright 2009 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.urlrewriter;
+
+import org.apache.tapestry5.services.PageRenderRequestParameters;
+import org.apache.tapestry5.services.ComponentEventRequestParameters;
+
+/**
+ * Context passed to the process method of URLRewriterRule implementations, providing additional
+ * information that the rules might need to function.
+ */
+public interface URLRewriteContext {
+
+    /**
+     *
+     * @return true if the "process" method of URLRewriterRule is being called for an incoming request.
+     */
+    boolean isIncoming();
+
+    /**
+     * If the request being processed is processed in response to pagelink creation, the PageRenderRequestParameters
+     * associated with that creation will be available via this method.  Otherwise, this method returns null.
+     * @return the PageRenderRequestParameters associated with the link creation for this request, or null
+     */
+    PageRenderRequestParameters getPageParameters();
+
+    /**
+     * If the request being processed is processed in response to component event link creation, the
+     * ComponentEVentRequestParameters associated with that creation will be available via this method.
+     * Otherwise, this method returns null.
+     * @return the ComponentEventRequestParameters associated with the link creation for this request, or null
+     */
+    ComponentEventRequestParameters getComponentEventParameters();
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriterRule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriterRule.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriterRule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/urlrewriter/URLRewriterRule.java Thu Apr  9 22:26:09 2009
@@ -30,6 +30,7 @@
      *            a {@link org.apache.tapestry5.services.Request}.
      * @return request a {@link org.apache.tapestry5.services.Request}.
      */
-    Request process(Request request);
+    Request process(Request request,URLRewriteContext context);
 
+    RewriteRuleApplicability applicability();
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/services/ServicesStrings.properties Thu Apr  9 22:26:09 2009
@@ -92,4 +92,6 @@
 add-new-method-conflict=Unable to add new method %s as it already exists.
 parameter-element-does-not-allow-attributes=A block parameter element does not allow any additional attributes. The element name defines the parameter name.
 invalid-path-for-library-namespace=The path portion of library namespace URI '%s' is not valid: it must be a simple identifier, or a series of identifiers seperated by slashes.
-literal-conduit-not-updateable=Literal values are not updateable.
\ No newline at end of file
+literal-conduit-not-updateable=Literal values are not updateable.
+request-rewrite-returned-null=URLRewriterRule.process returned null while processing incoming request
+link-rewrite-returned-null=URLRewriterRule.process returned null while processing outbound link.

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteSuccess2.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteSuccess2.tml?rev=763830&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteSuccess2.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteSuccess2.tml Thu Apr  9 22:26:09 2009
@@ -0,0 +1,10 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
+    <head>
+        <title>
+            Rewrite Success, 2
+        </title>
+    </head>
+    <body>
+        URL Rewriting that relies on the RewriteContext evidently works.
+    </body>
+</html>
\ No newline at end of file

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteWithContext.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteWithContext.tml?rev=763830&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteWithContext.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app5/RewriteWithContext.tml Thu Apr  9 22:26:09 2009
@@ -0,0 +1,12 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
+    <head>
+        <title>
+            Rewrite With Context
+        </title>
+    </head>
+    <body>
+        <a t:type="pagelink" t:id="thePageLink" page="RewriteSuccess2" class="page">Rewrite Page Link</a>
+        <a t:type="eventlink" t:id="theEventLink" event="click" class="event">Rewrite Component Event Link</a>
+        <a t:type="actionlink" t:id="theActingLink" class="action">Rewrite Action Link</a>
+    </body>
+</html>
\ No newline at end of file

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteSuccess2.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteSuccess2.java?rev=763830&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteSuccess2.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteSuccess2.java Thu Apr  9 22:26:09 2009
@@ -0,0 +1,19 @@
+// Copyright 2009 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.integration.app5.pages;
+
+public class RewriteSuccess2
+{
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteWithContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteWithContext.java?rev=763830&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteWithContext.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/pages/RewriteWithContext.java Thu Apr  9 22:26:09 2009
@@ -0,0 +1,27 @@
+// Copyright 2009 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.integration.app5.pages;
+
+public class RewriteWithContext
+{
+
+    public String onClick() {
+        return "RewriteSuccess2";
+    }
+
+    public String onActionFromTheActingLink() {
+        return "RewriteSuccess2";
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/services/AppModule.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app5/services/AppModule.java Thu Apr  9 22:26:09 2009
@@ -17,19 +17,19 @@
 import org.apache.tapestry5.integration.app5.pages.URLRewriteSuccess;
 import org.apache.tapestry5.ioc.OrderedConfiguration;
 import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.urlrewriter.IntegrationTests;
-import org.apache.tapestry5.urlrewriter.SimpleRequestWrapper;
-import org.apache.tapestry5.urlrewriter.URLRewriterRule;
+import org.apache.tapestry5.services.ComponentEventLinkEncoder;
+import org.apache.tapestry5.urlrewriter.*;
 
 public class AppModule
 {
     private static final String SUCCESS_PAGE_NAME = URLRewriteSuccess.class.getSimpleName().toLowerCase();
 
-    public static void contributeURLRewriterService(OrderedConfiguration<URLRewriterRule> configuration) {
+    public static void contributeURLRewriter(OrderedConfiguration<URLRewriterRule> configuration) {
         
-        URLRewriterRule rule1 = new URLRewriterRule() {
+        URLRewriterRule rule1 = new URLRewriterRule()
+        {
 
-            public Request process(Request request)
+            public Request process(Request request, URLRewriteContext context)
             {
                 final String path = request.getPath();
                 if (path.equals("/struts")) 
@@ -39,12 +39,17 @@
                 return request;
                 
             }
-            
+
+            public RewriteRuleApplicability applicability() {
+                return RewriteRuleApplicability.INBOUND;
+            }
+
         };
         
-        URLRewriterRule rule2 = new URLRewriterRule() {
+        URLRewriterRule rule2 = new URLRewriterRule()
+        {
 
-            public Request process(Request request)
+            public Request process(Request request, URLRewriteContext context)
             {
                 final String path = request.getPath();
                 if (path.equals("/jsf")) 
@@ -54,12 +59,18 @@
                 return request;
                 
             }
-            
+
+            public RewriteRuleApplicability applicability() {
+                return RewriteRuleApplicability.INBOUND;
+            }
+
         };
-        
-        URLRewriterRule rule3 = new URLRewriterRule() {
 
-            public Request process(Request request)
+
+        URLRewriterRule rule3 = new URLRewriterRule()
+        {
+
+            public Request process(Request request,URLRewriteContext context)
             {
                 String path = request.getPath();
                 if (path.equals("/tapestry")) 
@@ -70,12 +81,18 @@
                 return request;
                 
             }
-            
+
+            public RewriteRuleApplicability applicability()
+            {
+                return RewriteRuleApplicability.INBOUND;
+            }
+
         };
         
-        URLRewriterRule rule4 = new URLRewriterRule() {
+        URLRewriterRule rule4 = new URLRewriterRule()
+        {
 
-            public Request process(Request request)
+            public Request process(Request request, URLRewriteContext context)
             {
                 String serverName = request.getServerName();
                 String path = request.getPath();
@@ -87,12 +104,18 @@
                 return request;
                 
             }
-            
+
+            public RewriteRuleApplicability applicability()
+            {
+                return RewriteRuleApplicability.INBOUND;
+            }
+
         };
         
-        URLRewriterRule rule5 = new URLRewriterRule() {
+        URLRewriterRule rule5 = new URLRewriterRule() 
+        {
 
-            public Request process(Request request)
+            public Request process(Request request, URLRewriteContext context)
             {
                 String serverName = request.getServerName();
                 String path = request.getPath();
@@ -104,12 +127,18 @@
                 return request;
                 
             }
-            
+
+            public RewriteRuleApplicability applicability()
+            {
+                return RewriteRuleApplicability.OUTBOUND;
+            }
+
         };
         
-        URLRewriterRule rule6 = new URLRewriterRule() {
+        URLRewriterRule rule6 = new URLRewriterRule()
+        {
 
-            public Request process(Request request)
+            public Request process(Request request, URLRewriteContext context)
             {
                 String serverName = request.getServerName();
                 String path = request.getPath().toLowerCase();
@@ -120,15 +149,172 @@
                 return request;
                 
             }
-            
+
+            public RewriteRuleApplicability applicability()
+            {
+                return RewriteRuleApplicability.OUTBOUND;
+            }
+
         };
-        
+
+        URLRewriterRule rule7 = new Rule7();
+
+
         configuration.add("rule1", rule1);
         configuration.add("rule2", rule2, "after:rule1");
         configuration.add("rule3", rule3, "after:rule2");
         configuration.add("rule4", rule4);
         configuration.add("rule5", rule5);
         configuration.add("rule6", rule6);
+        configuration.add("rule7", rule7);
         
     }
+
+    //note that as this is a test, there are a lot of shortcuts employed in the url processing.
+    //and the example is entirely contrived.
+    //But it does illustrate the sorts of things that are possible.
+    static class Rule7 implements URLRewriterRule
+    {
+
+        private Request decodePage(Request request)
+        {
+            //want to skip first slash plus the slash trailing rpage.
+            int idx =request.getPath().indexOf('/',7);
+
+            String pageName;
+            String pathRemainder;
+            if (idx == -1) {
+                pageName = request.getPath().substring(7);
+                pathRemainder = "";
+            } else {
+                pageName = request.getPath().substring(7,idx);
+                pathRemainder = request.getPath().substring(idx);
+            }
+
+            String newPath = "/" + reverse(pageName)
+                    + pathRemainder;
+            return new SimpleRequestWrapper(request,newPath);
+        }
+
+        private Request decodeEventLink(Request request, String path,int idx)
+        {
+            String event = null;
+            //do we have a slash after?
+            int slashIdx = path.indexOf('/',idx);
+            if (slashIdx == -1) {
+                event = reverse(path.substring(idx+1));
+                path = path.substring(0,idx) ;
+            } else {
+                event = reverse(path.substring(idx+1,slashIdx));
+                path = path.substring(0,idx) + path.substring(slashIdx);
+            }
+            return decodeComponentLink(request,path,event);
+        }
+
+        private Request decodeComponentLink(Request request, String path, String event)
+        {
+            int idx = path.indexOf('.');
+            String pageName;
+            String componentName=null;//idea complains about componentName might not be initialized otherwise.
+            if (idx == -1)
+            {
+                idx = path.indexOf('/');
+                if (idx < 1)
+                {
+                    pageName = reverse(path);
+                    path = "";
+                } else {
+                    pageName = reverse(path.substring(0,idx));
+                    path = path.substring(idx);
+
+                }
+            }
+            else
+            {
+                int slashIdx = path.indexOf('/',idx);
+                pageName = reverse(path.substring(0,idx));
+                if (slashIdx < 1) {
+                    componentName = reverse(path.substring(idx+1));
+                    path = "";
+                } else {
+                    componentName = reverse(path.substring(idx+1,slashIdx));
+                    path = path.substring(slashIdx);
+                }
+            }
+            path = "/" + pageName + (componentName==null?"":"."+componentName)
+                    + (event==null?"":":" + event) + path;
+            return new SimpleRequestWrapper(request,path);
+        }
+
+        public Request process(Request request, URLRewriteContext context)
+        {
+            if (context.isIncoming()) {
+                if (request.getPath().startsWith("/rpage/"))
+                {
+                    return decodePage(request);
+                }
+                else if (request.getPath().startsWith("/cevent/"))
+                {
+                    String path = request.getPath().substring(8);
+                    //check for event presence first.
+                    int idx = path.indexOf(':');
+                    if (idx != -1)
+                    {
+                        return decodeEventLink(request,path,idx);
+                    }
+                    return decodeComponentLink(request,path,null);
+
+                }
+            }
+            else if (context.getPageParameters() != null)
+            {
+                //page link reversing is just to illustrate the fact that we can manipulate paths without caring about
+                //the precise details of the path. Except, we don't want to mess with index, URLRewriteSuccess,
+                //or dummy because that messes up the rest of the tests.
+                String pageName = context.getPageParameters().getLogicalPageName().toLowerCase();
+                if (pageName.equals("index") || pageName.equals("urlrewritesuccess") || pageName.equals("dummy")) {
+                    return request;
+                }
+                String newPath = "/rpage" + request.getPath().replaceAll(pageName,reverse(pageName));
+                return new SimpleRequestWrapper(request,newPath);
+            }
+            else
+            {
+                //mangle the event details.
+                String pageName = context.getComponentEventParameters().getActivePageName().toLowerCase();
+                if (pageName.equals("index") || pageName.equals("urlrewritesuccess") || pageName.equals("dummy")) {
+                    return request;
+                }
+                String eventName = context.getComponentEventParameters().getEventType().toLowerCase();
+                String componentId = context.getComponentEventParameters().getNestedComponentId().toLowerCase();
+
+                String newPath = "/cevent" +
+                        request.getPath().replaceAll(pageName,reverse(pageName))
+                                .replaceAll(eventName,reverse(eventName))
+                                .replaceAll(componentId,reverse(componentId));
+                return new SimpleRequestWrapper(request, newPath);
+            }
+            return request;
+        }
+
+        private String reverse(String input) {
+
+            if (input == null) return null;
+
+            StringBuilder rev = new StringBuilder(input.length());
+
+            for(int i=input.length();i>0;i--)
+            {
+                rev.append(input.charAt(i-1));
+            }
+
+            return rev.toString();
+        }
+
+        public RewriteRuleApplicability applicability()
+        {
+            return RewriteRuleApplicability.BOTH;
+        }
+    };
 }
+

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImplTest.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImplTest.java Thu Apr  9 22:26:09 2009
@@ -149,7 +149,7 @@
 
         verify();
 
-        // Now, change the file and process an UpdateEvent.
+        // Now, change the file and processInbound an UpdateEvent.
 
         touch(f);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilterTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilterTest.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilterTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/URLRewriterRequestFilterTest.java Thu Apr  9 22:26:09 2009
@@ -18,18 +18,17 @@
 import java.util.List;
 
 import org.apache.tapestry5.ioc.test.TestBase;
-import org.apache.tapestry5.internal.services.URLRewriterService;
-import org.apache.tapestry5.services.DelegatingRequest;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.RequestHandler;
-import org.apache.tapestry5.services.Response;
+import org.apache.tapestry5.services.URLRewriter;
+import org.apache.tapestry5.services.*;
 import org.apache.tapestry5.urlrewriter.SimpleRequestWrapper;
 import org.apache.tapestry5.urlrewriter.URLRewriterRule;
+import org.apache.tapestry5.urlrewriter.RewriteRuleApplicability;
+import org.apache.tapestry5.urlrewriter.URLRewriteContext;
 import org.testng.annotations.Test;
 
 /**
- * Tests {@linkplain org.org.apache.tapestry5.internal.services.URLRewriterRequestFilter}
- * and also {@link URLRewriterServiceImpl}.
+ * Tests {@linkplain org.apache.tapestry5.internal.services.URLRewriterRequestFilter}
+ * and also {@link URLRewriterImpl}.
  */
 public class URLRewriterRequestFilterTest extends TestBase
 {
@@ -39,7 +38,7 @@
 
         private DelegatingRequest delegetingRequest = new DelegatingRequest();
 
-        public Request process(Request request)
+        public Request process(Request request, URLRewriteContext context)
         {
             final String serverName = request.getServerName().replace("JSF", "tapestry");
             final String path = request.getPath().replace(".JSF", "");
@@ -48,11 +47,17 @@
             return delegetingRequest;
         }
 
+        public RewriteRuleApplicability applicability() {
+            return RewriteRuleApplicability.BOTH;
+        }
+
         Request getRequest()
         {
             return delegetingRequest;
         }
 
+
+
     }
 
     @Test
@@ -61,12 +66,16 @@
 
         URLRewriterRule rule1 = new URLRewriterRule()
         {
-            public Request process(Request request)
+            public Request process(Request request,URLRewriteContext context)
             {
                 final String serverName = request.getServerName().toUpperCase();
                 final String path = request.getPath().toUpperCase();
                 return new SimpleRequestWrapper(request, serverName, path);
             }
+
+            public RewriteRuleApplicability applicability() {
+                return RewriteRuleApplicability.BOTH;
+            }
         };
 
         InternalURLRewriterRule rule2 = new InternalURLRewriterRule();
@@ -81,7 +90,7 @@
         List<URLRewriterRule> rules = new ArrayList<URLRewriterRule>();
         rules.add(rule1);
         rules.add(rule2);
-        URLRewriterService service = new URLRewriterServiceImpl(rules);
+        URLRewriter service = new URLRewriterImpl(rules);
         URLRewriterRequestFilter filter = new URLRewriterRequestFilter(service);
 
         expect(handler.service(rule2.getRequest(), response)).andReturn(false);
@@ -106,18 +115,22 @@
 
         URLRewriterRule rule = new URLRewriterRule()
         {
-            public Request process(Request request)
+            public Request process(Request request,URLRewriteContext context)
             {
                 return null;
             }
+
+            public RewriteRuleApplicability applicability() {
+                return RewriteRuleApplicability.BOTH;
+            }
         };
         
         List<URLRewriterRule> list = new ArrayList<URLRewriterRule>();
         list.add(rule);
         
-        URLRewriterService urlRewriterService = new URLRewriterServiceImpl(list);
+        URLRewriter urlRewriter = new URLRewriterImpl(list);
 
-        URLRewriterRequestFilter filter = new URLRewriterRequestFilter(urlRewriterService);
+        URLRewriterRequestFilter filter = new URLRewriterRequestFilter(urlRewriter);
         Request request = newMock(Request.class);
         Response response = newMock(Response.class);
         RequestHandler requestHandler = newMock(RequestHandler.class);
@@ -135,6 +148,7 @@
 
         assertTrue(ok);
 
+
     }
 
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/urlrewriter/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/urlrewriter/IntegrationTests.java?rev=763830&r1=763829&r2=763830&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/urlrewriter/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/urlrewriter/IntegrationTests.java Thu Apr  9 22:26:09 2009
@@ -69,4 +69,25 @@
         assertTextPresent("End of maze. URL rewriting works :).");
 
     }
+
+    @Test
+    public void test_url_rewriter_using_context() throws InterruptedException
+    {
+        open("/RewriteWithContext");
+        assertAttribute("//a[@class='page']/@href","/rpage/2sseccusetirwer");
+        assertAttribute("//a[@class='event']/@href", "/cevent/txetnochtiwetirwer:kcilc");
+        assertAttribute("//a[@class='action']/@href","/cevent/txetnochtiwetirwer.knilgnitcaeht");
+
+        clickAndWait("//a[@class='page']");
+        assertTextPresent("URL Rewriting that relies on the RewriteContext evidently works.");
+
+        //note that we should be able to get back to rewritewithcontext via rpage encoding/decoding...
+        open("/rpage/txetnochtiwetirwer");
+        clickAndWait("//a[@class='event']");
+        assertTextPresent("URL Rewriting that relies on the RewriteContext evidently works.");
+
+        open("/rpage/txetnochtiwetirwer");
+        clickAndWait("//a[@class='action']");
+        assertTextPresent("URL Rewriting that relies on the RewriteContext evidently works.");
+    }
 }
\ No newline at end of file



Mime
View raw message