Author: hlship Date: Sat Feb 27 00:15:54 2010 New Revision: 916878 URL: http://svn.apache.org/viewvc?rev=916878&view=rev Log: TAP5-1034: Using URLRewriteRules will fail for component event links if the page has an activation context
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Link.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PageCallback.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LinkImpl.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/LinkImplTest.java Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Link.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Link.java?rev=916878&r1=916877&r2=916878&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Link.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Link.java Sat Feb 27 00:15:54 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, @@ -14,10 +14,10 @@ package org.apache.tapestry5; -import org.apache.commons.codec.net.URLCodec; - import java.util.List; +import org.apache.commons.codec.net.URLCodec; + /** * A link is the Tapestry representation of a URL or URI that triggers dynamic behavior. This link is in three parts: a * path portion, an optional anchor, and a set of query parameters. A request for a link will ultimately be recognized @@ -32,7 +32,7 @@ * Returns the names of any additional query parameters for the URI. Query parameters store less regular or less * often used values that can not be expressed in the path. They also are used to store, or link to, persistent * state. - * + * * @return list of query parameter names, is alphabetical order */ List<String> getParameterNames(); @@ -40,7 +40,7 @@ /** * Returns the value of a specifically named query parameter, or <tt>null</tt> if no such query parameter is stored * in the link. - * + * * @return the value of the named parameter */ String getParameterValue(String name); @@ -48,18 +48,45 @@ /** * Adds a parameter value. The value will be added, as is, to the URL. In many cases, the value should be URL * encoded via {...@link URLCodec}. - * - * @param parameterName the name of the parameter to store - * @param value the value to store - * @throws IllegalArgumentException if the link already has a parameter with the given name + * + * @param parameterName + * the name of the parameter to store + * @param value + * the value to store + * @throws IllegalArgumentException + * if the link already has a parameter with the given name */ void addParameter(String parameterName, String value); /** + * Removes a parameter value, which is occasionally useful when transforming a parameter into a portion of + * the path. + * + * @since 5.2.0 + */ + void removeParameter(String parameterName); + + /** + * Returns the completely unadorned base path. Other methods (such as {...@link #toURI()}), may append + * an anchor or query parameters. + * + * @since 5.2.0 + */ + String getBasePath(); + + /** + * Creates a copy of this link that has the same parameters, anchor, and other attributes, but a different + * {...@linkplain #getBasePath() base path}. + * + * @since 5.2.0 + */ + Link copyWithBasePath(String basePath); + + /** * Returns the URI portion of the link. When the link is created for a form, this will not include query parameters. - * This is the same value returned from toString(). In some circumstances, this may be a relative URI (relative to + * This is the same value returned from toString(). In some circumstances, this may be a relative URI (relative to * the current Request's URI). - * + * * @return the URI, ready to be added as an element attribute */ String toURI(); @@ -71,22 +98,23 @@ /** * Returns the link anchor. If this link does not have an anchor, this method returns <tt>null</tt>. - * + * * @return the link anchor */ String getAnchor(); /** * Sets the link anchor. Null and empty anchors will be ignored when building the link URI. - * - * @param anchor the link anchor + * + * @param anchor + * the link anchor */ void setAnchor(String anchor); /** * Converts the link to an absolute URI, a complete path, starting with a leading slash. This is necessary in many * cases for client-side JavaScript that must send a request to application via XMLHttpRequest. - * + * * @return the complete URI (not abbreviated relative to the current request path) */ String toAbsoluteURI(); Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PageCallback.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PageCallback.java?rev=916878&r1=916877&r2=916878&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PageCallback.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PageCallback.java Sat Feb 27 00:15:54 2010 @@ -67,7 +67,7 @@ if (hasActivationContext()) return String.format("PageCallback[%s %s]", pageName, activationContextDescription()); - return String.format("PageCallback[%s]"); + return String.format("PageCallback[%s]", pageName); } /** Does the activation context have any values? Used, typically, inside an override of {...@link #toString()}. */ Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LinkImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LinkImpl.java?rev=916878&r1=916877&r2=916878&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LinkImpl.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LinkImpl.java Sat Feb 27 00:15:54 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, @@ -27,7 +27,7 @@ { private Map<String, String> parameters; - private final String absoluteURI; + private final String basePath; private final boolean optimizable; @@ -39,16 +39,32 @@ private String anchor; - public LinkImpl(String absoluteURI, boolean optimizable, boolean forForm, Response response, - RequestPathOptimizer optimizer) + public LinkImpl(String basePath, boolean optimizable, boolean forForm, Response response, + RequestPathOptimizer optimizer) { - this.absoluteURI = absoluteURI; + this.basePath = basePath; this.optimizable = optimizable; this.forForm = forForm; this.response = response; this.optimizer = optimizer; } + public Link copyWithBasePath(String basePath) + { + Defense.notNull(basePath, "basePath"); + + LinkImpl copy = new LinkImpl(basePath, optimizable, forForm, response, optimizer); + + copy.anchor = anchor; + + for (String name : getParameterNames()) + { + copy.addParameter(name, parameters.get(name)); + } + + return copy; + } + public void addParameter(String parameterName, String value) { Defense.notBlank(parameterName, "parameterName"); @@ -60,6 +76,19 @@ parameters.put(parameterName, value); } + public String getBasePath() + { + return basePath; + } + + public void removeParameter(String parameterName) + { + Defense.notBlank(parameterName, "parameterName"); + + if (parameters != null) + parameters.remove(parameterName); + } + public String getAnchor() { return anchor; @@ -102,9 +131,7 @@ private String appendAnchor(String path) { - return InternalUtils.isBlank(anchor) - ? path - : path + "#" + anchor; + return InternalUtils.isBlank(anchor) ? path : path + "#" + anchor; } /** @@ -116,22 +143,21 @@ return toURI(); } - /** * Extends the absolute path with any query parameters. Query parameters are never added to a forForm link. - * + * * @return absoluteURI appended with query parameters */ private String buildURI() { if (forForm || parameters == null) - return absoluteURI; + return basePath; - StringBuilder builder = new StringBuilder(absoluteURI.length() * 2); + StringBuilder builder = new StringBuilder(basePath.length() * 2); - builder.append(absoluteURI); + builder.append(basePath); - String sep = absoluteURI.contains("?") ? "&" : "?"; + String sep = basePath.contains("?") ? "&" : "?"; for (String name : getParameterNames()) { Modified: 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=916878&r1=916877&r2=916878&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/URLRewriterLinkEncoderInterceptor.java Sat Feb 27 00:15:54 2010 @@ -111,40 +111,26 @@ private Link rewriteIfNeeded(Link link, URLRewriteContext context, boolean forForm) { - SimpleRequestWrapper fakeRequest = new SimpleRequestWrapper(request, link.toAbsoluteURI()); + SimpleRequestWrapper fakeRequest = new SimpleRequestWrapper(request, link.getBasePath()); 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(); + if (fakeRequest == rewritten) + return link; - String rewrittenServerName = rewritten.getServerName(); + String originalServerName = request.getServerName(); - boolean absolute = originalServerName.equals(rewrittenServerName) == false; + String rewrittenServerName = rewritten.getServerName(); - String newPath = rewritten.getPath(); + boolean absolute = originalServerName.equals(rewrittenServerName) == false; - String newUrl = absolute ? fullUrl(rewritten) : newPath; + String newPath = rewritten.getPath(); - Link replacement = new LinkImpl(newUrl, false, forForm, response, null); + String baseURI = absolute ? fullUrl(rewritten) : newPath; - 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)); - } + return link.copyWithBasePath(baseURI); } private String fullUrl(Request request) Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/LinkImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/LinkImplTest.java?rev=916878&r1=916877&r2=916878&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/LinkImplTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/LinkImplTest.java Sat Feb 27 00:15:54 2010 @@ -1,10 +1,10 @@ -// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation +// Copyright 2006, 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, @@ -102,7 +102,6 @@ verify(); } - @Test public void force_absolute_uri() { @@ -113,33 +112,65 @@ replay(); - Link link = new LinkImpl("/ctx/foo", true, false, response, optimizer); assertEquals(link.toAbsoluteURI(), ENCODED); - verify(); } @Test public void to_uri_with_added_parameters_and_on_construction_uri() { - RequestPathOptimizer optimizer = mockRequestPathOptimizer(); - Response response = mockResponse(); - - String expectedURI = "/ctx/foo?foo=bar&baz=barney"; - train_encodeURL(response, expectedURI, expectedURI); - - replay(); - - - Link link = new LinkImpl("/ctx/foo?foo=bar", false, false, response, optimizer); - link.addParameter("baz", "barney"); - - assertEquals(link.toURI(), expectedURI); - - - verify(); + RequestPathOptimizer optimizer = mockRequestPathOptimizer(); + Response response = mockResponse(); + + String expectedURI = "/ctx/foo?foo=bar&baz=barney"; + train_encodeURL(response, expectedURI, expectedURI); + + replay(); + + Link link = new LinkImpl("/ctx/foo?foo=bar", false, false, response, optimizer); + link.addParameter("baz", "barney"); + + assertEquals(link.toURI(), expectedURI); + + verify(); + } + + @Test + public void new_base_uri() + { + RequestPathOptimizer optimizer = mockRequestPathOptimizer(); + Response response = mockResponse(); + + String expectedURI = "/ctx/baz?baz=barney"; + train_encodeURL(response, expectedURI, expectedURI); + + replay(); + + Link link = new LinkImpl("/ctx/foo", false, false, response, optimizer); + link.addParameter("baz", "barney"); + link.setAnchor("jacob"); + + Link copy = link.copyWithBasePath("/ctx/baz"); + + assertEquals(copy.toURI(), expectedURI + "#jacob"); + + verify(); + } + + @Test + public void remove_parameter() + { + Link link = new LinkImpl("/baseURI", false, false, null, null); + + link.addParameter("fred", "flintstone"); + link.addParameter("barney", "rubble"); + + link.removeParameter("fred"); + + assertNull(link.getParameterValue("fred")); + assertListsEquals(link.getParameterNames(), "barney"); } }