|
|
|
@ -34,11 +34,9 @@ import java.net.URLConnection; |
|
|
|
import java.nio.file.FileSystem; |
|
|
|
import java.nio.file.FileSystem; |
|
|
|
import java.nio.file.FileSystems; |
|
|
|
import java.nio.file.FileSystems; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.nio.file.NoSuchFileException; |
|
|
|
|
|
|
|
import java.nio.file.Path; |
|
|
|
import java.nio.file.Path; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Enumeration; |
|
|
|
import java.util.Enumeration; |
|
|
|
import java.util.HashSet; |
|
|
|
|
|
|
|
import java.util.LinkedHashSet; |
|
|
|
import java.util.LinkedHashSet; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.Objects; |
|
|
|
@ -738,49 +736,88 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol |
|
|
|
protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) |
|
|
|
protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) |
|
|
|
throws IOException { |
|
|
|
throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
URI rootDirUri = rootDirResource.getURI(); |
|
|
|
URI rootDirUri; |
|
|
|
String rootDir = rootDirUri.getPath(); |
|
|
|
String rootDir; |
|
|
|
// If the URI is for a "resource" in the GraalVM native image file system, we have to
|
|
|
|
|
|
|
|
// ensure that the root directory does not end in a slash while simultaneously ensuring
|
|
|
|
|
|
|
|
// that the root directory is not an empty string (since fileSystem.getPath("").resolve(str)
|
|
|
|
|
|
|
|
// throws an ArrayIndexOutOfBoundsException in a native image).
|
|
|
|
|
|
|
|
if ("resource".equals(rootDirUri.getScheme()) && (rootDir.length() > 1) && rootDir.endsWith("/")) { |
|
|
|
|
|
|
|
rootDir = rootDir.substring(0, rootDir.length() - 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FileSystem fileSystem; |
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
fileSystem = FileSystems.getFileSystem(rootDirUri.resolve("/")); |
|
|
|
rootDirUri = rootDirResource.getURI(); |
|
|
|
|
|
|
|
rootDir = rootDirUri.getPath(); |
|
|
|
|
|
|
|
// If the URI is for a "resource" in the GraalVM native image file system, we have to
|
|
|
|
|
|
|
|
// ensure that the root directory does not end in a slash while simultaneously ensuring
|
|
|
|
|
|
|
|
// that the root directory is not an empty string (since fileSystem.getPath("").resolve(str)
|
|
|
|
|
|
|
|
// throws an ArrayIndexOutOfBoundsException in a native image).
|
|
|
|
|
|
|
|
if ("resource".equals(rootDirUri.getScheme()) && (rootDir.length() > 1) && rootDir.endsWith("/")) { |
|
|
|
|
|
|
|
rootDir = rootDir.substring(0, rootDir.length() - 1); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) { |
|
|
|
catch (Exception ex) { |
|
|
|
fileSystem = FileSystems.newFileSystem(rootDirUri.resolve("/"), Map.of(), |
|
|
|
if (logger.isInfoEnabled()) { |
|
|
|
ClassUtils.getDefaultClassLoader()); |
|
|
|
logger.info("Failed to resolve %s in the file system: %s".formatted(rootDirResource, ex)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return Collections.emptySet(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Path rootPath = fileSystem.getPath(rootDir); |
|
|
|
FileSystem fileSystem = getFileSystem(rootDirUri); |
|
|
|
String resourcePattern = rootPath.resolve(subPattern).toString(); |
|
|
|
if (fileSystem == null) { |
|
|
|
Predicate<Path> resourcePatternMatches = path -> getPathMatcher().match(resourcePattern, path.toString()); |
|
|
|
return Collections.emptySet(); |
|
|
|
Set<Resource> result = new HashSet<>(); |
|
|
|
} |
|
|
|
try (Stream<Path> files = Files.walk(rootPath)) { |
|
|
|
|
|
|
|
files.filter(resourcePatternMatches).sorted().forEach(file -> { |
|
|
|
try { |
|
|
|
try { |
|
|
|
Path rootPath = fileSystem.getPath(rootDir); |
|
|
|
result.add(convertToResource(file.toUri())); |
|
|
|
String resourcePattern = rootPath.resolve(subPattern).toString(); |
|
|
|
} |
|
|
|
Predicate<Path> resourcePatternMatches = path -> getPathMatcher().match(resourcePattern, path.toString()); |
|
|
|
catch (Exception ex) { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
// TODO Introduce logging
|
|
|
|
logger.trace("Searching directory [%s] for files matching pattern [%s]" |
|
|
|
|
|
|
|
.formatted(rootPath.toAbsolutePath(), subPattern)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Set<Resource> result = new LinkedHashSet<>(); |
|
|
|
|
|
|
|
try (Stream<Path> files = Files.walk(rootPath)) { |
|
|
|
|
|
|
|
files.filter(resourcePatternMatches).sorted().forEach(file -> { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
result.add(convertToResource(file.toUri())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
|
|
|
|
logger.debug("Failed to convert file %s to an org.springframework.core.io.Resource: %s" |
|
|
|
|
|
|
|
.formatted(file, ex)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
|
|
|
|
logger.debug("Faild to complete search in directory [%s] for files matching pattern [%s]: %s" |
|
|
|
|
|
|
|
.formatted(rootPath.toAbsolutePath(), subPattern, ex)); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (NoSuchFileException ex) { |
|
|
|
finally { |
|
|
|
// TODO Introduce logging
|
|
|
|
try { |
|
|
|
|
|
|
|
fileSystem.close(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (UnsupportedOperationException ex) { |
|
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
private FileSystem getFileSystem(URI uri) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
fileSystem.close(); |
|
|
|
URI root = uri.resolve("/"); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
return FileSystems.getFileSystem(root); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
return FileSystems.newFileSystem(root, Map.of(), ClassUtils.getDefaultClassLoader()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (UnsupportedOperationException ex) { |
|
|
|
catch (Exception ex) { |
|
|
|
// TODO Introduce logging
|
|
|
|
if (logger.isInfoEnabled()) { |
|
|
|
|
|
|
|
logger.info("Failed to resolve java.nio.file.FileSystem for %s: %s".formatted(uri, ex)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
|