Updated Branches:
  refs/heads/master 7934dbf93 -> 0aaea4354

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/0aaea435
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/0aaea435
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/0aaea435

Branch: refs/heads/master
Commit: 0aaea43541563ebe840636cd807420db09f7e26d
Parents: d3a26f7
Author: martin-g <[email protected]>
Authored: Mon Jan 16 13:57:42 2012 +0100
Committer: martin-g <[email protected]>
Committed: Mon Jan 16 14:27:18 2012 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/wicket/Application.java   |    5 +-
 .../src/main/java/org/apache/wicket/Session.java   |    9 +-
 .../wicket/ajax/res/js/wicket-ajax-jquery.js       |   44 +--
 .../wicket/markup/head/JavaScriptHeaderItem.java   |    8 +-
 .../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   |  325 ++++++++-------
 .../request/cycle/RequestCycleUrlForTest.java      |  200 +++++++++
 11 files changed, 448 insertions(+), 232 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/0aaea435/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 31831e6..47a69ab 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -1645,7 +1645,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/0aaea435/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 6e574ef..24258b1 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/0aaea435/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js 
b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
index 539b56b..feb5c0e 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
+++ 
b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
@@ -1743,7 +1743,7 @@
                        // is an element in head that is of same type as 
myElement, and whose src
                        // attribute is same as myElement.src.
                        containsElement: function (element, mandatoryAttribute) 
{
-                               var attr = 
Wicket.Head._stripJSessionId(element.getAttribute(mandatoryAttribute));
+                               var attr = 
element.getAttribute(mandatoryAttribute);
                                if (isUndef(attr) || attr === "") {
                                        return false;
                                }
@@ -1764,9 +1764,8 @@
                                        // 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;
                                                }
@@ -1775,43 +1774,6 @@
                                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-4312
-                       _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/0aaea435/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
index d61efcd..aaa3d9c 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/head/JavaScriptHeaderItem.java
@@ -19,6 +19,7 @@ package org.apache.wicket.markup.head;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.string.JavaScriptUtils;
 import org.apache.wicket.util.string.Strings;
 
@@ -203,11 +204,8 @@ public abstract class JavaScriptHeaderItem extends 
HeaderItem
        protected static void internalRenderJavaScriptReference(Response 
response, 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");
 
-               JavaScriptUtils.writeJavaScriptUrl(response, url, id, defer, 
charset);
+               JavaScriptUtils.writeJavaScriptUrl(response, 
Strings.stripJSessionId(url), id, defer, charset);
        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/0aaea435/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 94f295c..32103aa 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
@@ -40,8 +40,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;
@@ -450,7 +453,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);
        }
 
        /**
@@ -469,7 +473,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);
        }
 
        /**
@@ -483,14 +489,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/0aaea435/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 0f38e74..80dc89b 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)
         */
        @Override
        public void detach(IRequestCycle requestCycle)
@@ -100,7 +100,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)
         */
        @Override
        public void respond(IRequestCycle requestCycle)

http://git-wip-us.apache.org/repos/asf/wicket/blob/0aaea435/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 7f97bfc..09537e2 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)
         */
        @Override
        public void respond(final IRequestCycle requestCycle)
@@ -79,7 +76,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)
         */
        @Override
        public void detach(IRequestCycle requestCycle)

