Skip to content

Commit 65a8f5e

Browse files
committed
PathMatchingResourcePatternResolver reuses resolved root dir URL
Issue: SPR-14202
1 parent f73df2e commit 65a8f5e

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,18 @@ protected Resource[] findPathMatchingResources(String locationPattern) throws IO
462462
Set<Resource> result = new LinkedHashSet<Resource>(16);
463463
for (Resource rootDirResource : rootDirResources) {
464464
rootDirResource = resolveRootDirResource(rootDirResource);
465-
if (rootDirResource.getURL().getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
466-
result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirResource, subPattern, getPathMatcher()));
465+
URL rootDirURL = rootDirResource.getURL();
466+
if (equinoxResolveMethod != null) {
467+
if (rootDirURL.getProtocol().startsWith("bundle")) {
468+
rootDirURL = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirURL);
469+
rootDirResource = new UrlResource(rootDirURL);
470+
}
471+
}
472+
if (rootDirURL.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
473+
result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirURL, subPattern, getPathMatcher()));
467474
}
468-
else if (isJarResource(rootDirResource)) {
469-
result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
475+
else if (ResourceUtils.isJarURL(rootDirURL) || isJarResource(rootDirResource)) {
476+
result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirURL, subPattern));
470477
}
471478
else {
472479
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
@@ -504,52 +511,57 @@ protected String determineRootDir(String location) {
504511

505512
/**
506513
* Resolve the specified resource for path matching.
507-
* <p>The default implementation detects an Equinox OSGi "bundleresource:"
508-
* / "bundleentry:" URL and resolves it into a standard jar file URL that
509-
* can be traversed using Spring's standard jar file traversal algorithm.
514+
* <p>By default, Equinox OSGi "bundleresource:" / "bundleentry:" URL will be
515+
* resolved into a standard jar file URL that be traversed using Spring's
516+
* standard jar file traversal algorithm. For any preceding custom resolution,
517+
* override this method and replace the resource handle accordingly.
510518
* @param original the resource to resolve
511519
* @return the resolved resource (may be identical to the passed-in resource)
512520
* @throws IOException in case of resolution failure
513521
*/
514522
protected Resource resolveRootDirResource(Resource original) throws IOException {
515-
if (equinoxResolveMethod != null) {
516-
URL url = original.getURL();
517-
if (url.getProtocol().startsWith("bundle")) {
518-
return new UrlResource((URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, url));
519-
}
520-
}
521523
return original;
522524
}
523525

524526
/**
525527
* Return whether the given resource handle indicates a jar resource
526528
* that the {@code doFindPathMatchingJarResources} method can handle.
527-
* <p>The default implementation checks against the URL protocols
528-
* "jar", "zip" and "wsjar" (the latter are used by BEA WebLogic Server
529-
* and IBM WebSphere, respectively, but can be treated like jar files).
529+
* <p>By default, the URL protocols "jar", "zip", "vfszip and "wsjar"
530+
* will be treated as jar resources. This template method allows for
531+
* detecting further kinds of jar-like resources, e.g. through
532+
* {@code instanceof} checks on the resource handle type.
530533
* @param resource the resource handle to check
531534
* (usually the root directory to start path matching from)
532535
* @see #doFindPathMatchingJarResources
533536
* @see org.springframework.util.ResourceUtils#isJarURL
534537
*/
535538
protected boolean isJarResource(Resource resource) throws IOException {
536-
return ResourceUtils.isJarURL(resource.getURL());
539+
return false;
537540
}
538541

539542
/**
540543
* Find all resources in jar files that match the given location pattern
541544
* via the Ant-style PathMatcher.
542545
* @param rootDirResource the root directory as Resource
546+
* @param rootDirURL the pre-resolved root directory URL
543547
* @param subPattern the sub pattern to match (below the root directory)
544548
* @return a mutable Set of matching Resource instances
545549
* @throws IOException in case of I/O errors
550+
* @since 4.3
546551
* @see java.net.JarURLConnection
547552
* @see org.springframework.util.PathMatcher
548553
*/
549-
protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, String subPattern)
554+
@SuppressWarnings("deprecation")
555+
protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, URL rootDirURL, String subPattern)
550556
throws IOException {
551557

552-
URLConnection con = rootDirResource.getURL().openConnection();
558+
// Check deprecated variant for potential overriding first...
559+
Set<Resource> result = doFindPathMatchingJarResources(rootDirResource, subPattern);
560+
if (result != null) {
561+
return result;
562+
}
563+
564+
URLConnection con = rootDirURL.openConnection();
553565
JarFile jarFile;
554566
String jarFileUrl;
555567
String rootEntryPath;
@@ -570,7 +582,7 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
570582
// We'll assume URLs of the format "jar:path!/entry", with the protocol
571583
// being arbitrary as long as following the entry format.
572584
// We'll also handle paths with and without leading "file:" prefix.
573-
String urlFile = rootDirResource.getURL().getFile();
585+
String urlFile = rootDirURL.getFile();
574586
try {
575587
int separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
576588
if (separatorIndex != -1) {
@@ -602,7 +614,7 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
602614
// The Sun JRE does not return a slash here, but BEA JRockit does.
603615
rootEntryPath = rootEntryPath + "/";
604616
}
605-
Set<Resource> result = new LinkedHashSet<Resource>(8);
617+
result = new LinkedHashSet<Resource>(8);
606618
for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) {
607619
JarEntry entry = entries.nextElement();
608620
String entryPath = entry.getName();
@@ -622,6 +634,23 @@ protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource,
622634
}
623635
}
624636

637+
/**
638+
* Find all resources in jar files that match the given location pattern
639+
* via the Ant-style PathMatcher.
640+
* @param rootDirResource the root directory as Resource
641+
* @param subPattern the sub pattern to match (below the root directory)
642+
* @return a mutable Set of matching Resource instances
643+
* @throws IOException in case of I/O errors
644+
* @deprecated as of Spring 4.3, in favor of
645+
* {@link #doFindPathMatchingJarResources(Resource, URL, String)}
646+
*/
647+
@Deprecated
648+
protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, String subPattern)
649+
throws IOException {
650+
651+
return null;
652+
}
653+
625654
/**
626655
* Resolve the given jar file URL into a JarFile object.
627656
*/
@@ -778,8 +807,9 @@ protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set<File> r
778807
private static class VfsResourceMatchingDelegate {
779808

780809
public static Set<Resource> findMatchingResources(
781-
Resource rootResource, String locationPattern, PathMatcher pathMatcher) throws IOException {
782-
Object root = VfsPatternUtils.findRoot(rootResource.getURL());
810+
URL rootDirURL, String locationPattern, PathMatcher pathMatcher) throws IOException {
811+
812+
Object root = VfsPatternUtils.findRoot(rootDirURL);
783813
PatternVirtualFileVisitor visitor =
784814
new PatternVirtualFileVisitor(VfsPatternUtils.getPath(root), locationPattern, pathMatcher);
785815
VfsPatternUtils.visit(root, visitor);

0 commit comments

Comments
 (0)