You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2012/01/16 13:58:12 UTC
git commit: WICKET-4334 Prevent Wicket from causing redundant
download of stateless resources (.js, .css etc.,
) on browser with cookies enabled
Updated Branches:
refs/heads/wicket-1.5.x 2e5a73773 -> bb87eb516
WICKET-4334
Prevent Wicket from causing redundant download of stateless resources (.js, .css etc.,) on browser with cookies enabled
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/bb87eb51
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/bb87eb51
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/bb87eb51
Branch: refs/heads/wicket-1.5.x
Commit: bb87eb516e2da9f7a255210f96cbca8251b13fcd
Parents: 2e5a737
Author: martin-g <mg...@apache.org>
Authored: Mon Jan 16 13:57:42 2012 +0100
Committer: martin-g <mg...@apache.org>
Committed: Mon Jan 16 13:57:42 2012 +0100
----------------------------------------------------------------------
.../main/java/org/apache/wicket/Application.java | 5 +-
.../src/main/java/org/apache/wicket/Session.java | 9 +-
.../java/org/apache/wicket/ajax/wicket-ajax.js | 44 +----
.../markup/html/internal/HeaderResponse.java | 16 +-
.../apache/wicket/request/cycle/RequestCycle.java | 41 +++-
.../resource/ResourceReferenceRequestHandler.java | 4 +-
.../handler/resource/ResourceRequestHandler.java | 7 +-
.../request/mapper/BufferedResponseMapper.java | 18 ++-
.../wicket/request/resource/PackageResource.java | 19 ++-
.../markup/html/internal/HeaderResponseTest.java | 5 +-
.../request/cycle/RequestCycleUrlForTest.java | 184 +++++++++++++++
11 files changed, 275 insertions(+), 77 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/Application.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java b/wicket-core/src/main/java/org/apache/wicket/Application.java
index 3934826..4937b79 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -1593,7 +1593,10 @@ public abstract class Application implements UnboundListener, IEventSink
@Override
public void onDetach(final RequestCycle requestCycle)
{
- Session.get().getPageManager().commitRequest();
+ if (Session.exists())
+ {
+ Session.get().getPageManager().commitRequest();
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/Session.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Session.java b/wicket-core/src/main/java/org/apache/wicket/Session.java
index 765db75..ccc014c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Session.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Session.java
@@ -49,9 +49,6 @@ import org.slf4j.LoggerFactory;
* Holds information about a user session, including some fixed number of most recent pages (and all
* their nested component information).
* <ul>
- * <li><b>Access via RequestCycle </b>- The Session for a {@link RequestCycle} can be retrieved by
- * calling {@link RequestCycle#getSession()}.
- *
* <li><b>Access via Component </b>- If a RequestCycle object is not available, the Session can be
* retrieved for a Component by calling {@link Component#getSession()}. As currently implemented,
* each Component does not itself have a reference to the session that contains it. However, the
@@ -162,7 +159,7 @@ public abstract class Session implements IClusterable, IEventSink
/**
* Cached instance of agent info which is typically designated by calling
- * {@link RequestCycle#newClientInfo()}.
+ * {@link Session#getClientInfo()}.
*/
protected ClientInfo clientInfo;
@@ -841,9 +838,7 @@ public abstract class Session implements IClusterable, IEventSink
/**
* Returns the {@link IPageManager} instance.
- *
- * @see #newPageManager()
- *
+ *
* @return {@link IPageManager} instance.
*/
public final IPageManager getPageManager()
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/wicket-ajax.js b/wicket-core/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
index 8d412ec..37f3049 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
@@ -1801,7 +1801,7 @@ Wicket.Head.addElement = function(element) {
// is an element in head that is of same type as myElement, and whose src
// attribute is same as myElement.src.
Wicket.Head.containsElement = function(element, mandatoryAttribute) {
- var attr = Wicket.Head.stripJSessionId(element.getAttribute(mandatoryAttribute));
+ var attr = element.getAttribute(mandatoryAttribute);
if (attr == null || attr == "" || typeof(attr) == "undefined")
return false;
@@ -1820,8 +1820,8 @@ Wicket.Head.containsElement = function(element, mandatoryAttribute) {
// this is necessary for filtering script references
if (node.tagName.toLowerCase() == element.tagName.toLowerCase()) {
- var loadedUrl = Wicket.Head.stripJSessionId(node.getAttribute(mandatoryAttribute));
- var loadedUrl_ = Wicket.Head.stripJSessionId(node.getAttribute(mandatoryAttribute+"_"));
+ var loadedUrl = node.getAttribute(mandatoryAttribute);
+ var loadedUrl_ = node.getAttribute(mandatoryAttribute+"_");
if (loadedUrl == attr || loadedUrl_ == attr) {
return true;
}
@@ -1830,44 +1830,6 @@ Wicket.Head.containsElement = function(element, mandatoryAttribute) {
return false;
}
-/**
- * Removes the optional ';jsessionid=...' from the passed url
- *
- * @param {String} url the url to strip the jsessionid from
- * @return {String} the url without the jsessionid and its value
- */
- // WICKET-3596
-Wicket.Head.stripJSessionId = function(url) {
- if (url == null)
- {
- return null;
- }
-
- // http://.../abc;jsessionid=...?param=...
- var ixSemiColon = url.indexOf(";");
- if (ixSemiColon == -1)
- {
- return url;
- }
-
- var ixQuestionMark = url.indexOf("?");
- if (ixQuestionMark == -1)
- {
- // no query paramaters; cut off at ";"
- // http://.../abc;jsession=...
- return url.substring(0, ixSemiColon);
- }
-
- if (ixQuestionMark <= ixSemiColon)
- {
- // ? is before ; - no jsessionid in the url
- return url;
- }
-
- return url.substring(0, ixSemiColon) + url.substring(ixQuestionMark);
-}
-
-
// Adds a javascript element to page header.
// The fakeSrc attribute is used to filter out duplicate javascript references.
// External javascripts are loaded using xmlhttprequest. Then a javascript element is created and the
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HeaderResponse.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HeaderResponse.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HeaderResponse.java
index 1d4de09..7817d46 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HeaderResponse.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/internal/HeaderResponse.java
@@ -128,10 +128,8 @@ public abstract class HeaderResponse implements IHeaderResponse
private void internalRenderCSSReference(final String url, final String media,
final String condition)
{
- if (Strings.isEmpty(url))
- {
- throw new IllegalArgumentException("url cannot be empty or null");
- }
+ Args.notEmpty(url, "url");
+
if (!closed)
{
String urlWoSessionId = Strings.stripJSessionId(url);
@@ -145,7 +143,7 @@ public abstract class HeaderResponse implements IHeaderResponse
getResponse().write("]>");
}
getResponse().write("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
- getResponse().write(url);
+ getResponse().write(urlWoSessionId);
getResponse().write("\"");
if (media != null)
{
@@ -230,10 +228,8 @@ public abstract class HeaderResponse implements IHeaderResponse
private void internalRenderJavaScriptReference(String url, String id, boolean defer,
String charset)
{
- if (Strings.isEmpty(url))
- {
- throw new IllegalArgumentException("url cannot be empty or null");
- }
+ Args.notEmpty(url, "url");
+
if (!closed)
{
String urlWoSessionId = Strings.stripJSessionId(url);
@@ -246,7 +242,7 @@ public abstract class HeaderResponse implements IHeaderResponse
if (token1Unused && token2Unused)
{
- JavaScriptUtils.writeJavaScriptUrl(getResponse(), url, id, defer,
+ JavaScriptUtils.writeJavaScriptUrl(getResponse(), urlWoSessionId, id, defer,
charset);
markRendered(token1);
if (token2 != null)
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java b/wicket-core/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
index 73a3463..592b1b9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
@@ -41,8 +41,11 @@ import org.apache.wicket.request.handler.IPageProvider;
import org.apache.wicket.request.handler.PageProvider;
import org.apache.wicket.request.handler.RenderPageRequestHandler;
import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.handler.resource.ResourceRequestHandler;
import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
import org.apache.wicket.util.lang.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -449,7 +452,8 @@ public class RequestCycle implements IRequestCycle, IEventSink
*/
public final CharSequence urlFor(ResourceReference reference, PageParameters params)
{
- return renderUrl(mapUrlFor(reference, params));
+ ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference, params);
+ return renderUrl(mapUrlFor(handler), handler);
}
/**
@@ -468,7 +472,9 @@ public class RequestCycle implements IRequestCycle, IEventSink
public final <C extends Page> CharSequence urlFor(final Class<C> pageClass,
final PageParameters parameters)
{
- return renderUrl(mapUrlFor(pageClass, parameters));
+ IRequestHandler handler = new BookmarkablePageRequestHandler(new PageProvider(pageClass,
+ parameters));
+ return renderUrl(mapUrlFor(handler), handler);
}
/**
@@ -482,14 +488,39 @@ public class RequestCycle implements IRequestCycle, IEventSink
*/
public CharSequence urlFor(IRequestHandler handler)
{
- return renderUrl(mapUrlFor(handler));
+ Url mappedUrl = mapUrlFor(handler);
+ CharSequence url = renderUrl(mappedUrl, handler);
+ return url;
}
- private String renderUrl(Url url)
+ private String renderUrl(Url url, IRequestHandler handler)
{
if (url != null)
{
- return getOriginalResponse().encodeURL(getUrlRenderer().renderUrl(url));
+ String renderedUrl = getUrlRenderer().renderUrl(url);
+ if (handler instanceof ResourceReferenceRequestHandler)
+ {
+ ResourceReferenceRequestHandler rrrh = (ResourceReferenceRequestHandler) handler;
+ IResource resource = rrrh.getResource();
+ if (resource instanceof IStaticCacheableResource == false)
+ {
+ renderedUrl = getOriginalResponse().encodeURL(renderedUrl);
+ }
+ }
+ else if (handler instanceof ResourceRequestHandler)
+ {
+ ResourceRequestHandler rrh = (ResourceRequestHandler) handler;
+ IResource resource = rrh.getResource();
+ if (resource instanceof IStaticCacheableResource == false)
+ {
+ renderedUrl = getOriginalResponse().encodeURL(renderedUrl);
+ }
+ }
+ else
+ {
+ renderedUrl = getOriginalResponse().encodeURL(renderedUrl);
+ }
+ return renderedUrl;
}
else
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceReferenceRequestHandler.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceReferenceRequestHandler.java b/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceReferenceRequestHandler.java
index 3aa0fa8..92d2822 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceReferenceRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceReferenceRequestHandler.java
@@ -82,7 +82,7 @@ public class ResourceReferenceRequestHandler implements IRequestHandler, ILoggab
}
/**
- * @see org.apache.org.apache.wicket.request.IRequestHandler#detach(org.apache.wicket.request.cycle.RequestCycle)
+ * @see org.apache.wicket.request.IRequestHandler#detach(org.apache.wicket.request.IRequestCycle)
*/
public void detach(IRequestCycle requestCycle)
{
@@ -98,7 +98,7 @@ public class ResourceReferenceRequestHandler implements IRequestHandler, ILoggab
/**
- * @see org.apache.org.apache.wicket.request.IRequestHandler#respond(org.apache.wicket.request.cycle.RequestCycle)
+ * @see org.apache.wicket.request.IRequestHandler#respond(org.apache.wicket.request.IRequestCycle)
*/
public void respond(IRequestCycle requestCycle)
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceRequestHandler.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceRequestHandler.java b/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceRequestHandler.java
index a41b643..1c41ff8 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/handler/resource/ResourceRequestHandler.java
@@ -36,9 +36,6 @@ public class ResourceRequestHandler implements IRequestHandler
* Construct.
*
* @param resource
- * @param locale
- * @param style
- * @param variation
* @param pageParameters
*/
public ResourceRequestHandler(IResource resource, PageParameters pageParameters)
@@ -68,7 +65,7 @@ public class ResourceRequestHandler implements IRequestHandler
}
/**
- * @see org.apache.org.apache.wicket.request.IRequestHandler#respond(org.apache.wicket.request.cycle.RequestCycle)
+ * @see org.apache.wicket.request.IRequestHandler#respond(org.apache.wicket.request.IRequestCycle)
*/
public void respond(final IRequestCycle requestCycle)
{
@@ -78,7 +75,7 @@ public class ResourceRequestHandler implements IRequestHandler
}
/**
- * @see org.apache.org.apache.wicket.request.IRequestHandler#detach(org.apache.wicket.request.cycle.RequestCycle)
+ * @see org.apache.wicket.request.IRequestHandler#detach(org.apache.wicket.request.IRequestCycle)
*/
public void detach(IRequestCycle requestCycle)
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/request/mapper/BufferedResponseMapper.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/mapper/BufferedResponseMapper.java b/wicket-core/src/main/java/org/apache/wicket/request/mapper/BufferedResponseMapper.java
index 7e3240c..92dadbc 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/mapper/BufferedResponseMapper.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/mapper/BufferedResponseMapper.java
@@ -16,15 +16,18 @@
*/
package org.apache.wicket.request.mapper;
+import org.apache.wicket.Application;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.BufferedWebResponse;
import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.request.IRequestCycle;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.IRequestMapper;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Url;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.handler.BufferedResponseRequestHandler;
+import org.apache.wicket.session.ISessionStore;
import org.apache.wicket.util.string.Strings;
/**
@@ -47,7 +50,20 @@ public class BufferedResponseMapper implements IRequestMapper
*/
protected String getSessionId()
{
- return RequestCycle.get() != null ? Session.get().getId() : null;
+ String sessionId = null;
+
+ if (Application.exists() && RequestCycle.get() != null)
+ {
+ ISessionStore sessionStore = Application.get().getSessionStore();
+ IRequestCycle requestCycle = RequestCycle.get();
+ Session session = sessionStore.lookup(requestCycle.getRequest());
+ if (session != null)
+ {
+ sessionId = session.getId();
+ }
+ }
+
+ return sessionId;
}
protected boolean hasBufferedResponse(Url url)
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/main/java/org/apache/wicket/request/resource/PackageResource.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/request/resource/PackageResource.java b/wicket-core/src/main/java/org/apache/wicket/request/resource/PackageResource.java
index 461efd3..782c3c2 100644
--- a/wicket-core/src/main/java/org/apache/wicket/request/resource/PackageResource.java
+++ b/wicket-core/src/main/java/org/apache/wicket/request/resource/PackageResource.java
@@ -138,9 +138,7 @@ public class PackageResource extends AbstractResource implements IStaticCacheabl
// Convert resource path to absolute path relative to base package
absolutePath = Packages.absolutePath(scope, name);
- final String parentEscape = Application.get()
- .getResourceSettings()
- .getParentFolderPlaceholder();
+ final String parentEscape = getParentFolderPlaceholder();
if (Strings.isEmpty(parentEscape) == false)
{
@@ -530,6 +528,21 @@ public class PackageResource extends AbstractResource implements IStaticCacheabl
return true;
}
+ String getParentFolderPlaceholder()
+ {
+ String parentFolderPlaceholder;
+ if (Application.exists())
+ {
+ parentFolderPlaceholder = Application.get()
+ .getResourceSettings()
+ .getParentFolderPlaceholder();
+ } else
+ {
+ parentFolderPlaceholder = "..";
+ }
+ return parentFolderPlaceholder;
+ }
+
private static class CacheKey implements Serializable
{
private final String scopeName;
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/HeaderResponseTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/HeaderResponseTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/HeaderResponseTest.java
index 86299e2..311aa1d 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/HeaderResponseTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/HeaderResponseTest.java
@@ -191,14 +191,15 @@ public class HeaderResponseTest
}
/**
+ * https://issues.apache.org/jira/browse/WICKET-4334
* https://issues.apache.org/jira/browse/WICKET-4312
*/
@Test
- public void preserveJSessionId() {
+ public void doNotPreserveJSessionId() {
WicketTester tester = new WicketTester();
try {
headerResponse.renderJavaScriptReference("js-resource.js;jsessionid=1h402r54r4xuep32znicouftm", "some-id", false, null);
- String expected = "<script type=\"text/javascript\" id=\"some-id\" src=\"js-resource.js;jsessionid=1h402r54r4xuep32znicouftm\"></script>\n";
+ String expected = "<script type=\"text/javascript\" id=\"some-id\" src=\"js-resource.js\"></script>\n";
String actual = headerResponse.getResponse().toString();
Assert.assertEquals(expected, actual);
} finally {
http://git-wip-us.apache.org/repos/asf/wicket/blob/bb87eb51/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java b/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
new file mode 100644
index 0000000..13d43ba
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
@@ -0,0 +1,184 @@
+package org.apache.wicket.request.cycle;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.wicket.mock.MockHomePage;
+import org.apache.wicket.request.IExceptionMapper;
+import org.apache.wicket.request.IRequestMapper;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.handler.BookmarkablePageRequestHandler;
+import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.handler.resource.ResourceRequestHandler;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.ByteArrayResource;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
+import org.apache.wicket.response.StringResponse;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests that RequestCycle#urlFor() does not encode the jsessionid for static resources.
+ *
+ * https://issues.apache.org/jira/browse/WICKET-4334
+ */
+public class RequestCycleUrlForTest extends Assert
+{
+ private static final String JSESSIONID = ";jsessionid=1234567890";
+ private static final String BOOKMARKABLE_PAGE_URL = "/bookmarkablePage";
+ private static final String RES_REF_URL = "/resRef";
+ private static final String RESOURCE_URL = "/res";
+
+ RequestCycle requestCycle;
+
+ @Before
+ public void before()
+ {
+ Request request = mock(Request.class);
+ Response response = new StringResponse() {
+ @Override
+ public String encodeURL(CharSequence url)
+ {
+ return url + JSESSIONID;
+ }
+ };
+ IRequestMapper mapper = mock(IRequestMapper.class);
+
+ Url bookmarkablePageUrl = Url.parse(BOOKMARKABLE_PAGE_URL);
+ when(mapper.mapHandler(argThat(new ExactClassMatcher<BookmarkablePageRequestHandler>(BookmarkablePageRequestHandler.class)))).thenReturn(bookmarkablePageUrl);
+
+ Url resourceUrl = Url.parse(RESOURCE_URL);
+ when(mapper.mapHandler(argThat(new ExactClassMatcher<ResourceRequestHandler>(ResourceRequestHandler.class)))).thenReturn(resourceUrl);
+
+ Url resourceReferenceUrl = Url.parse(RES_REF_URL);
+ when(mapper.mapHandler(argThat(new ExactClassMatcher<ResourceReferenceRequestHandler>(ResourceReferenceRequestHandler.class)))).thenReturn(resourceReferenceUrl);
+
+ IExceptionMapper exceptionMapper = mock(IExceptionMapper.class);
+ RequestCycleContext context = new RequestCycleContext(request, response, mapper, exceptionMapper);
+
+ requestCycle = new RequestCycle(context);
+ }
+
+ /**
+ * Pages should have the jsessionid encoded in the url
+ *
+ * @throws Exception
+ */
+ @Test
+ public void urlForClass() throws Exception
+ {
+ CharSequence url = requestCycle.urlFor(MockHomePage.class, new PageParameters());
+ assertEquals("/bookmarkablePage"+JSESSIONID, url);
+ }
+
+ /**
+ * ResourceReference with IStaticCacheableResource should not have the jsessionid encoded in the url
+ *
+ * @throws Exception
+ */
+ @Test
+ public void urlForResourceReference() throws Exception
+ {
+ final IStaticCacheableResource resource = mock(IStaticCacheableResource.class);
+ ResourceReference reference = new ResourceReference("dummy")
+ {
+ @Override
+ public IResource getResource()
+ {
+ return resource;
+ }
+ };
+ ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference);
+ CharSequence url = requestCycle.urlFor(handler);
+ assertEquals(RES_REF_URL, url);
+ }
+
+ /**
+ * ResourceReference with non-IStaticCacheableResource should not have the jsessionid encoded in the url
+ *
+ * @throws Exception
+ */
+ @Test
+ public void urlForResourceReferenceWithNonStaticResource() throws Exception
+ {
+ final IResource resource = mock(IResource.class);
+ ResourceReference reference = new ResourceReference("dummy")
+ {
+ @Override
+ public IResource getResource()
+ {
+ return resource;
+ }
+ };
+ ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference);
+ CharSequence url = requestCycle.urlFor(handler);
+ assertEquals(RES_REF_URL+JSESSIONID, url);
+ }
+
+ /**
+ * IStaticCacheableResource should not have the jsessionid encoded in the url
+ *
+ * @throws Exception
+ */
+ @Test
+ public void urlForStaticResource() throws Exception
+ {
+ IStaticCacheableResource resource = mock(IStaticCacheableResource.class);
+ ResourceRequestHandler handler = new ResourceRequestHandler(resource, new PageParameters());
+ CharSequence url = requestCycle.urlFor(handler);
+ assertEquals(RESOURCE_URL, url);
+ }
+
+ /**
+ * Non-IStaticCacheableResource should have the jsessionid encoded in the url
+ *
+ * @throws Exception
+ */
+ @Test
+ public void urlForDynamicResource() throws Exception
+ {
+ ByteArrayResource resource = new ByteArrayResource(null, new byte[] {1, 2}, "test.bin");
+ ResourceRequestHandler handler = new ResourceRequestHandler(resource, new PageParameters());
+ CharSequence url = requestCycle.urlFor(handler);
+ assertEquals(RESOURCE_URL + JSESSIONID, url);
+ }
+
+ /**
+ * A matcher that matches only when the object class is exactly the same as the expected one.
+ *
+ * @param <T>
+ * the type of the expected class
+ */
+ private static class ExactClassMatcher<T> extends BaseMatcher<T>
+ {
+ private final Class<T> targetClass;
+
+ public ExactClassMatcher(Class<T> targetClass)
+ {
+ this.targetClass = targetClass;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object obj)
+ {
+ if (obj != null)
+ {
+ return targetClass.equals(obj.getClass());
+ }
+ return false;
+ }
+
+ public void describeTo(Description desc)
+ {
+ desc.appendText("Matches a class or subclass");
+ }
+ }
+}