@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 2008 the original author or authors .
* Copyright 2002 - 201 0 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 @@
@@ -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;
@@ -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
@@ -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
@@ -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
@@ -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 ) ;
}
}
}
}