public class PathMatchingResourcePatternResolver extends Object implements ResourcePatternResolver
ResourcePatternResolver implementation that is able to resolve a
specified resource location path into one or more matching Resources. The
source path may be a simple path which has a one-to-one mapping to a target
org.hotswap.agent.util.spring.io.resource.springframework.core.io.Resource
, or alternatively may contain the special "classpath*:" prefix
and/or internal Ant-style regular expressions (matched using Spring's
org.hotswap.agent.util.spring.path.springframework.util.AntPathMatcher
utility). Both of the latter are effectively wildcards.
No Wildcards:
In the simple case, if the specified location path does not start with the
"classpath*:" prefix, and does not contain a PathMatcher pattern,
this resolver will simply return a single resource via a
getResource() call on the underlying ResourceLoader. Examples
are real URLs such as "file:C:/context.xml", pseudo-URLs such as
"classpath:/context.xml", and simple unprefixed paths such as
"/WEB-INF/context.xml". The latter will resolve in a fashion specific
to the underlying ResourceLoader (e.g. ServletContextResource
for a WebApplicationContext).
Ant-style Patterns:
When the path location contains an Ant-style pattern, e.g.:
/WEB-INF/*-context.xml com/mycompany/**/applicationContext.xml file:C:/some/path/*-context.xml classpath:com/mycompany/**/applicationContext.xmlthe resolver follows a more complex but defined procedure to try to resolve the wildcard. It produces a
Resource for the path up to the last
non-wildcard segment and obtains a URL from it. If this URL is not a
"jar:" URL or container-specific variant (e.g. "zip:" in
WebLogic, "wsjar" in WebSphere", etc.), then a java.io.File
is obtained from it, and used to resolve the wildcard by walking the
filesystem. In the case of a jar URL, the resolver either gets a
java.net.JarURLConnection from it, or manually parses the jar URL,
and then traverses the contents of the jar file, to resolve the wildcards.
Implications on portability:
If the specified path is already a file URL (either explicitly, or implicitly
because the base ResourceLoader is a filesystem one, then wildcarding
is guaranteed to work in a completely portable fashion.
If the specified path is a classpath location, then the resolver must obtain
the last non-wildcard path segment URL via a
Classloader.getResource() call. Since this is just a node of the path
(not the file at the end) it is actually undefined (in the ClassLoader
Javadocs) exactly what sort of a URL is returned in this case. In practice,
it is usually a java.io.File representing the directory, where the
classpath resource resolves to a filesystem location, or a jar URL of some
sort, where the classpath resource resolves to a jar location. Still, there
is a portability concern on this operation.
If a jar URL is obtained for the last non-wildcard segment, the resolver must
be able to get a java.net.JarURLConnection from it, or manually parse
the jar URL, to be able to walk the contents of the jar, and resolve the
wildcard. This will work in most environments, but will fail in others, and
it is strongly recommended that the wildcard resolution of resources coming
from jars be thoroughly tested in your specific environment before you rely
on it.
classpath*: Prefix:
There is special support for retrieving multiple class path resources with
the same name, via the "classpath*:" prefix. For example,
"classpath*:META-INF/beans.xml" will find all "beans.xml" files in
the class path, be it in "classes" directories or in JAR files. This is
particularly useful for autodetecting config files of the same name at the
same location within each jar file. Internally, this happens via a
ClassLoader.getResources() call, and is completely portable.
The "classpath*:" prefix can also be combined with a PathMatcher pattern in
the rest of the location path, for example "classpath*:META-INF/*-beans.xml".
In this case, the resolution strategy is fairly simple: a
ClassLoader.getResources() call is used on the last non-wildcard path
segment to get all the matching resources in the class loader hierarchy, and
then off each resource the same PathMatcher resolution strategy described
above is used for the wildcard subpath.
Other notes:
WARNING: Note that "classpath*:" when combined with Ant-style
patterns will only work reliably with at least one root directory before the
pattern starts, unless the actual target files reside in the file system.
This means that a pattern like "classpath*:*.xml" will not
retrieve files from the root of jar files but rather only from the root of
expanded directories. This originates from a limitation in the JDK's
ClassLoader.getResources() method which only returns file system
locations for a passed-in empty String (indicating potential roots to
search).
WARNING: Ant-style patterns with "classpath:" resources are not guaranteed to find matching resources if the root package to search is available in multiple class path locations. This is because a resource such as
com / mycompany / package1 / service - context.xmlmay be in only one location, but when a path such as
classpath:com/mycompany/**/service-context.xml
is used to try to resolve it, the resolver will work off the (first) URL
returned by getResource("com/mycompany");. If this base package node
exists in multiple classloader locations, the actual end resource may not be
underneath. Therefore, preferably, use "classpath*:" with the same
Ant-style pattern in such a case, which will search all class path
locations that contain the root package.ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX,
org.hotswap.agent.util.spring.path.springframework.util.AntPathMatcher,
org.hotswap.agent.util.spring.io.loader.springframework.core.io.ResourceLoader#getResource(String),
ClassLoader.getResources(String)CLASSPATH_ALL_URL_PREFIXCLASSPATH_URL_PREFIX| Constructor and Description |
|---|
PathMatchingResourcePatternResolver()
Create a new PathMatchingResourcePatternResolver with a
DefaultResourceLoader.
|
PathMatchingResourcePatternResolver(ClassLoader classLoader)
Create a new PathMatchingResourcePatternResolver with a
DefaultResourceLoader.
|
PathMatchingResourcePatternResolver(ResourceLoader resourceLoader)
Create a new PathMatchingResourcePatternResolver.
|
| Modifier and Type | Method and Description |
|---|---|
protected void |
addAllClassLoaderJarRoots(ClassLoader classLoader,
Set<Resource> result)
Search all
URLClassLoader URLs for jar file references and add
them to the given set of resources in the form of pointers to the root of
the jar file content. |
protected Resource |
convertClassLoaderURL(URL url)
Convert the given URL as returned from the ClassLoader into a
Resource. |
protected String |
determineRootDir(String location)
Determine the root directory for the given location.
|
protected Set<Resource> |
doFindAllClassPathResources(String path)
Find all class location resources with the given path via the
ClassLoader.
|
protected Set<Resource> |
doFindMatchingFileSystemResources(File rootDir,
String subPattern)
Find all resources in the file system that match the given location
pattern via the Ant-style PathMatcher.
|
protected Set<Resource> |
doFindPathMatchingFileResources(Resource rootDirResource,
String subPattern)
Find all resources in the file system that match the given location
pattern via the Ant-style PathMatcher.
|
protected Set<Resource> |
doFindPathMatchingJarResources(Resource rootDirResource,
String subPattern)
Find all resources in jar files that match the given location pattern via
the Ant-style PathMatcher.
|
protected void |
doRetrieveMatchingFiles(String fullPattern,
File dir,
Set<File> result)
Recursively retrieve files that match the given pattern, adding them to
the given result list.
|
protected Resource[] |
findAllClassPathResources(String location)
Find all class location resources with the given location via the
ClassLoader.
|
protected Resource[] |
findPathMatchingResources(String locationPattern)
Find all resources that match the given location pattern via the
Ant-style PathMatcher.
|
ClassLoader |
getClassLoader()
Expose the ClassLoader used by this ResourceLoader.
|
protected JarFile |
getJarFile(String jarFileUrl)
Resolve the given jar file URL into a JarFile object.
|
PathMatcher |
getPathMatcher()
Return the PathMatcher that this resource pattern resolver uses.
|
Resource |
getResource(String location)
Return a Resource handle for the specified resource.
|
ResourceLoader |
getResourceLoader()
Return the ResourceLoader that this pattern resolver works with.
|
Resource[] |
getResources(String locationPattern)
Resolve the given location pattern into Resource objects.
|
protected boolean |
isJarResource(Resource resource)
Return whether the given resource handle indicates a jar resource that
the
doFindPathMatchingJarResources method can handle. |
protected Resource |
resolveRootDirResource(Resource original)
Resolve the specified resource for path matching.
|
protected Set<File> |
retrieveMatchingFiles(File rootDir,
String pattern)
Retrieve files that match the given path pattern, checking the given
directory and its subdirectories.
|
void |
setPathMatcher(PathMatcher pathMatcher)
Set the PathMatcher implementation to use for this resource pattern
resolver.
|
public PathMatchingResourcePatternResolver()
ClassLoader access will happen via the thread context class loader.
DefaultResourceLoaderpublic PathMatchingResourcePatternResolver(ResourceLoader resourceLoader)
ClassLoader access will happen via the thread context class loader.
resourceLoader - the ResourceLoader to load root directories and actual
resources withpublic PathMatchingResourcePatternResolver(ClassLoader classLoader)
classLoader - the ClassLoader to load classpath resources with, or
null for using the thread context class loader at the
time of actual resource accessDefaultResourceLoaderpublic ResourceLoader getResourceLoader()
public ClassLoader getClassLoader()
ResourceLoaderClients which need to access the ClassLoader directly can do so in a uniform manner with the ResourceLoader, rather than relying on the thread context ClassLoader.
getClassLoader in interface ResourceLoadernull if even the system ClassLoader
isn't accessible)org.springframework.util.ClassUtils#getDefaultClassLoader()public void setPathMatcher(PathMatcher pathMatcher)
AntPathMatcherpublic PathMatcher getPathMatcher()
public Resource getResource(String location)
ResourceLoaderInputStreamSource.getInputStream() calls.
Note that a Resource handle does not imply an existing resource; you need
to invoke Resource.exists() to check for existence.
getResource in interface ResourceLoaderlocation - the resource locationResourceLoader.CLASSPATH_URL_PREFIX,
org.hotswap.agent.util.spring.io.resource.springframework.core.io.Resource#exists,
org.hotswap.agent.util.spring.io.resource.springframework.core.io.Resource#getInputStreampublic Resource[] getResources(String locationPattern) throws IOException
ResourcePatternResolverOverlapping resource entries that point to the same physical resource should be avoided, as far as possible. The result should have set semantics.
getResources in interface ResourcePatternResolverlocationPattern - the location pattern to resolveIOException - in case of I/O errorsprotected Resource[] findAllClassPathResources(String location) throws IOException
doFindAllClassPathResources(String).location - the absolute path within the classpathIOException - in case of I/O errorsClassLoader.getResources(java.lang.String),
convertClassLoaderURL(java.net.URL)protected Set<Resource> doFindAllClassPathResources(String path) throws IOException
findAllClassPathResources(String).path - the absolute path within the classpath (never a leading slash)IOExceptionprotected Resource convertClassLoaderURL(URL url)
Resource.
The default implementation simply creates a UrlResource instance.
url - a URL as returned from the ClassLoaderClassLoader.getResources(java.lang.String),
Resourceprotected void addAllClassLoaderJarRoots(ClassLoader classLoader, Set<Resource> result)
URLClassLoader URLs for jar file references and add
them to the given set of resources in the form of pointers to the root of
the jar file content.classLoader - the ClassLoader to search (including its ancestors)result - the set of resources to add jar roots toprotected Resource[] findPathMatchingResources(String locationPattern) throws IOException
locationPattern - the location pattern to matchIOException - in case of I/O errorsdoFindPathMatchingJarResources(org.hotswap.agent.util.spring.io.resource.Resource, java.lang.String),
doFindPathMatchingFileResources(org.hotswap.agent.util.spring.io.resource.Resource, java.lang.String),
org.hotswap.agent.util.spring.path.springframework.util.PathMatcherprotected String determineRootDir(String location)
Used for determining the starting point for file matching, resolving the
root directory location to a java.io.File and passing it into
retrieveMatchingFiles, with the remainder of the location as
pattern.
Will return "/WEB-INF/" for the pattern "/WEB-INF/*.xml", for example.
location - the location to checkretrieveMatchingFiles(java.io.File, java.lang.String)protected Resource resolveRootDirResource(Resource original) throws IOException
The default implementation detects an Equinox OSGi "bundleresource:" / "bundleentry:" URL and resolves it into a standard jar file URL that can be traversed using Spring's standard jar file traversal algorithm.
original - the resource to resolveIOException - in case of resolution failureprotected boolean isJarResource(Resource resource) throws IOException
doFindPathMatchingJarResources method can handle.
The default implementation checks against the URL protocols "jar", "zip" and "wsjar" (the latter are used by BEA WebLogic Server and IBM WebSphere, respectively, but can be treated like jar files).
resource - the resource handle to check (usually the root directory to
start path matching from)IOExceptiondoFindPathMatchingJarResources(org.hotswap.agent.util.spring.io.resource.Resource, java.lang.String),
org.hotswap.agent.util.spring.util.springframework.util.ResourceUtils#isJarURLprotected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, String subPattern) throws IOException
rootDirResource - the root directory as ResourcesubPattern - the sub pattern to match (below the root directory)IOException - in case of I/O errorsJarURLConnection,
org.hotswap.agent.util.spring.path.springframework.util.PathMatcherprotected JarFile getJarFile(String jarFileUrl) throws IOException
IOExceptionprotected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) throws IOException
rootDirResource - the root directory as ResourcesubPattern - the sub pattern to match (below the root directory)IOException - in case of I/O errorsretrieveMatchingFiles(java.io.File, java.lang.String),
org.hotswap.agent.util.spring.path.springframework.util.PathMatcherprotected Set<Resource> doFindMatchingFileSystemResources(File rootDir, String subPattern) throws IOException
rootDir - the root directory in the file systemsubPattern - the sub pattern to match (below the root directory)IOException - in case of I/O errorsretrieveMatchingFiles(java.io.File, java.lang.String),
org.hotswap.agent.util.spring.path.springframework.util.PathMatcherprotected Set<File> retrieveMatchingFiles(File rootDir, String pattern) throws IOException
rootDir - the directory to start frompattern - the pattern to match against, relative to the root directoryIOException - if directory contents could not be retrievedprotected void doRetrieveMatchingFiles(String fullPattern, File dir, Set<File> result) throws IOException
fullPattern - the pattern to match against, with prepended root directory
pathdir - the current directoryresult - the Set of matching File instances to add toIOException - if directory contents could not be retrievedCopyright © 2018. All rights reserved.