ServletContextResourcePatternResolver handles "/WEB-INF/lib/*.jar!/**/context.xml" style patterns (SPR-7198)
This commit is contained in:
parent
738d84f75c
commit
a8ed98255f
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
|
|
@ -17,14 +17,21 @@
|
|||
package org.springframework.web.context.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -38,6 +45,9 @@ import org.springframework.util.StringUtils;
|
|||
*/
|
||||
public class ServletContextResourcePatternResolver extends PathMatchingResourcePatternResolver {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ServletContextResourcePatternResolver.class);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ServletContextResourcePatternResolver.
|
||||
* @param servletContext the ServletContext to load resources with
|
||||
|
|
@ -102,8 +112,15 @@ public class ServletContextResourcePatternResolver extends PathMatchingResourceP
|
|||
Set candidates = servletContext.getResourcePaths(dir);
|
||||
if (candidates != null) {
|
||||
boolean dirDepthNotFixed = fullPattern.contains("**");
|
||||
for (Iterator it = candidates.iterator(); it.hasNext();) {
|
||||
String currPath = (String) it.next();
|
||||
int jarFileSep = fullPattern.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
|
||||
String jarFilePath = null;
|
||||
String pathInJarFile = null;
|
||||
if (jarFileSep > 0 && jarFileSep + ResourceUtils.JAR_URL_SEPARATOR.length() < fullPattern.length()) {
|
||||
jarFilePath = fullPattern.substring(0, jarFileSep);
|
||||
pathInJarFile = fullPattern.substring(jarFileSep + ResourceUtils.JAR_URL_SEPARATOR.length());
|
||||
}
|
||||
for (Object candidate : candidates) {
|
||||
String currPath = (String) candidate;
|
||||
if (!currPath.startsWith(dir)) {
|
||||
// Returned resource path does not start with relative directory:
|
||||
// assuming absolute path returned -> strip absolute path.
|
||||
|
|
@ -112,13 +129,19 @@ public class ServletContextResourcePatternResolver extends PathMatchingResourceP
|
|||
currPath = currPath.substring(dirIndex);
|
||||
}
|
||||
}
|
||||
if (currPath.endsWith("/") &&
|
||||
(dirDepthNotFixed ||
|
||||
StringUtils.countOccurrencesOf(currPath, "/") <= StringUtils.countOccurrencesOf(fullPattern, "/"))) {
|
||||
if (currPath.endsWith("/") && (dirDepthNotFixed || StringUtils.countOccurrencesOf(currPath, "/") <=
|
||||
StringUtils.countOccurrencesOf(fullPattern, "/"))) {
|
||||
// Search subdirectories recursively: ServletContext.getResourcePaths
|
||||
// only returns entries for one directory level.
|
||||
doRetrieveMatchingServletContextResources(servletContext, fullPattern, currPath, result);
|
||||
}
|
||||
if (jarFilePath != null && getPathMatcher().match(jarFilePath, currPath)) {
|
||||
// Base pattern matches a jar file - search for matching entries within.
|
||||
String absoluteJarPath = servletContext.getRealPath(currPath);
|
||||
if (absoluteJarPath != null) {
|
||||
doRetrieveMatchingJarEntries(absoluteJarPath, pathInJarFile, result);
|
||||
}
|
||||
}
|
||||
if (getPathMatcher().match(fullPattern, currPath)) {
|
||||
result.add(new ServletContextResource(servletContext, currPath));
|
||||
}
|
||||
|
|
@ -126,4 +149,36 @@ public class ServletContextResourcePatternResolver extends PathMatchingResourceP
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method extracts entries from the given jar by pattern.
|
||||
* @param jarFilePath the path to the jar file
|
||||
* @param entryPattern the pattern for jar entries to match
|
||||
* @param result the Set of matching Resources to add to
|
||||
* @throws IOException if jar contents could not be retrieved
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void doRetrieveMatchingJarEntries(String jarFilePath, String entryPattern, Set<Resource> result) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Searching jar file [" + jarFilePath + "] for entries matching [" + entryPattern + "]");
|
||||
}
|
||||
try {
|
||||
JarFile jarFile = new JarFile(jarFilePath);
|
||||
for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
String entryPath = entry.getName();
|
||||
if (getPathMatcher().match(entryPattern, entryPath)) {
|
||||
result.add(new UrlResource(ResourceUtils.URL_PROTOCOL_JAR + ":" +
|
||||
ResourceUtils.URL_PROTOCOL_FILE + ":" + jarFilePath +
|
||||
ResourceUtils.JAR_URL_SEPARATOR + entryPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Cannot search for matching resources in jar file [" + jarFilePath +
|
||||
"] because the jar cannot be opened through the file system", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue