diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractVersionStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractVersionStrategy.java
index 8cb3c3b5f4..17d72700e8 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractVersionStrategy.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AbstractVersionStrategy.java
@@ -6,6 +6,7 @@ import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -20,73 +21,106 @@ import org.springframework.util.StringUtils;
* version string.
*
* @author Brian Clozel
+ * @author Rossen Stoyanchev
* @since 4.1
*/
public abstract class AbstractVersionStrategy implements VersionStrategy {
- private static final Pattern pattern = Pattern.compile("-(\\S*)\\.");
-
protected final Log logger = LogFactory.getLog(getClass());
- /**
- * Extracts a version string from the request path, as a suffix in the resource
- * file name.
- * @param requestPath the request path to extract the version string from
- * @return a version string or an empty string if none was found
- */
- protected String extractVersionFromFilename(String requestPath) {
- Matcher matcher = pattern.matcher(requestPath);
- if (matcher.find()) {
- String match = matcher.group(1);
- return match.contains("-") ? match.substring(match.lastIndexOf("-") + 1) : match;
- }
- else {
- return "";
- }
+ private final VersionPathStrategy pathStrategy;
+
+
+ protected AbstractVersionStrategy(VersionPathStrategy pathStrategy) {
+ Assert.notNull(pathStrategy, "'pathStrategy' is required");
+ this.pathStrategy = pathStrategy;
}
- /**
- * Deletes the given candidate version string from the request path.
- * The version string should be a suffix in the resource file name.
- */
- protected String deleteVersionFromFilename(String requestPath, String candidateVersion) {
- return StringUtils.delete(requestPath, "-" + candidateVersion);
+
+ public VersionPathStrategy getVersionPathStrategy() {
+ return this.pathStrategy;
}
- /**
- * Adds the given version string to the baseUrl, as a file name suffix.
- */
- protected String addVersionToFilename(String baseUrl, String version) {
- String baseFilename = StringUtils.stripFilenameExtension(baseUrl);
- String extension = StringUtils.getFilenameExtension(baseUrl);
- return baseFilename + "-" + version + "." + extension;
+
+ @Override
+ public String extractVersion(String requestPath) {
+ return this.pathStrategy.extractVersion(requestPath);
}
- /**
- * Extracts a version string from the request path, as a prefix in the request path.
- * @param requestPath the request path to extract the version string from
- * @return a version string or an empty string if none was found
- */
- protected String extractVersionAsPrefix(String requestPath, String prefix) {
- if (requestPath.startsWith(prefix)) {
- return prefix;
- }
- return "";
+ @Override
+ public String removeVersion(String requestPath, String version) {
+ return this.pathStrategy.removeVersion(requestPath, version);
+ }
+
+ @Override
+ public String addVersion(String requestPath, String version) {
+ return this.pathStrategy.addVersion(requestPath, version);
}
+
/**
- * Deletes the given candidate version string from the request path.
- * The version string should be a prefix in the request path.
+ * A prefix-based {@code VersionPathStrategy},
+ * e.g. {@code "{version}/path/foo.js"}.
*/
- protected String deleteVersionAsPrefix(String requestPath, String version) {
- return requestPath.substring(version.length());
+ protected static class PrefixVersionPathStrategy implements VersionPathStrategy {
+
+ private final String prefix;
+
+
+ public PrefixVersionPathStrategy(String version) {
+ Assert.hasText(version, "'version' is required and must not be empty");
+ this.prefix = version;
+ }
+
+ @Override
+ public String extractVersion(String requestPath) {
+ return (requestPath.startsWith(this.prefix) ? this.prefix : null);
+ }
+
+ @Override
+ public String removeVersion(String requestPath, String version) {
+ return requestPath.substring(this.prefix.length());
+ }
+
+ @Override
+ public String addVersion(String path, String version) {
+ return (this.prefix.endsWith("/") || path.startsWith("/") ? this.prefix + path : this.prefix + "/" + path);
+ }
+
}
/**
- * Adds the given version string to the baseUrl, as a prefix in the request path.
+ * File name-based {@code VersionPathStrategy},
+ * e.g. {@code "path/foo-{version}.css"}.
*/
- protected String addVersionAsPrefix(String baseUrl, String version) {
- return version + baseUrl;
+ protected static class FileNameVersionPathStrategy implements VersionPathStrategy {
+
+ private static final Pattern pattern = Pattern.compile("-(\\S*)\\.");
+
+
+ @Override
+ public String extractVersion(String requestPath) {
+ Matcher matcher = pattern.matcher(requestPath);
+ if (matcher.find()) {
+ String match = matcher.group(1);
+ return match.contains("-") ? match.substring(match.lastIndexOf("-") + 1) : match;
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public String removeVersion(String requestPath, String version) {
+ return StringUtils.delete(requestPath, "-" + version);
+ }
+
+ @Override
+ public String addVersion(String requestPath, String version) {
+ String baseFilename = StringUtils.stripFilenameExtension(requestPath);
+ String extension = StringUtils.getFilenameExtension(requestPath);
+ return baseFilename + "-" + version + "." + extension;
+ }
}
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategy.java
deleted file mode 100644
index 778e2e03e2..0000000000
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategy.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2002-2014 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.springframework.web.servlet.resource;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.springframework.core.io.Resource;
-import org.springframework.util.DigestUtils;
-import org.springframework.util.FileCopyUtils;
-
-/**
- * A {@code VersionStrategy} that handles version strings as a Hex MD5 hash in resource file names.
- *
- *
For example the path "styles/foo-e36d2e05253c6c7085a91522ce43a0b4.css" will
- * match to "styles/foo.css" assuming the hash computed from the content of
- * "foo.css" matches the hash in the path.
- *
- * @author Jeremy Grelle
- * @author Rossen Stoyanchev
- * @author Sam Brannen
- * @author Brian Clozel
- * @since 4.1
- * @see VersionResourceResolver
- */
-public class ContentBasedVersionStrategy extends AbstractVersionStrategy {
-
- @Override
- public String extractVersionFromPath(String requestPath) {
- return extractVersionFromFilename(requestPath);
- }
-
- @Override
- public String deleteVersionFromPath(String requestPath, String candidateVersion) {
- return deleteVersionFromFilename(requestPath, candidateVersion);
- }
-
- @Override
- public boolean resourceVersionMatches(Resource baseResource, String candidateVersion) {
- String resourceHash = calculateHash(baseResource);
- return candidateVersion.equals(resourceHash);
- }
-
- @Override
- public String addVersionToUrl(String baseUrl, List extends Resource> locations, ResourceResolverChain chain) {
- if (logger.isTraceEnabled()) {
- logger.trace("Getting the original resource to calculate hash");
- }
- Resource original = chain.resolveResource(null, baseUrl, locations);
- String hash = calculateHash(original);
- if (logger.isTraceEnabled()) {
- logger.trace("Calculated hash=" + hash);
- }
- return addVersionToFilename(baseUrl, hash);
- }
-
- private String calculateHash(Resource resource) {
- try {
- byte[] content = FileCopyUtils.copyToByteArray(resource.getInputStream());
- return DigestUtils.md5DigestAsHex(content);
- }
- catch (IOException e) {
- logger.error("Failed to calculate hash for resource [" + resource + "]");
- return "";
- }
- }
-
-}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ContentVersionStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ContentVersionStrategy.java
new file mode 100644
index 0000000000..c9a3c9175a
--- /dev/null
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ContentVersionStrategy.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.springframework.web.servlet.resource;
+
+import java.io.IOException;
+
+import org.springframework.core.io.Resource;
+import org.springframework.util.DigestUtils;
+import org.springframework.util.FileCopyUtils;
+
+/**
+ * A {@code VersionStrategy} that calculates an Hex MD5 hashes from the content
+ * of the resource and appends it to the file name, e.g.
+ * {@code "styles/main-e36d2e05253c6c7085a91522ce43a0b4.css"}.
+ *
+ * @author Brian Clozel
+ * @author Rossen Stoyanchev
+ * @since 4.1
+ * @see VersionResourceResolver
+ */
+public class ContentVersionStrategy extends AbstractVersionStrategy {
+
+
+ public ContentVersionStrategy() {
+ super(new FileNameVersionPathStrategy());
+ }
+
+
+ @Override
+ public String getResourceVersion(Resource resource) {
+ try {
+ byte[] content = FileCopyUtils.copyToByteArray(resource.getInputStream());
+ return DigestUtils.md5DigestAsHex(content);
+ }
+ catch (IOException ex) {
+ throw new IllegalStateException("Failed to calculate hash for resource [" + resource + "]", ex);
+ }
+ }
+
+}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/FixedVersionStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/FixedVersionStrategy.java
index 9c8d9da229..eacc005202 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/FixedVersionStrategy.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/FixedVersionStrategy.java
@@ -15,28 +15,18 @@
*/
package org.springframework.web.servlet.resource;
-import java.util.List;
-import java.util.concurrent.Callable;
-
import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
/**
- * A {@code VersionStrategy} that handles unique, static, application-wide version strings
- * as prefixes in the request path.
- *
- *
Enables inserting a unique and static version String (e.g. reduced SHA, version name,
- * release date) at the beginning of resource paths so that when a new version of the application
- * is released, clients are forced to reload application resources.
+ * A {@code VersionStrategy} that relies on a fixed version applied as a request
+ * path prefix, e.g. reduced SHA, version name, release date, etc.
*
- *
This is useful when changing resource names is not an option (e.g. when
- * using JavaScript module loaders). If that's not the case, the use of
- * {@link ContentBasedVersionStrategy} provides more optimal performance since
- * version is generated on a per-resource basis: only actually modified resources are reloaded
- * by the client.
+ *
This is useful for example when {@link ContentVersionStrategy} cannot be
+ * used such as when using JavaScript module loaders which are in charge of
+ * loading the JavaScript resources and need to know their relative paths.
*
* @author Brian Clozel
- * @author Sam Brannen
+ * @author Rossen Stoyanchev
* @since 4.1
* @see VersionResourceResolver
*/
@@ -46,44 +36,17 @@ public class FixedVersionStrategy extends AbstractVersionStrategy {
/**
* Create a new FixedVersionStrategy with the given version string.
- * @param fixedVersion the fixed version string to use
- */
- public FixedVersionStrategy(String fixedVersion) {
- Assert.hasText(fixedVersion, "version must not be null or empty");
- this.version = fixedVersion.endsWith("/") ? fixedVersion : fixedVersion + "/";
- }
-
- /**
- * Create a new FixedVersionStrategy and get the version string to use by
- * calling the given {@code Callable} instance.
+ * @param version the fixed version string to use
*/
- public FixedVersionStrategy(Callable versionInitializer) throws Exception {
- String fixedVersion = versionInitializer.call();
- Assert.hasText(fixedVersion, "version must not be null or empty");
- this.version = fixedVersion.endsWith("/") ? fixedVersion : fixedVersion + "/";
- }
-
- @Override
- public String extractVersionFromPath(String requestPath) {
-
- return extractVersionAsPrefix(requestPath, this.version);
- }
-
- @Override
- public String deleteVersionFromPath(String requestPath, String candidateVersion) {
- return deleteVersionAsPrefix(requestPath, candidateVersion);
+ public FixedVersionStrategy(String version) {
+ super(new PrefixVersionPathStrategy(version));
+ this.version = version;
}
- @Override
- public boolean resourceVersionMatches(Resource baseResource, String candidateVersion) {
- return this.version.equals(candidateVersion);
- }
@Override
- public String addVersionToUrl(String baseUrl, List extends Resource> locations,
- ResourceResolverChain chain) {
-
- return addVersionAsPrefix(baseUrl, this.version);
+ public String getResourceVersion(Resource resource) {
+ return this.version;
}
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionPathStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionPathStrategy.java
new file mode 100644
index 0000000000..995145ed53
--- /dev/null
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionPathStrategy.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.springframework.web.servlet.resource;
+
+/**
+ * A strategy for extracting and embedding a resource version in its URL path.
+ *
+ * @author Brian Clozel
+ * @author Rossen Stoyanchev
+ * @since 4.1
+*/
+public interface VersionPathStrategy {
+
+ /**
+ * Extract the resource version from the request path.
+ * @param requestPath the request path to check
+ * @return the version string or {@code null} if none was found
+ */
+ String extractVersion(String requestPath);
+
+ /**
+ * Remove the version from the request path. It is assumed that the given
+ * version was extracted via {@link #extractVersion(String)}.
+ * @param requestPath the request path of the resource being resolved
+ * @param version the version obtained from {@link #extractVersion(String)}
+ * @return the request path with the version removed
+ */
+ String removeVersion(String requestPath, String version);
+
+ /**
+ * Add a version to the given request path.
+ * @param requestPath the requestPath
+ * @param version the version
+ * @return the requestPath updated with a version string
+ */
+ String addVersion(String requestPath, String version);
+
+}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java
index 0e195f615f..bd972c15f0 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java
@@ -50,6 +50,7 @@ public class VersionResourceResolver extends AbstractResourceResolver {
private Map versionStrategyMap = Collections.emptyMap();
+
/**
* Set a Map with URL paths as keys and {@code VersionStrategy}
* as values.
@@ -59,10 +60,11 @@ public class VersionResourceResolver extends AbstractResourceResolver {
*
* @param versionStrategyMap map with URLs as keys and version strategies as values
*/
- public void setVersionStrategyMap(Map versionStrategyMap) {
+ public void setStrategyMap(Map versionStrategyMap) {
this.versionStrategyMap = versionStrategyMap;
}
+
@Override
protected Resource resolveResourceInternal(HttpServletRequest request, String requestPath,
List extends Resource> locations, ResourceResolverChain chain) {
@@ -72,12 +74,12 @@ public class VersionResourceResolver extends AbstractResourceResolver {
return resolved;
}
- VersionStrategy versionStrategy = findStrategy(requestPath);
+ VersionStrategy versionStrategy = getStrategyForPath(requestPath);
if (versionStrategy == null) {
return null;
}
- String candidateVersion = versionStrategy.extractVersionFromPath(requestPath);
+ String candidateVersion = versionStrategy.extractVersion(requestPath);
if (StringUtils.isEmpty(candidateVersion)) {
if (logger.isTraceEnabled()) {
logger.trace("No version found in path=\"" + requestPath + "\"");
@@ -85,7 +87,7 @@ public class VersionResourceResolver extends AbstractResourceResolver {
return null;
}
- String simplePath = versionStrategy.deleteVersionFromPath(requestPath, candidateVersion);
+ String simplePath = versionStrategy.removeVersion(requestPath, candidateVersion);
if (logger.isTraceEnabled()) {
logger.trace("Extracted version from path, re-resolving without version, path=\"" + simplePath + "\"");
@@ -96,7 +98,8 @@ public class VersionResourceResolver extends AbstractResourceResolver {
return null;
}
- if (versionStrategy.resourceVersionMatches(baseResource, candidateVersion)) {
+ String actualVersion = versionStrategy.getResourceVersion(baseResource);
+ if (candidateVersion.equals(actualVersion)) {
if (logger.isTraceEnabled()) {
logger.trace("resource matches extracted version");
}
@@ -113,11 +116,19 @@ public class VersionResourceResolver extends AbstractResourceResolver {
protected String resolveUrlPathInternal(String resourceUrlPath, List extends Resource> locations, ResourceResolverChain chain) {
String baseUrl = chain.resolveUrlPath(resourceUrlPath, locations);
if (StringUtils.hasText(baseUrl)) {
- VersionStrategy versionStrategy = findStrategy(resourceUrlPath);
+ VersionStrategy versionStrategy = getStrategyForPath(resourceUrlPath);
if (versionStrategy == null) {
return null;
}
- return versionStrategy.addVersionToUrl(baseUrl, locations, chain);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Getting the original resource to determine version");
+ }
+ Resource resource = chain.resolveResource(null, baseUrl, locations);
+ String version = versionStrategy.getResourceVersion(resource);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Version=" + version);
+ }
+ return versionStrategy.addVersion(baseUrl, version);
}
return baseUrl;
}
@@ -126,7 +137,7 @@ public class VersionResourceResolver extends AbstractResourceResolver {
* Finds a {@code VersionStrategy} for the request path of the requested resource.
* @return an instance of a {@code VersionStrategy} or null if none matches that request path
*/
- protected VersionStrategy findStrategy(String requestPath) {
+ protected VersionStrategy getStrategyForPath(String requestPath) {
String path = "/".concat(requestPath);
List matchingPatterns = new ArrayList();
for (String pattern : this.versionStrategyMap.keySet()) {
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionStrategy.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionStrategy.java
index 5385e036e0..1893566f9a 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionStrategy.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionStrategy.java
@@ -15,50 +15,24 @@
*/
package org.springframework.web.servlet.resource;
-import java.util.List;
-
import org.springframework.core.io.Resource;
/**
- * A strategy for handling version strings in request paths when resolving
- * static resources with a {@link VersionResourceResolver}.
+ * An extension of {@link VersionPathStrategy} that adds a method to determine the
+ * actual version of a {@link org.springframework.core.io.Resource Resource}.
*
* @author Brian Clozel
+ * @author Rossen Stoyanchev
* @since 4.1
* @see VersionResourceResolver
*/
-public interface VersionStrategy {
+public interface VersionStrategy extends VersionPathStrategy {
/**
- * Extracts a version string from the request path.
- * @param requestPath the request path of the resource being resolved
- * @return the version string or an empty string if none was found
+ * Get the version for the given resource.
+ * @param resource the resource to check
+ * @return the version, never {@code null}
*/
- String extractVersionFromPath(String requestPath);
+ String getResourceVersion(Resource resource);
- /**
- * Deletes the given candidate version string from the given request path.
- * @param requestPath the request path of the resource being resolved
- * @param candidateVersion the candidate version string
- * @return the modified request path, without the version string
- */
- String deleteVersionFromPath(String requestPath, String candidateVersion);
-
- /**
- * Checks whether the given {@code Resource} matches the candidate version string.
- * Useful when the version string is managed on a per-resource basis.
- * @param baseResource the resource to check against the given version
- * @param candidateVersion the candidate version for the given resource
- * @return true if the resource matches the version string, false otherwise
- */
- boolean resourceVersionMatches(Resource baseResource, String candidateVersion);
-
- /**
- * Adds a version string to the given baseUrl.
- * @param baseUrl the baseUrl of the requested resource
- * @param locations the resource locations to resolve resources from
- * @param chain the chain of resource resolvers
- * @return the baseUrl updated with a version string
- */
- String addVersionToUrl(String baseUrl, List extends Resource> locations, ResourceResolverChain chain);
}
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java
index 567dad0425..75210d071a 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java
@@ -78,7 +78,7 @@ public class AppCacheManifestTransformerTests {
VersionResourceResolver versionResourceResolver = new VersionResourceResolver();
versionResourceResolver
- .setVersionStrategyMap(Collections.singletonMap("/**", new ContentBasedVersionStrategy()));
+ .setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy()));
List resolvers = new ArrayList();
resolvers.add(versionResourceResolver);
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategyTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategyTests.java
index 9d2b0fc14d..f1b3fdfcaa 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategyTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ContentBasedVersionStrategyTests.java
@@ -15,10 +15,7 @@
*/
package org.springframework.web.servlet.resource;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.List;
import org.junit.Before;
import org.junit.Test;
@@ -31,65 +28,50 @@ import org.springframework.util.FileCopyUtils;
import static org.junit.Assert.*;
/**
- * Unit tests for {@link org.springframework.web.servlet.resource.ContentBasedVersionStrategy}
+ * Unit tests for {@link ContentVersionStrategy}
* @author Brian Clozel
*/
public class ContentBasedVersionStrategyTests {
- private List locations;
+ private ContentVersionStrategy versionStrategy = new ContentVersionStrategy();
- private ContentBasedVersionStrategy versionStrategy = new ContentBasedVersionStrategy();
-
- private ResourceResolverChain chain;
@Before
public void setup() {
- this.locations = new ArrayList();
- this.locations.add(new ClassPathResource("test/", getClass()));
- this.locations.add(new ClassPathResource("testalternatepath/", getClass()));
-
VersionResourceResolver versionResourceResolver = new VersionResourceResolver();
- versionResourceResolver.setVersionStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
- this.chain = new DefaultResourceResolverChain(Arrays.asList(versionResourceResolver, new PathResourceResolver()));
+ versionResourceResolver.setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
}
@Test
- public void extractVersionFromPath() throws Exception {
+ public void extractVersion() throws Exception {
String hash = "7fbe76cdac6093784895bb4989203e5a";
String path = "font-awesome/css/font-awesome.min-" + hash + ".css";
- assertEquals(hash, this.versionStrategy.extractVersionFromPath(path));
- assertEquals("", this.versionStrategy.extractVersionFromPath("foo/bar.css"));
+ assertEquals(hash, this.versionStrategy.extractVersion(path));
+ assertNull(this.versionStrategy.extractVersion("foo/bar.css"));
}
@Test
- public void deleteVersionFromPath() throws Exception {
+ public void removeVersion() throws Exception {
String file = "font-awesome/css/font-awesome.min%s%s.css";
String hash = "7fbe76cdac6093784895bb4989203e5a";
- assertEquals(String.format(file, "", ""), this.versionStrategy.deleteVersionFromPath(String.format(file, "-", hash), hash));
- assertEquals("", this.versionStrategy.extractVersionFromPath("foo/bar.css"));
+ assertEquals(String.format(file, "", ""), this.versionStrategy.removeVersion(String.format(file, "-", hash), hash));
+ assertNull(this.versionStrategy.extractVersion("foo/bar.css"));
}
@Test
- public void resourceVersionMatches() throws Exception {
+ public void getResourceVersion() throws Exception {
Resource expected = new ClassPathResource("test/bar.css", getClass());
String hash = DigestUtils.md5DigestAsHex(FileCopyUtils.copyToByteArray(expected.getInputStream()));
- String wrongHash = "wronghash";
-
- assertTrue(this.versionStrategy.resourceVersionMatches(expected, hash));
- assertFalse(this.versionStrategy.resourceVersionMatches(expected, wrongHash));
+ assertEquals(hash, this.versionStrategy.getResourceVersion(expected));
}
@Test
public void addVersionToUrl() throws Exception {
- String file = "bar.css";
- Resource expected = new ClassPathResource("test/" + file, getClass());
- String hash = DigestUtils.md5DigestAsHex(FileCopyUtils.copyToByteArray(expected.getInputStream()));
- String path = "bar-" + hash + ".css";
- String resultUrl = this.versionStrategy.addVersionToUrl(file, this.locations, this.chain);
-
- assertEquals(path, resultUrl);
+ String requestPath = "test/bar.css";
+ String version = "123";
+ assertEquals("test/bar-123.css", this.versionStrategy.addVersion(requestPath, version));
}
}
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/CssLinkResourceTransformerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/CssLinkResourceTransformerTests.java
index c4d391098b..5f93358ddf 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/CssLinkResourceTransformerTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/CssLinkResourceTransformerTests.java
@@ -50,9 +50,9 @@ public class CssLinkResourceTransformerTests {
@Before
public void setUp() {
Map versionStrategyMap = new HashMap<>();
- versionStrategyMap.put("/**", new ContentBasedVersionStrategy());
+ versionStrategyMap.put("/**", new ContentVersionStrategy());
VersionResourceResolver versionResolver = new VersionResourceResolver();
- versionResolver.setVersionStrategyMap(versionStrategyMap);
+ versionResolver.setStrategyMap(versionStrategyMap);
List resolvers = new ArrayList();
resolvers.add(versionResolver);
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/FixedVersionStrategyTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/FixedVersionStrategyTests.java
index b3cab06411..8eeb0ab0ee 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/FixedVersionStrategyTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/FixedVersionStrategyTests.java
@@ -15,16 +15,11 @@
*/
package org.springframework.web.servlet.resource;
-import java.util.Collections;
-import java.util.concurrent.Callable;
-
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
-import org.springframework.core.io.Resource;
-
/**
* Unit tests for {@link org.springframework.web.servlet.resource.FixedVersionStrategy}
* @author Brian Clozel
@@ -33,49 +28,36 @@ public class FixedVersionStrategyTests {
private final String version = "1df341f";
- private final String resourceId = "js/foo.js";
+ private final String path = "js/foo.js";
+
+ private FixedVersionStrategy strategy;
- private FixedVersionStrategy versionStrategy;
@Before
public void setup() {
- this.versionStrategy = new FixedVersionStrategy(this.version);
+ this.strategy = new FixedVersionStrategy(this.version);
}
- @Test(expected = IllegalArgumentException.class)
- public void constructWithEmptyPrefixVersion() throws Exception {
-
- FixedVersionStrategy versionStrategy = new FixedVersionStrategy(" ");
- }
@Test(expected = IllegalArgumentException.class)
- public void constructWithEmptyCallableVersion() throws Exception {
-
- FixedVersionStrategy versionStrategy = new FixedVersionStrategy(
- new Callable() {
- @Override
- public String call() throws Exception {
- return " ";
- }
- });
+ public void emptyPrefixVersion() throws Exception {
+ new FixedVersionStrategy(" ");
}
@Test
- public void extractVersionFromPath() throws Exception {
- assertEquals(this.version + "/", this.versionStrategy.extractVersionFromPath(this.version + "/" + this.resourceId));
- assertEquals("", this.versionStrategy.extractVersionFromPath(this.resourceId));
+ public void extractVersion() throws Exception {
+ assertEquals(this.version, this.strategy.extractVersion(this.version + "/" + this.path));
+ assertNull(this.strategy.extractVersion(this.path));
}
@Test
- public void deleteVersionFromPath() throws Exception {
- assertEquals(this.resourceId,
- this.versionStrategy.deleteVersionFromPath(this.version + "/" + this.resourceId, this.version + "/"));
+ public void removeVersion() throws Exception {
+ assertEquals("/" + this.path, this.strategy.removeVersion(this.version + "/" + this.path, this.version));
}
@Test
- public void addVersionToUrl() throws Exception {
- assertEquals(this.version + "/" + this.resourceId,
- this.versionStrategy.addVersionToUrl(this.resourceId, Collections.emptyList(), null));
-
+ public void addVersion() throws Exception {
+ assertEquals(this.version + "/" + this.path, this.strategy.addVersion(this.path, this.version));
}
+
}
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/GzipResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/GzipResourceResolverTests.java
index 40a9ad18bf..b322f21c3a 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/GzipResourceResolverTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/GzipResourceResolverTests.java
@@ -71,9 +71,9 @@ public class GzipResourceResolverTests {
@Before
public void setUp() {
Map versionStrategyMap = new HashMap<>();
- versionStrategyMap.put("/**", new ContentBasedVersionStrategy());
+ versionStrategyMap.put("/**", new ContentVersionStrategy());
VersionResourceResolver versionResolver = new VersionResourceResolver();
- versionResolver.setVersionStrategyMap(versionStrategyMap);
+ versionResolver.setStrategyMap(versionStrategyMap);
List resolvers = new ArrayList();
resolvers.add(new GzipResourceResolver());
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java
index 48749ff3eb..2641b763f0 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java
@@ -115,9 +115,9 @@ public class ResourceUrlProviderJavaConfigTests {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
Map versionStrategyMap = new HashMap<>();
- versionStrategyMap.put("/**", new ContentBasedVersionStrategy());
+ versionStrategyMap.put("/**", new ContentVersionStrategy());
VersionResourceResolver versionResolver = new VersionResourceResolver();
- versionResolver.setVersionStrategyMap(versionStrategyMap);
+ versionResolver.setStrategyMap(versionStrategyMap);
registry.addResourceHandler("/resources/**")
.addResourceLocations("classpath:org/springframework/web/servlet/resource/test/")
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java
index 12e4ced623..870b305574 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java
@@ -68,9 +68,9 @@ public class ResourceUrlProviderTests {
@Test
public void getFingerprintedResourceUrl() {
Map versionStrategyMap = new HashMap<>();
- versionStrategyMap.put("/**", new ContentBasedVersionStrategy());
+ versionStrategyMap.put("/**", new ContentVersionStrategy());
VersionResourceResolver versionResolver = new VersionResourceResolver();
- versionResolver.setVersionStrategyMap(versionStrategyMap);
+ versionResolver.setStrategyMap(versionStrategyMap);
List resolvers = new ArrayList();
resolvers.add(versionResolver);
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java
index cbeddb0e0f..61d80000da 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java
@@ -40,7 +40,7 @@ public class VersionResourceResolverTests {
private List locations;
- private VersionResourceResolver versionResourceResolver;
+ private VersionResourceResolver resolver;
private ResourceResolverChain chain;
@@ -49,126 +49,118 @@ public class VersionResourceResolverTests {
@Before
public void setup() {
- this.locations = new ArrayList();
+ this.locations = new ArrayList<>();
this.locations.add(new ClassPathResource("test/", getClass()));
this.locations.add(new ClassPathResource("testalternatepath/", getClass()));
- this.versionResourceResolver = new VersionResourceResolver();
+ this.resolver = new VersionResourceResolver();
this.chain = mock(ResourceResolverChain.class);
this.versionStrategy = mock(VersionStrategy.class);
}
@Test
- public void resolveResourceInternalExisting() throws Exception {
+ public void resolveResourceExisting() throws Exception {
String file = "bar.css";
Resource expected = new ClassPathResource("test/" + file, getClass());
when(this.chain.resolveResource(null, file, this.locations)).thenReturn(expected);
- this.versionResourceResolver
- .setVersionStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
- Resource actual = this.versionResourceResolver.resolveResourceInternal(null, file, this.locations, this.chain);
+ this.resolver.setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
+ Resource actual = this.resolver.resolveResourceInternal(null, file, this.locations, this.chain);
assertEquals(expected, actual);
verify(this.chain, times(1)).resolveResource(null, file, this.locations);
- verify(this.versionStrategy, never()).extractVersionFromPath(file);
+ verify(this.versionStrategy, never()).extractVersion(file);
}
@Test
- public void resolveResourceInternalNoStrategy() throws Exception {
+ public void resolveResourceNoVersionStrategy() throws Exception {
String file = "missing.css";
when(this.chain.resolveResource(null, file, this.locations)).thenReturn(null);
- this.versionResourceResolver.setVersionStrategyMap(Collections.emptyMap());
- Resource actual = this.versionResourceResolver.resolveResourceInternal(null, file, this.locations, this.chain);
+ this.resolver.setStrategyMap(Collections.emptyMap());
+ Resource actual = this.resolver.resolveResourceInternal(null, file, this.locations, this.chain);
assertNull(actual);
verify(this.chain, times(1)).resolveResource(null, file, this.locations);
}
@Test
- public void resolveResourceInternalNoCandidateVersion() throws Exception {
-
+ public void resolveResourceNoVersionInPath() throws Exception {
String file = "bar.css";
when(this.chain.resolveResource(null, file, this.locations)).thenReturn(null);
- when(this.versionStrategy.extractVersionFromPath(file)).thenReturn("");
+ when(this.versionStrategy.extractVersion(file)).thenReturn("");
- this.versionResourceResolver
- .setVersionStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
- Resource actual = this.versionResourceResolver.resolveResourceInternal(null, file, this.locations, this.chain);
+ this.resolver.setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
+ Resource actual = this.resolver.resolveResourceInternal(null, file, this.locations, this.chain);
assertNull(actual);
verify(this.chain, times(1)).resolveResource(null, file, this.locations);
- verify(this.versionStrategy, times(1)).extractVersionFromPath(file);
+ verify(this.versionStrategy, times(1)).extractVersion(file);
}
@Test
- public void resolveResourceInternalNoBaseResource() throws Exception {
-
+ public void resolveResourceNoResourceAfterVersionRemoved() throws Exception {
String versionFile = "bar-version.css";
String version = "version";
String file = "bar.css";
when(this.chain.resolveResource(null, versionFile, this.locations)).thenReturn(null);
when(this.chain.resolveResource(null, file, this.locations)).thenReturn(null);
- when(this.versionStrategy.extractVersionFromPath(versionFile)).thenReturn(version);
- when(this.versionStrategy.deleteVersionFromPath(versionFile, version)).thenReturn(file);
+ when(this.versionStrategy.extractVersion(versionFile)).thenReturn(version);
+ when(this.versionStrategy.removeVersion(versionFile, version)).thenReturn(file);
- this.versionResourceResolver
- .setVersionStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
- Resource actual = this.versionResourceResolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
+ this.resolver.setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
+ Resource actual = this.resolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
assertNull(actual);
- verify(this.versionStrategy, times(1)).deleteVersionFromPath(versionFile, version);
+ verify(this.versionStrategy, times(1)).removeVersion(versionFile, version);
}
@Test
- public void resolveResourceInternalNoMatch() throws Exception {
-
+ public void resolveResourceVersionDoesNotMatch() throws Exception {
String versionFile = "bar-version.css";
String version = "version";
String file = "bar.css";
Resource expected = new ClassPathResource("test/" + file, getClass());
when(this.chain.resolveResource(null, versionFile, this.locations)).thenReturn(null);
when(this.chain.resolveResource(null, file, this.locations)).thenReturn(expected);
- when(this.versionStrategy.extractVersionFromPath(versionFile)).thenReturn(version);
- when(this.versionStrategy.deleteVersionFromPath(versionFile, version)).thenReturn(file);
- when(this.versionStrategy.resourceVersionMatches(expected, version)).thenReturn(false);
+ when(this.versionStrategy.extractVersion(versionFile)).thenReturn(version);
+ when(this.versionStrategy.removeVersion(versionFile, version)).thenReturn(file);
+ when(this.versionStrategy.getResourceVersion(expected)).thenReturn("newer-version");
- this.versionResourceResolver
- .setVersionStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
- Resource actual = this.versionResourceResolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
+ this.resolver.setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
+ Resource actual = this.resolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
assertNull(actual);
- verify(this.versionStrategy, times(1)).resourceVersionMatches(expected, version);
+ verify(this.versionStrategy, times(1)).getResourceVersion(expected);
}
@Test
- public void resolveResourceInternalMatch() throws Exception {
-
+ public void resolveResourceSuccess() throws Exception {
String versionFile = "bar-version.css";
String version = "version";
String file = "bar.css";
Resource expected = new ClassPathResource("test/" + file, getClass());
when(this.chain.resolveResource(null, versionFile, this.locations)).thenReturn(null);
when(this.chain.resolveResource(null, file, this.locations)).thenReturn(expected);
- when(this.versionStrategy.extractVersionFromPath(versionFile)).thenReturn(version);
- when(this.versionStrategy.deleteVersionFromPath(versionFile, version)).thenReturn(file);
- when(this.versionStrategy.resourceVersionMatches(expected, version)).thenReturn(true);
+ when(this.versionStrategy.extractVersion(versionFile)).thenReturn(version);
+ when(this.versionStrategy.removeVersion(versionFile, version)).thenReturn(file);
+ when(this.versionStrategy.getResourceVersion(expected)).thenReturn(version);
- this.versionResourceResolver
- .setVersionStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
- Resource actual = this.versionResourceResolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
+ this.resolver
+ .setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
+ Resource actual = this.resolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
assertEquals(expected, actual);
- verify(this.versionStrategy, times(1)).resourceVersionMatches(expected, version);
+ verify(this.versionStrategy, times(1)).getResourceVersion(expected);
}
@Test
- public void findStrategy() throws Exception {
+ public void getStrategyForPath() throws Exception {
Map strategies = new HashMap<>();
VersionStrategy jsStrategy = mock(VersionStrategy.class);
VersionStrategy catchAllStrategy = mock(VersionStrategy.class);
strategies.put("/**", catchAllStrategy);
strategies.put("/**/*.js", jsStrategy);
- this.versionResourceResolver.setVersionStrategyMap(strategies);
+ this.resolver.setStrategyMap(strategies);
- assertEquals(catchAllStrategy, this.versionResourceResolver.findStrategy("foo.css"));
- assertEquals(catchAllStrategy, this.versionResourceResolver.findStrategy("foo-js.css"));
- assertEquals(jsStrategy, this.versionResourceResolver.findStrategy("foo.js"));
- assertEquals(jsStrategy, this.versionResourceResolver.findStrategy("bar/foo.js"));
+ assertEquals(catchAllStrategy, this.resolver.getStrategyForPath("foo.css"));
+ assertEquals(catchAllStrategy, this.resolver.getStrategyForPath("foo-js.css"));
+ assertEquals(jsStrategy, this.resolver.getStrategyForPath("foo.js"));
+ assertEquals(jsStrategy, this.resolver.getStrategyForPath("bar/foo.js"));
}
}