WICKET-5446 Improve version matching in resource caching strategies

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/2bd971ad
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/2bd971ad
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/2bd971ad

Branch: refs/heads/sandbox/WICKET-4686
Commit: 2bd971ad723cd9ad2c10d868149d677dcb6abab3
Parents: a535cd3
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Tue Dec 17 11:18:02 2013 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Tue Dec 17 11:19:05 2013 +0200

----------------------------------------------------------------------
 ...enameWithVersionResourceCachingStrategy.java | 24 +++++++++----
 .../caching/version/CachingResourceVersion.java |  6 ++++
 .../caching/version/IResourceVersion.java       | 10 ++++++
 .../version/LastModifiedResourceVersion.java    | 13 +++++++
 .../version/MessageDigestResourceVersion.java   | 12 +++++++
 .../RequestCycleCachedResourceVersion.java      |  7 ++++
 .../caching/version/StaticResourceVersion.java  | 10 ++++++
 .../BasicResourceReferenceMapperTest.java       | 38 +++++++++++++++++++-
 .../ContextRelativeResourceCachingTest.java     |  2 +-
 ...eWithVersionResourceCachingStrategyTest.java | 18 ++++++++++
 10 files changed, 131 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategy.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategy.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategy.java
index 087ea13..0afd86c 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategy.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategy.java
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.request.resource.caching;
 
+import java.util.regex.Pattern;
+
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.http.WebResponse;
 import org.apache.wicket.request.resource.AbstractResource;
@@ -110,12 +112,6 @@ public class FilenameWithVersionResourceCachingStrategy 
implements IResourceCach
                // get undecorated filename
                final String filename = url.getFileName();
 
