@@ -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