http://git-wip-us.apache.org/repos/asf/wicket/blob/0aaea435/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 b376d1c..66bbfd7 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/0aaea435/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 3a78942..b55b405 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)
                {
@@ -499,6 +497,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/0aaea435/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 fc84c48..c4bcc43 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
@@ -47,166 +47,167 @@ import org.junit.Test;
  */
 public class HeaderResponseTest
 {
-       private static final String RESOURCE_NAME = "resource.name";
-
-       private IHeaderResponse headerResponse;
-
-       private ResourceReference reference;
-
-       /**
-        * Prepare
-        */
-       @Before
-       public void before()
-       {
-               final Response realResponse = new StringResponse();
-
-               headerResponse = new HeaderResponse()
-               {
-                       @Override
-                       protected Response getRealResponse()
-                       {
-                               return realResponse;
-                       }
-               };
-
-               reference = new ResourceReference("testReference")
-               {
-                       private static final long serialVersionUID = 1L;
-
-                       @Override
-                       public IResource getResource()
-                       {
-                               return null;
-                       }
-               };
-
-               RequestCycle requestCycle = mock(RequestCycle.class);
-               
when(requestCycle.urlFor(any(IRequestHandler.class))).thenReturn(RESOURCE_NAME);
-
-               Request request = mock(Request.class);
-               when(request.getCharset()).thenReturn(Charset.defaultCharset());
-               when(requestCycle.getRequest()).thenReturn(request);
-
-               UrlRenderer urlRenderer = mock(UrlRenderer.class);
-               
when(urlRenderer.renderContextRelativeUrl((any(String.class)))).thenReturn(RESOURCE_NAME);
-               when(requestCycle.getUrlRenderer()).thenReturn(urlRenderer);
-
-               ThreadContext.setRequestCycle(requestCycle);
-       }
-
-       /**
-        * Tear down
-        */
-       @After
-       public void after()
-       {
-               ThreadContext.setRequestCycle(null);
-       }
-
-       /**
-        * Tests the creation of a proper IE conditional comment
-        */
-       @Test
-       public void conditionalRenderCSSReference()
-       {
-               headerResponse.render(CssHeaderItem.forReference(reference, 
null, "screen", "lt IE 8"));
-               String expected = "<!--[if lt IE 8]><link rel=\"stylesheet\" 
type=\"text/css\" href=\"" +
-                       RESOURCE_NAME + "\" media=\"screen\" /><![endif]-->\n";
-               String actual = headerResponse.getResponse().toString();
-               Assert.assertEquals(expected, actual);
-       }
-
-       /**
-        * Tests the creation of a proper IE conditional comment
-        */
-       @Test
-       public void conditionalRenderCSSReferenceWithUrl()
-       {
-               headerResponse.render(CssHeaderItem.forUrl("resource.css", 
"screen", "lt IE 8"));
-               String expected = "<!--[if lt IE 8]><link rel=\"stylesheet\" 
type=\"text/css\" href=\"" +
-                       RESOURCE_NAME + "\" media=\"screen\" /><![endif]-->\n";
-               String actual = headerResponse.getResponse().toString();
-               Assert.assertEquals(expected, actual);
-       }
-
-       /**
-        * Tests setting of 'defer' attribute
-        * <p>
-        * WICKET-3661
-        */
-       @Test
-       public void deferJavaScriptReference()
-       {
-               boolean defer = true;
-               
headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", "some-id", 
defer));
-               String expected = "<script type=\"text/javascript\" 
id=\"some-id\" defer=\"defer\" src=\"" +
-                       RESOURCE_NAME + "\"></script>\n";
-               String actual = headerResponse.getResponse().toString();
-               Assert.assertEquals(expected, actual);
-       }
-
-       /**
-        * Tests non-setting of 'defer' attribute
-        * <p>
-        * WICKET-3661
-        */
-       @Test
-       public void deferFalseJavaScriptReference()
-       {
-               boolean defer = false;
-               
headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", "some-id", 
defer));
-               String expected = "<script type=\"text/javascript\" 
id=\"some-id\" src=\"" + RESOURCE_NAME +
-                       "\"></script>\n";
-               String actual = headerResponse.getResponse().toString();
-               Assert.assertEquals(expected, actual);
-       }
-
-       /**
-        * Tests setting of 'charset' attribute
-        * <p>
-        * WICKET-3909
-        */
-       @Test
-       public void charsetSetJavaScriptReference()
-       {
-               String charset = "foo";
-               
headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", "some-id", 
false,
-                       charset));
-               String expected = "<script type=\"text/javascript\" 
id=\"some-id\" charset=\"" + charset +
-                       "\" src=\"" + RESOURCE_NAME + "\"></script>\n";
-               String actual = headerResponse.getResponse().toString();
-               Assert.assertEquals(expected, actual);
-       }
-
-       /**
-        * Tests non-setting of 'charset' attribute
-        * <p>
-        * WICKET-3909
-        */
-       @Test
-       public void charsetNotSetJavaScriptReference()
-       {
-               
headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", "some-id", 
false, null));
-               String expected = "<script type=\"text/javascript\" 
id=\"some-id\" src=\"" + RESOURCE_NAME +
-                       "\"></script>\n";
-               String actual = headerResponse.getResponse().toString();
-               Assert.assertEquals(expected, actual);
-       }
-
-       /**
-        * https://issues.apache.org/jira/browse/WICKET-4312
-        */
-       @Test
-       public void preserveJSessionId() {
-               WicketTester tester = new WicketTester();
-               try {
-                       
headerResponse.render(JavaScriptHeaderItem.forUrl("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 actual = headerResponse.getResponse().toString();
-                       Assert.assertEquals(expected, actual);
-               } finally {
-                       tester.destroy();
-               }
-       }
+    private static final String RESOURCE_NAME = "resource.name";
+
+    private IHeaderResponse headerResponse;
+
+    private ResourceReference reference;
+
+    /**
+     * Prepare
+     */
+    @Before
+    public void before()
+    {
+        final Response realResponse = new StringResponse();
+
+        headerResponse = new HeaderResponse()
+        {
+            @Override
+            protected Response getRealResponse()
+            {
+                return realResponse;
+            }
+        };
+
+        reference = new ResourceReference("testReference")
+        {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IResource getResource()
+            {
+                return null;
+            }
+        };
+
+        RequestCycle requestCycle = mock(RequestCycle.class);
+        
when(requestCycle.urlFor(any(IRequestHandler.class))).thenReturn(RESOURCE_NAME);
+
+        Request request = mock(Request.class);
+        when(request.getCharset()).thenReturn(Charset.defaultCharset());
+        when(requestCycle.getRequest()).thenReturn(request);
+
+        UrlRenderer urlRenderer = mock(UrlRenderer.class);
+        
when(urlRenderer.renderContextRelativeUrl((any(String.class)))).thenReturn(RESOURCE_NAME);
+        when(requestCycle.getUrlRenderer()).thenReturn(urlRenderer);
+
+        ThreadContext.setRequestCycle(requestCycle);
+    }
+
+    /**
+     * Tear down
+     */
+    @After
+    public void after()
+    {
+        ThreadContext.setRequestCycle(null);
+    }
+
+    /**
+     * Tests the creation of a proper IE conditional comment
+     */
+    @Test
+    public void conditionalRenderCSSReference()
+    {
+        headerResponse.render(CssHeaderItem.forReference(reference, null, 
"screen", "lt IE 8"));
+        String expected = "<!--[if lt IE 8]><link rel=\"stylesheet\" 
type=\"text/css\" href=\"" +
+            RESOURCE_NAME + "\" media=\"screen\" /><![endif]-->\n";
+        String actual = headerResponse.getResponse().toString();
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Tests the creation of a proper IE conditional comment
+     */
+    @Test
+    public void conditionalRenderCSSReferenceWithUrl()
+    {
+        headerResponse.render(CssHeaderItem.forUrl("resource.css", "screen", 
"lt IE 8"));
+        String expected = "<!--[if lt IE 8]><link rel=\"stylesheet\" 
type=\"text/css\" href=\"" +
+            RESOURCE_NAME + "\" media=\"screen\" /><![endif]-->\n";
+        String actual = headerResponse.getResponse().toString();
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Tests setting of 'defer' attribute
+     * <p>
+     * WICKET-3661
+     */
+    @Test
+    public void deferJavaScriptReference()
+    {
+        boolean defer = true;
+        headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", 
"some-id", defer));
+        String expected = "<script type=\"text/javascript\" id=\"some-id\" 
defer=\"defer\" src=\"" +
+            RESOURCE_NAME + "\"></script>\n";
+        String actual = headerResponse.getResponse().toString();
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Tests non-setting of 'defer' attribute
+     * <p>
+     * WICKET-3661
+     */
+    @Test
+    public void deferFalseJavaScriptReference()
+    {
+        boolean defer = false;
+        headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", 
"some-id", defer));
+        String expected = "<script type=\"text/javascript\" id=\"some-id\" 
src=\"" + RESOURCE_NAME +
+            "\"></script>\n";
+        String actual = headerResponse.getResponse().toString();
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Tests setting of 'charset' attribute
+     * <p>
+     * WICKET-3909
+     */
+    @Test
+    public void charsetSetJavaScriptReference()
+    {
+        String charset = "foo";
+        headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", 
"some-id", false,
+            charset));
+        String expected = "<script type=\"text/javascript\" id=\"some-id\" 
charset=\"" + charset +
+            "\" src=\"" + RESOURCE_NAME + "\"></script>\n";
+        String actual = headerResponse.getResponse().toString();
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * Tests non-setting of 'charset' attribute
+     * <p>
+     * WICKET-3909
+     */
+    @Test
+    public void charsetNotSetJavaScriptReference()
+    {
+        headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js", 
"some-id", false, null));
+        String expected = "<script type=\"text/javascript\" id=\"some-id\" 
src=\"" + RESOURCE_NAME +
+            "\"></script>\n";
+        String actual = headerResponse.getResponse().toString();
+        Assert.assertEquals(expected, actual);
+    }
+
+    /**
+     * https://issues.apache.org/jira/browse/WICKET-4334
+     * https://issues.apache.org/jira/browse/WICKET-4312
+     */
+    @Test
+    public void doNotPreserveJSessionId() {
+        WicketTester tester = new WicketTester();
+        try {
+            
headerResponse.render(JavaScriptHeaderItem.forUrl("js-resource.js;jsessionid=1h402r54r4xuep32znicouftm",
 "some-id", false, null));
+            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 {
+            tester.destroy();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/0aaea435/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..b779521
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.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");
+               }
+       }
+}

Reply via email to