-               if (filename.contains(getVersionPrefix()))
-               {
-                       LOG.error("A resource with name '{}' contains the 
version prefix '{}' so the un-decoration will not work." +
-                                       " Either use a different version prefix 
or rename this resource.", filename, getVersionPrefix());
-               }
-
                // check if resource name has extension
                final int extensionAt = filename.lastIndexOf('.');
 
@@ -135,6 +131,14 @@ public class FilenameWithVersionResourceCachingStrategy 
implements IResourceCach
                {
                        versionedFilename.append(filename.substring(0, 
extensionAt));
                }
+
+               int pos = versionedFilename.indexOf(getVersionPrefix());
+               if (pos != -1 && isVersion(versionedFilename.substring(pos + 
versionPrefix.length())))
+               {
+                       LOG.error("A resource with name '{}' contains the 
version prefix '{}' so the un-decoration will not work." +
+                                       " Either use a different version prefix 
or rename this resource.", filename, getVersionPrefix());
+               }
+
                // add version suffix
                versionedFilename.append(versionPrefix);
                
@@ -168,7 +172,7 @@ public class FilenameWithVersionResourceCachingStrategy 
implements IResourceCach
                pos = fullname.lastIndexOf(versionPrefix);
 
                // remove version string if it exists
-               if (pos != -1)
+               if (pos != -1 && isVersion(fullname.substring(pos + 
versionPrefix.length())))
                {
                        // get filename before version string
                        final String basename = fullname.substring(0, pos);
@@ -188,6 +192,12 @@ public class FilenameWithVersionResourceCachingStrategy 
implements IResourceCach
                }
        }
 
+       private boolean isVersion(String substring)
+       {
+               Pattern versionPattern = resourceVersion.getVersionPattern();
+               return versionPattern == null || 
versionPattern.matcher(substring).matches();
+       }
+
        /**
         * set resource caching to maximum and set cache-visibility to 'public'
         * 

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/CachingResourceVersion.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/CachingResourceVersion.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/CachingResourceVersion.java
index f237446..a2639a1 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/CachingResourceVersion.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/CachingResourceVersion.java
@@ -19,6 +19,7 @@ package org.apache.wicket.request.resource.caching.version;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
 import org.apache.wicket.util.collections.MostRecentlyUsedMap;
@@ -134,6 +135,11 @@ public class CachingResourceVersion implements 
IResourceVersion
                return version;
        }
 
+       @Override
+       public Pattern getVersionPattern() {
+               return delegate.getVersionPattern();
+       }
+
        /**
         * remove cacheable resource from cache
         * 

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/IResourceVersion.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/IResourceVersion.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/IResourceVersion.java
index e4b92d1..f24124b 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/IResourceVersion.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/IResourceVersion.java
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.request.resource.caching.version;
 
+import java.util.regex.Pattern;
+
 import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
 
 /**
@@ -41,4 +43,12 @@ public interface IResourceVersion
         *         if version string could not be calculated
         */
        String getVersion(IStaticCacheableResource resource);
+
+       /**
+        * a pattern that matches returned versions
+        *
+        * @return a pattern or <code>null</code> if no pattern
+        *         is available
+        */
+       Pattern getVersionPattern();
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/LastModifiedResourceVersion.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/LastModifiedResourceVersion.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/LastModifiedResourceVersion.java
index d01a573..dcdbc6c 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/LastModifiedResourceVersion.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/LastModifiedResourceVersion.java
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.request.resource.caching.version;
 
+import java.util.regex.Pattern;
+
 import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.time.Time;
@@ -30,6 +32,11 @@ import org.apache.wicket.util.time.Time;
  */
 public class LastModifiedResourceVersion implements IResourceVersion
 {
+       /**
+        * A valid pattern is a sequence of digits
+        */
+       private static final Pattern TIMESTAMP_PATTERN = 
Pattern.compile("[0-9]+");
+
        @Override
        public String getVersion(IStaticCacheableResource resource)
        {
@@ -52,4 +59,10 @@ public class LastModifiedResourceVersion implements 
IResourceVersion
                // version string = last modified timestamp converted to 
milliseconds
                return String.valueOf(lastModified.getMilliseconds());
        }
+
+       @Override
+       public Pattern getVersionPattern()
+       {
+               return TIMESTAMP_PATTERN;
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/MessageDigestResourceVersion.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/MessageDigestResourceVersion.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/MessageDigestResourceVersion.java
index a320fd6..9652e05 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/MessageDigestResourceVersion.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/MessageDigestResourceVersion.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.regex.Pattern;
 
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
@@ -53,6 +54,11 @@ public class MessageDigestResourceVersion implements 
IResourceVersion
        private static final int DEFAULT_BUFFER_BYTES = 8192; // needed for 
javadoc {@value ..}
        private static final Bytes DEFAULT_BUFFER_SIZE = 
Bytes.bytes(DEFAULT_BUFFER_BYTES);
 
+       /**
+        * A valid pattern is a sequence of digits and upper cased English 
letters A-F
+        */
+       private static final Pattern DIGEST_PATTERN = 
Pattern.compile("[0-9A-F]+");
+
        /** 
         * message digest algorithm for computing hashes 
         */
@@ -153,6 +159,12 @@ public class MessageDigestResourceVersion implements 
IResourceVersion
                }
        }
 
+       @Override
+       public Pattern getVersionPattern()
+       {
+               return DIGEST_PATTERN;
+       }
+
        /**
         * get instance of message digest provider from JCA
         * 

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/RequestCycleCachedResourceVersion.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/RequestCycleCachedResourceVersion.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/RequestCycleCachedResourceVersion.java
index dbcec9d..e726858 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/RequestCycleCachedResourceVersion.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/RequestCycleCachedResourceVersion.java
@@ -18,6 +18,7 @@ package org.apache.wicket.request.resource.caching.version;
 
 import java.io.Serializable;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import org.apache.wicket.MetaDataKey;
 import org.apache.wicket.ThreadContext;
@@ -104,4 +105,10 @@ public class RequestCycleCachedResourceVersion implements 
IResourceVersion
                
                return version;
        }
+
+       @Override
+       public Pattern getVersionPattern()
+       {
+               return delegate.getVersionPattern();
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/StaticResourceVersion.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/StaticResourceVersion.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/StaticResourceVersion.java
index cefc700..5d4b941 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/StaticResourceVersion.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/caching/version/StaticResourceVersion.java
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.request.resource.caching.version;
 
+import java.util.regex.Pattern;
+
 import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
 import org.apache.wicket.util.lang.Args;
 
@@ -29,6 +31,7 @@ import org.apache.wicket.util.lang.Args;
 public class StaticResourceVersion implements IResourceVersion
 {
        private final String version;
+       private final Pattern pattern;
 
        /**
         * create static version provider
@@ -39,6 +42,7 @@ public class StaticResourceVersion implements IResourceVersion
        public StaticResourceVersion(String version)
        {
                this.version = Args.notNull(version, "version");
+               this.pattern = Pattern.compile(Pattern.quote(version));
        }
 
        @Override
@@ -46,4 +50,10 @@ public class StaticResourceVersion implements 
IResourceVersion
        {
                return version;
        }
+
+       @Override
+       public Pattern getVersionPattern()
+       {
+               return pattern;
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java
index 3e075e0..d7cce88 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/core/request/mapper/BasicResourceReferenceMapperTest.java
@@ -20,6 +20,7 @@ import static org.hamcrest.CoreMatchers.instanceOf;
 
 import java.io.Serializable;
 import java.util.Locale;
+import java.util.regex.Pattern;
 
 import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.request.Url;
@@ -34,9 +35,11 @@ import 
org.apache.wicket.request.resource.caching.IResourceCachingStrategy;
 import org.apache.wicket.request.resource.caching.IStaticCacheableResource;
 import org.apache.wicket.request.resource.caching.NoOpResourceCachingStrategy;
 import org.apache.wicket.request.resource.caching.ResourceUrl;
+import org.apache.wicket.request.resource.caching.version.IResourceVersion;
 import 
org.apache.wicket.request.resource.caching.version.StaticResourceVersion;
 import org.apache.wicket.util.IProvider;
 import org.apache.wicket.util.ValueProvider;
+import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.junit.Test;
@@ -501,7 +504,7 @@ public class BasicResourceReferenceMapperTest extends 
AbstractResourceReferenceM
                };
 
                IResourceCachingStrategy strategy = new 
FilenameWithVersionResourceCachingStrategy(
-                       "-version-", new StaticResourceVersion("foobar"));
+                       "-version-", new AlphaDigitResourceVersion("foobar"));
 
                INamedParameters params = new PageParameters();
                ResourceUrl url = new ResourceUrl("test.js", params);
@@ -550,6 +553,39 @@ public class BasicResourceReferenceMapperTest extends 
AbstractResourceReferenceM
        }
 
        /**
+        * A resource version that allows any of: alpha, digit, dash and dot 
charcters
+        */
+       private static class AlphaDigitResourceVersion implements 
IResourceVersion
+       {
+               private static final Pattern pattern = 
Pattern.compile("[0-9a-z-\\.]*");
+
+               private final String version;
+
+               /**
+                * create static version provider
+                *
+                * @param version
+                *             static version string to deliver for all queries 
resources
+                */
+               public AlphaDigitResourceVersion(String version)
+               {
+                       this.version = Args.notNull(version, "version");
+               }
+
+               @Override
+               public String getVersion(IStaticCacheableResource resource)
+               {
+                       return version;
+               }
+
+               @Override
+               public Pattern getVersionPattern()
+               {
+                       return pattern;
+               }
+       }
+
+       /**
         *
         */
        @Test

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/ContextRelativeResourceCachingTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/ContextRelativeResourceCachingTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/ContextRelativeResourceCachingTest.java
index 0821a38..3fdd8ee 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/ContextRelativeResourceCachingTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/ContextRelativeResourceCachingTest.java
@@ -98,7 +98,7 @@ public class ContextRelativeResourceCachingTest extends 
WicketTestCase
                ContextRelativeResource resource = new 
ContextRelativeResource("/style.css");
                init(resource, "/test/resource");
 
-               Request request = 
createRequest("test/resource-version-4711?bla=123");
+               Request request = 
createRequest("test/resource-version-123?bla=4567");
                final IRequestHandler handler = 
tester.getApplication().getRootRequestMapper()
                        .mapRequest(request);
                assertThat(handler, 
instanceOf(ResourceReferenceRequestHandler.class));

http://git-wip-us.apache.org/repos/asf/wicket/blob/2bd971ad/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategyTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategyTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategyTest.java
index 9ad3a7f..0c82205 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategyTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/request/resource/caching/FilenameWithVersionResourceCachingStrategyTest.java
@@ -49,6 +49,12 @@ public class FilenameWithVersionResourceCachingStrategyTest 
extends Assert
                strategy.decorateUrl(resourceUrl, new TestResource());
 
                
assertEquals("some-resource--vers--"+TEST_RESOURCE_VERSION+".txt", 
resourceUrl.getFileName());
+
+               // don't issue an error
+               resourceUrl = new 
ResourceUrl("some-resource--vers--with-prefix.txt", new PageParameters());
+               strategy.decorateUrl(resourceUrl, new TestResource());
+
+               
assertEquals("some-resource--vers--with-prefix--vers--"+TEST_RESOURCE_VERSION+".txt",
 resourceUrl.getFileName());
        }
 
        @Test
@@ -58,6 +64,18 @@ public class FilenameWithVersionResourceCachingStrategyTest 
extends Assert
                strategy.undecorateUrl(resourceUrl);
 
                assertEquals("some-resource.txt", resourceUrl.getFileName());
+
+               // test URL with versiton containing prefix in original
+               resourceUrl = new 
ResourceUrl("some-resource--vers--with-prefix--vers--"+TEST_RESOURCE_VERSION+".txt",
 new PageParameters());
+               strategy.undecorateUrl(resourceUrl);
+
+               assertEquals("some-resource--vers--with-prefix.txt", 
resourceUrl.getFileName());
+
+               // test URL without version containing prefix
+               resourceUrl = new 
ResourceUrl("some-resource--vers--without-version.txt", new PageParameters());
+               strategy.undecorateUrl(resourceUrl);
+
+               assertEquals("some-resource--vers--without-version.txt", 
resourceUrl.getFileName());
        }
 
        @Test

Reply via email to