Kontakt

New URL Rewriting API

Posted on Montag, 6th September, 2010

Since 5.1.0.1, Tapestry has basic support for URL rewriting based on the URLRewriter service. In 5.2.0 this service has been deprecated in favour of LinkTransformer service. The new service is actually a facade around ComponentEventLinkTransformer and PageRenderLinkTransformer services.

The PageRenderLinkTransformer service is responsible for the transformation of the page render requests. The implementation of the service is a chain of PageRenderLinkTransformer.

The ComponentEventLinkTransformer service allows a selective replacement of the default links used to represent a component event request. The implementation of the service is a chain of ComponentEventLinkTransformer. Now let’s see some examples.

Rewriting incoming URLs

Imagine you decided to migrate your existing application to Tapestry. Let’s say you are moving from JavaServer Faces. Because the navigation mechanisms in Tapestry and JSF are different, the URLs of your application will change in a incompatible way. This might annoy some of your users who bookmarked the URLs. After the migration these URLs will not work any more. In order to avoid it, you might rewrite all the incoming URLs that start with /jsf.

When processing an incoming requests Tapestry tries to determine if the request is a page render request. If so, Tapestry creates an instance of PageRenderRequestParameters which represents a page and its activation context. The created instance of PageRenderRequestParameters is then used by the PageRenderRequestHandler service to handle a page render request by activating and then rendering the page.

You can take over the task of creation of PageRenderRequestParameters by contributing a PageRenderLinkTransformer. The following listing shows how to accomplish this. When Tapestry attempts to decode the page render request, it will invoke the decodePageRenderRequest() method of JsfLinkTransformer. Inside this method we check if the request path is for a JSF page. If so, an instance of PageRenderRequestParameters representing the Index page with an empty activation context is returned. This will cause the rendering of the Index page when the /jsf/home.xhtml path is requested.

If the incoming request was not identified as a JSF request, a null value is returned. In this case the default logic for decoding the page render request will be executed.

public class JsfLinkTransformer implements PageRenderLinkTransformer {

   public PageRenderRequestParameters decodePageRenderRequest(
                  Request request) {
      String path = request.getPath();

      if (path.startsWith("/jsf/home.xhtml")) {
         return new PageRenderRequestParameters(
            Index.class.getSimpleName(),
            new EmptyEventContext(),
            false);
      }

      return null;
    }

   public Link transformPageRenderLink(
         Link defaultLink,
         PageRenderRequestParameters parameters) {
      return defaultLink;
   }
}

The class EmptyEventContext represents an empty activation context as shown in following example.

public class EmptyEventContext implements EventContext {

   public int getCount() {
      return 0;
   }

   public <T> T get(Class<T> desiredType, int index) {
      return null;
   }

   public String[] toStrings() {
      return new String[0];
   }
}

The next listing shows how to contribute an JsfLinkTransformer to the configuration of the PageRenderLinkTransformer service.

public class AppModule {

   @Contribute(PageRenderLinkTransformer.class)
   @Primary
   public static void provideURLRewriting(
      OrderedConfiguration<PageRenderLinkTransformer>
 configuration) {

      configuration.addInstance(
         "Faces", JsfLinkTransformer.class);
   }
}

Rewriting URLs within an Application

Imagine you want to deprecate a page inside your application in favour of a new page. Because some of your users might have bookmarked the old page you decided to keep it for a while. The URL of the page should still be accessible but all the links inside the application need to be updated. You can either go through all pages of your application to update the page parameter of the PageLink component or you can make a global replacement by contributing to the configuration of the PageRenderLinkTransformer service.

After creating a Link that encapsulates a page render request, Tapestry passes that Link through the PageRenderLinkTransformer chain of command. By contributing your own PageRenderLinkTransformer you can replace a passed link by another one. The following listing shows how to replace a link to MyPage by a link to AnotherPage globally. Inside the transformPageRenderLink() method the base path of the passed link is examined to identify the target page. If the Link represents a URL to MyPage, then a Link to AnotherPage is created and returned. Returning the original Link means that no transformation is required.

public class DeprecatePageLinkTransformer implements PageRenderLinkTransformer {

   @Inject
   private PageRenderLinkSource pageRenderLinkSource;

   public PageRenderRequestParameters decodePageRenderRequest(
                  Request request) {
      return null;
   }

   public Link transformPageRenderLink(
         Link defaultLink,
         PageRenderRequestParameters parameters) {

      if (defaultLink.getBasePath().contains("/mypage")) {
         return this.pageRenderLinkSource
               .createPageRenderLink(AnotherPage.class);
      }

      return defaultLink;
   }
}

The contribution in the following listing will cause that all the PageLink linking to MyPage will render a page link to AnotherPage event though the page parameter is set to MyPage.

public class AppModule {

   @Contribute(PageRenderLinkTransformer.class)
   @Primary
   public static void provideURLRewriting(
      OrderedConfiguration<PageRenderLinkTransformer>
 configuration) {

      configuration.addInstance(
         "DeprecatePageLink",
         DeprecatePageLinkTransformer.class);
   }
}

Rewriting Component Event URLs

Finally, the replacement of the default links used to represent a component event request is accomplished by the ComponentEventLinkTransformer service. This transformer follows the same pattern as PageRenderLinkTransformer.

 

  1. Ksenia Khailenko
  2. Ksenia Khailenko
  3. Igor Drobiazko
  4. Angelo
  5. Angelo

 

avatar

Your name

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Tapestry 5 Blog - Copyright © 2009 - Eclectic Theme by Your Inspiration Web - Powered by WordPress