org.nuiton.util.Resource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-utils Show documentation
Show all versions of nuiton-utils Show documentation
Library of usefull classes to be used in any project.
/*
* #%L
* Nuiton Utils
* %%
* Copyright (C) 2004 - 2011 CodeLutin, Chatellier Eric
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.util;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.swing.ImageIcon;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import static org.nuiton.i18n.I18n.t;
/**
* Cette class permet de rechercher un fichier en indiquant son nom avec son
* chemin. Cette librairie ira ensuite chercher ce fichier sur le système de
* fichier, et s'il n'est pas trouvé dans le classpath. Le fichier peut donc
* être dans un fichier .jar ou .zip. Exemple :
*
* URL image = Resource.getURL("/images/bidulle.png");
*
*
* Created: 5 août 2003
*
* @author Benjamin Poussin - [email protected]
*
*/
public class Resource { // Resource
/** Logger. */
private static final Log log = LogFactory.getLog(Resource.class);
protected Resource() {
}
/**
* Permet d'ajouter dans le classloader par defaut une nouvelle URL dans
* lequel il faut rechercher les fichiers.
*
* @param url l'url a ajouter
*/
public static void addDefaultClassLoader(URL url) {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
addClassLoader(classLoader, url);
}
/**
* Permet d'ajouter dans un classloader une nouvelle URL dans
* lequel il faut rechercher les fichiers.
*
* @param classLoader le classloader a modifier
* @param url l'url a ajouter
*/
public static void addClassLoader(ClassLoader classLoader, URL url) {
try {
Method method = URLClassLoader.class.getDeclaredMethod("addURL",
new Class[]{URL.class});
method.setAccessible(true);
method.invoke(classLoader, url);
} catch (Exception eee) {
throw new RuntimeException(t("nuitonutil.error.add.url.in.classloader", classLoader, eee));
}
}
/**
* Recherche la ressource nom.
*
* @param name nom de la ressource
* @return l'url de la ressource
* @throws ResourceNotFoundException si la resource n'a pas ete trouvee
*/
public static URL getURL(String name) {
URL url = getURLOrNull(name);
if (url != null) {
return url;
}
throw new ResourceNotFoundException(t("nuitonutil.error.resource.not.found", name));
}
/**
* Recherche la ressource nom.
*
* @param name le nom de la ressource
* @return l'url de la ressource ou null
*/
public static URL getURLOrNull(String name) {
// on recherche d'abord sur le filesystem
File file = new File(name);
if (file.exists()) {
try {
return file.toURI().toURL();
} catch (MalformedURLException eee) {
log.warn(t("nuitonutil.error.convert.file.to.url", file, eee.getMessage()));
}
}
// on ne l'a pas trouve on recherche dans le classpath
// on supprime le / devant le nom de la ressource, sinon elle
// n'est pas trouve (pas de recherche dans les differents
// element du classpath.
if (name.length() > 1 && name.startsWith("/")) {
name = name.substring(1);
}
URL url = ClassLoader.getSystemClassLoader().getResource(name);
if (url != null) {
return url;
}
ClassLoader cl = Resource.class.getClassLoader();
url = cl.getResource(name);
return url;
}
/**
* Retourne l'icone demandee.
*
* @param name le nom de l'icone
* @return Retourne l'icon demande ou null s'il n'est pas trouvé
*/
public static ImageIcon getIcon(String name) {
try {
return new ImageIcon(getURL(name));
} catch (Exception eee) {
log.warn("Can't find icon: " + name, eee);
return null;
}
}
/**
* Retourner la liste des fichiers du classLoader. Ces fichiers doivent
* correspondre au pattern donne.
*
* Utile par defaut {@link ClassLoader#getSystemClassLoader()}.
*
* @param pattern le nom du fichier a extraire du fichier compressé ou
* du repertoire doit correspondre au pattern (repertoire + nom
* compris).
* @return la liste des urls correspondant au pattern
*/
public static List getURLs(String pattern) {
return getURLs(pattern, (URLClassLoader) null);
}
/**
* Retourner la liste des fichiers du classLoader. Ces fichiers doivent
* correspondre au pattern donne.
*
* @param classLoader classloader to use (if null, use {@link ClassLoader#getSystemClassLoader()}
* @param pattern le nom du fichier a extraire du fichier compressé ou
* du repertoire doit correspondre au pattern (repertoire + nom
* compris).
* @return la liste des urls correspondant au pattern
*/
public static List getURLs(String pattern, URLClassLoader classLoader) {
if (classLoader == null) {
classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
}
URL[] arrayURL = ClassLoaderUtil.getURLs(classLoader);
return getURLs(pattern, arrayURL);
}
/**
* Retourner la liste des fichiers du classLoader. Ces fichiers doivent
* correspondre au pattern donne.
*
* @param arrayURL les urls ou chercher
* @param pattern le nom du fichier a extraire du fichier compressé ou
* dur epertoire doit correspondre au pattern (repertoire + nom
* compris).
* @return la liste des urls correspondant au pattern
*/
public static List getURLs(String pattern, URL... arrayURL) {
long t0 = System.nanoTime();
List urlList = new HashList();
if (arrayURL.length == 1) {
URL jarURL = arrayURL[0];
if (isJar(jarURL.toString())) {
// jar invocation
try {
arrayURL = getClassPathURLsFromJarManifest(jarURL);
} catch (Exception e) {
log.warn(e);
arrayURL = new URL[]{jarURL};
}
}
}
if (log.isDebugEnabled()) {
for (URL url : arrayURL) {
log.debug("found url " + url);
}
}
for (URL urlFile : arrayURL) {
// EC-20100510 this cause wrong accent encoding
//String fileName = urlFile.getFile();
// String fileName;
// try {
// fileName = urlFile.toURI().getPath();
// } catch (Exception e) {
// if (log.isWarnEnabled()) {
// log.warn(e);
// }
// // warning, this can cause wrong encoding !!!
// fileName = urlFile.getFile();
// }
// // TODO deal with encoding in windows, this is very durty, but it
// // works...
File file = FileUtils.toFile(urlFile);
String fileName = file.getAbsolutePath();
// File file = new File(fileName.replaceAll("%20", " "));
if (!file.exists()) {
// this case should not appear
if (log.isDebugEnabled()) {
log.debug("Can't find file " + file + " (" + fileName + ")");
}
continue;
}
if (isJar(fileName)) {
// cas ou le ichier du classLoader est un fichier jar
if (log.isDebugEnabled()) {
log.debug("jar to search " + file);
}
urlList.addAll(getURLsFromJar(file, pattern));
continue;
}
if (file.isDirectory()) {
// cas ou le ichier du classLoader est un repertoire
if (log.isDebugEnabled()) {
log.debug("directory to search " + file);
}
// on traite le cas ou il peut y avoir des repertoire dans ce
// repertoire
urlList.addAll(getURLsFromDirectory(file, pattern));
continue;
}
if (isZip(fileName)) {
// cas ou le ichier du classLoader est un fichier zip
if (log.isDebugEnabled()) {
log.debug("zip to search " + file);
}
urlList.addAll(getURLsFromZip(file, pattern));
}
}
if (log.isInfoEnabled()) {
log.info("search URLs pattern: " + pattern + " in "
+ arrayURL.length + " urls in "
+ StringUtil.convertTime(System.nanoTime() - t0));
}
return urlList;
}
public static URL[] getClassPathURLsFromJarManifest(URL jarURL)
throws IOException {
URL[] result;
File jarFile = FileUtils.toFile(jarURL);
if (log.isDebugEnabled()) {
log.debug("class-path jar to scan " + jarFile);
}
JarFile jar = new JarFile(jarFile);
try {
// String jarPath = jarURL.toURI().getPath();
// File jarFile = new File(jarPath);
File container = jarFile.getParentFile();
Manifest mf = jar.getManifest();
String classPath = null;
if (mf != null && mf.getMainAttributes() != null) {
classPath = mf.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
}
String[] paths;
if (classPath != null) {
paths = classPath.split(" ");
} else {
paths = StringUtil.EMPTY_STRING_ARRAY;
}
result = new URL[paths.length + 1];
result[0] = jarURL;
File path;
for (int i = 0; i < paths.length; i++) {
String s = paths[i];
// test de l'existence d'un protocole dans le path (genre file:...)
if (s.indexOf(':') != -1) {
result[i + 1] = new URL(s);
continue;
}
if (s.startsWith(".") || !s.startsWith("/")) {
// relative url
path = new File(container, s);
} else {
path = new File(s);
}
if (log.isDebugEnabled()) {
log.debug(path);
}
result[i + 1] = path.toURI().toURL();
}
// jar.close();
} finally {
if (jar != null) {
jar.close();
}
}
return result;
}
public static List getURLsFromZip(File zipFile, String pattern) {
try {
if (log.isTraceEnabled()) {
log.trace("search '" + pattern + "' in " + zipFile);
}
List result = new ArrayList();
// InputStream in = new FileInputStream(zipFile);
ZipInputStream zis =
new ZipInputStream(new FileInputStream(zipFile));
try {
while (zis.available() != 0) {
ZipEntry entry = zis.getNextEntry();
if (entry == null) {
break;
}
String name = entry.getName();
if (log.isTraceEnabled()) {
log.trace("zipFile: " + zipFile + " name: " + name);
}
if (pattern == null || name.matches(pattern)) {
// on recupere le fichier correspondant au pattern dans
// le classloader
URL url = getURL(name);
// on ajoute le fichier correspondant au pattern dans
// la liste
if (log.isTraceEnabled()) {
log.trace("zipFile: " + zipFile + " url: " + url);
}
result.add(url);
}
}
} finally {
zis.close();
}
if (log.isTraceEnabled()) {
log.trace("found with pattern '" + pattern + "' : " + result);
}
return result;
} catch (IOException eee) {
throw new ResourceException(t("nuitonutil.error.get.url.from.zip",
zipFile.getAbsolutePath(),
eee.getMessage())
);
}
}
public static List getURLsFromJar(File jarfile, String pattern) {
try {
if (log.isTraceEnabled()) {
log.trace("search '" + pattern + "' in " + jarfile);
}
List result = new ArrayList();
// InputStream in = new FileInputStream(jarfile);
ZipInputStream zis =
new ZipInputStream(new FileInputStream(jarfile));
try {
while (zis.available() != 0) {
ZipEntry entry = zis.getNextEntry();
if (entry == null) {
break;
}
String name = entry.getName();
if (log.isTraceEnabled()) {
log.trace("jarfile: " + jarfile + " name: " + name);
}
if (pattern == null || name.matches(pattern)) {
// on recupere le fichier correspondant au pattern
// dans le classloader
URL url = getURL(name);
// on ajoute le fichier correspondant au pattern dans
// la liste
if (log.isTraceEnabled()) {
log.trace("jarfile: " + jarfile + " url: " + url);
}
result.add(url);
}
}
} finally {
zis.close();
}
if (log.isTraceEnabled()) {
log.trace("found with pattern '" + pattern + "' : " + result);
}
return result;
} catch (IOException eee) {
throw new ResourceException(t("nuitonutil.error.get.url.from.zip",
jarfile.getAbsolutePath(),
eee.getMessage())
);
}
}
/**
* Retourne la liste des fichiers correspondant au pattern donne, aucun
* ordre ne doit être supposé sur les fichiers.
*
* @param repository repertoire dans lequel on recherche les fichiers
* @param pattern le nom du fichier a extraire du fichier du repertoire doit
* correspondre au pattern (repertoire + nom compris). si le
* pattern est null, tous les fichiers trouvé sont retourné.
* @return la liste des urls correspondant au pattern
*/
public static List getURLsFromDirectory(File repository, String pattern) {
try {
if (log.isTraceEnabled()) {
log.trace("search '" + pattern + "' in " + repository);
}
List urlList = new HashList();
File[] filesList = repository.listFiles();
if (filesList != null) {
for (File file : filesList) {
String name = file.getAbsolutePath();
if (log.isTraceEnabled()) {
log.trace("directory: " + repository + " name: "
+ name);
}
// cas de recursivite : repertoire dans un repertoire
if (file.exists() && file.isDirectory()) {
urlList.addAll(getURLsFromDirectory(file,
pattern));
// si le fichier du repertoire n'est pas un repertoire
// on verifie s'il correspond au pattern
} else if (pattern == null || name.matches(pattern)) {
URL url = file.toURI().toURL();
if (log.isTraceEnabled()) {
log.trace("directory: " + repository + " url: "
+ url);
}
urlList.add(url);
}
}
}
if (log.isTraceEnabled()) {
log.trace("found with pattern '" + pattern + "' : " + urlList);
}
return urlList;
} catch (MalformedURLException eee) {
throw new ResourceException(
t("nuitonutil.error.convert.file.to.url",
repository + " (pattern " + pattern + ") ",
eee.getMessage())
);
//throw new ResourceException("Le fichier n'a pu être converti en URL", eee);
}
}
/**
* Verifie si le fichier est un fichier jar.
*
* @param name nom du fichier a tester
* @return vrai si le fichier se termine par .jar faux sinon
*/
public static boolean isJar(String name) {
if (name != null && name.length() > 4) {
String ext = name.substring(name.length() - 4, name.length());
return ".jar".equalsIgnoreCase(ext);
}
return false;
}
/**
* Verifie si le fichier est un fichier zip
*
* @param name nom du fichier a tester
* @return vrai si le fichier se termine par .zip faux sinon
*/
public static boolean isZip(String name) {
if (name != null && name.length() > 4) {
String ext = name.substring(name.length() - 4, name.length());
return ".zip".equalsIgnoreCase(ext);
}
return false;
}
/**
* Test if an url contains the given directory with no recurse seeking.
*
* @param url the url to seek
* @param directory the directory to find
* @return {@code true} if directory was found, {@code false} otherwise.
* @throws IOException if any io pb
*/
public static boolean containsDirectDirectory(URL url, String directory) throws IOException {
// String fileName = url.getFile();
// // TODO deal with encoding in windows, this is very durty, but it works...
// File file = new File(fileName.replaceAll("%20", " "));
File file = FileUtils.toFile(url);
String fileName = file.getAbsolutePath();
if (!file.exists()) {
return false;
}
if (isJar(fileName) || isZip(fileName)) {
// cas ou le fichier du classLoader est un fichier jar ou zip
if (log.isTraceEnabled()) {
log.trace("zip to search " + file);
}
ZipFile zipFile = new ZipFile(file);
try {
return zipFile.getEntry(directory + '/') != null;
} finally {
zipFile.close();
}
}
if (file.isDirectory()) {
// cas ou le ichier du classLoader est un repertoire
if (log.isTraceEnabled()) {
log.trace("directory to search " + file);
}
return new File(file, directory).exists();
}
if (log.isWarnEnabled()) {
log.warn(t("nuitonutil.error.unknown.url.type", url));
}
return false;
}
/**
* Return true if {@code str} is a pattern (contains * or ?).
*
* @param str str to test
* @return {@code true} if {@code str} is a pattern, {@code false} otherwise
* @since 2.2
*/
protected static boolean isPattern(String str) {
return str.indexOf('*') != -1 || str.indexOf('?') != -1;
}
/**
* Find pattern resouces in {@link ClassLoader#getSystemClassLoader()}.
*
* Usage :
*
* List<URL> urls = Resources.getResources("META-INF/.*\\.MF");
* List<URL> urls = Resources.getResources("org/nuiton/util/.?esource\\.class");
*
*
* @param pattern java regex style pattern to find
* @return url list found
* @throws IOException if any IO problem while seeking resources
* @since 2.2
*/
public static List getResources(String pattern) throws IOException {
return getResources(pattern, null);
}
/**
* Find pattern resouces in classloader.
*
* Usage :
*
* List<URL> urls = Resources.getResources("META-INF/.*\\.MF");
* List<URL> urls = Resources.getResources("org/nuiton/util/.?esource\\.class");
*
*
* @param pattern java regex style pattern to find
* @param classLoader classLoader
* @return url list found
* @throws IOException if any IO problem while seeking resources
* @since 2.2
*/
public static List getResources(String pattern,
ClassLoader classLoader) throws IOException {
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
List urlList;
if (isPattern(pattern)) {
urlList = getPatternRessources(pattern, classLoader);
} else {
urlList = new HashList();
Enumeration resourceUrls = classLoader.getResources(pattern);
while (resourceUrls.hasMoreElements()) {
URL url = resourceUrls.nextElement();
urlList.add(url);
}
}
return urlList;
}
/**
* Obtain some resources from a pattern using a specific class loader to
* seel resources.
*
* @param pattern pattern of searched resources
* @param classLoader class loader which responsible to seek resources
* @return list of resources found
* @throws IOException if any IO problem while scanning resources
* @since 2.2
*/
protected static List getPatternRessources(String pattern,
ClassLoader classLoader) throws IOException {
List urlList = new HashList();
// get root directory to get URL in classpath
// for example :
// /WEB-INF/*.xml → /WEB-INF/
// /META-INF/persistence/*.xml → /META-INF/persistence/
int prefixEnd = pattern.indexOf(":") + 1;
int rootDirEnd = pattern.length();
while (rootDirEnd > prefixEnd &&
isPattern(pattern.substring(prefixEnd, rootDirEnd))) {
rootDirEnd = pattern.lastIndexOf('/', rootDirEnd - 2) + 1;
}
if (rootDirEnd == 0) {
rootDirEnd = prefixEnd;
}
String rootDirPath = pattern.substring(0, rootDirEnd);
String subPattern = pattern.substring(rootDirPath.length());
Enumeration rootDirResources =
classLoader.getResources(rootDirPath);
while (rootDirResources.hasMoreElements()) {
URL rootDirResource = rootDirResources.nextElement();
if (isJarUrl(rootDirResource)) {
// cas ou le ichier du classLoader est un fichier jar
if (log.isDebugEnabled()) {
log.debug("jar to search " + rootDirResource);
}
urlList.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
} else {
urlList.addAll(doFindMatchingFileSystemResources(rootDirResource, subPattern));
}
}
return urlList;
}
/**
* Test if an url detnoe a jar file.
*
* Code taken from spring source code :
* org.springframework.core.io.support.PathMatchingResourcePatternResolver
*
* @param url url to test
* @return true if url denote a jar file
* @since 2.2
*/
public static boolean isJarUrl(URL url) {
String protocol = url.getProtocol();
return "jar".equals(protocol) ||
"zip".equals(protocol) ||
"wsjar".equals(protocol);
}
/**
* Find all resources in jar files that match the given location pattern
* via the Java Regex style Matcher.
*
* Code taken from spring source code :
* org.springframework.core.io.support.PathMatchingResourcePatternResolver
*
* @param rootDirResource the root directory as Resource
* @param subPattern the sub pattern to match (below the root directory)
* @return the Set of matching Resource instances
* @throws IOException in case of I/O errors
* @see JarURLConnection
* @since 2.2
*/
protected static List doFindPathMatchingJarResources(URL rootDirResource,
String subPattern) throws IOException {
URLConnection con = rootDirResource.openConnection();
JarFile jarFile;
String jarFileUrl;
String rootEntryPath;
boolean newJarFile = false;
if (con instanceof JarURLConnection) {
// Should usually be the case for traditional JAR files.
JarURLConnection jarCon = (JarURLConnection) con;
jarCon.setUseCaches(false);
jarFile = jarCon.getJarFile();
jarFileUrl = jarCon.getJarFileURL().toExternalForm();
JarEntry jarEntry = jarCon.getJarEntry();
rootEntryPath = jarEntry != null ? jarEntry.getName() : "";
} else {
// No JarURLConnection → need to resort to URL file parsing.
// We'll assume URLs of the format "jar:path!/entry", with the protocol
// being arbitrary as long as following the entry format.
// We'll also handle paths with and without leading "file:" prefix.
String urlFile = rootDirResource.getFile();
int separatorIndex = urlFile.indexOf("!/");
if (separatorIndex != -1) {
jarFileUrl = urlFile.substring(0, separatorIndex);
rootEntryPath = urlFile.substring(separatorIndex + "!/".length());
//jarFile = getJarFile(jarFileUrl);
if (jarFileUrl.startsWith("file:")) {
jarFile = new JarFile(jarFileUrl.substring("file:".length()));
} else {
jarFile = new JarFile(jarFileUrl);
}
} else {
jarFile = new JarFile(urlFile);
jarFileUrl = urlFile;
rootEntryPath = "";
}
newJarFile = true;
}
try {
if (log.isDebugEnabled()) {
log.debug("Looking for matching resources in jar file [" + jarFileUrl + "]");
}
if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) {
// Root entry path must end with slash to allow for proper matching.
// The Sun JRE does not return a slash here, but BEA JRockit does.
rootEntryPath = rootEntryPath + "/";
}
List result = new HashList(8);
for (Enumeration> entries = jarFile.entries(); entries.hasMoreElements(); ) {
JarEntry entry = (JarEntry) entries.nextElement();
String entryPath = entry.getName();
if (entryPath.startsWith(rootEntryPath)) {
String relativePath = entryPath.substring(rootEntryPath.length());
if (relativePath.matches(subPattern)) {
URL entryURL = new URL(rootDirResource, relativePath);
result.add(entryURL);
}
}
}
return result;
} finally {
// Close jar file, but only if freshly obtained -
// not from JarURLConnection, which might cache the file reference.
if (newJarFile) {
jarFile.close();
}
}
}
/**
* Find all resources in the file system that match the given location pattern
* via the Java style matcher.
*
* Code taken from spring source code :
* org.springframework.core.io.support.PathMatchingResourcePatternResolver
*
* @param rootDirResource the root directory as Resource
* @param subPattern the sub pattern to match (below the root directory)
* @return the Set of matching Resource instances
* @throws IOException in case of I/O errors
* @see #retrieveMatchingFiles(File, String)
* @since 2.2
*/
protected static List doFindMatchingFileSystemResources(URL rootDirResource,
String subPattern)
throws IOException {
File rootDir;
try {
rootDir = new File(rootDirResource.toURI().getSchemeSpecificPart());
rootDir = rootDir.getAbsoluteFile();
} catch (URISyntaxException ex) {
return Collections.emptyList();
}
return retrieveMatchingFiles(rootDir, subPattern);
}
/**
* Retrieve files that match the given path pattern,
* checking the given directory and its subdirectories.
*
* Code taken from spring source code :
* org.springframework.core.io.support.PathMatchingResourcePatternResolver
*
* @param rootDir the directory to start from
* @param pattern the pattern to match against,
* relative to the root directory
* @return the Set of matching File instances
* @throws IOException if directory contents could not be retrieved
* @since 2.2
*/
protected static List retrieveMatchingFiles(File rootDir,
String pattern) throws IOException {
if (!rootDir.exists()) {
return Collections.emptyList();
}
if (!rootDir.isDirectory()) {
return Collections.emptyList();
}
if (!rootDir.canRead()) {
return Collections.emptyList();
}
//String fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/");
String fullPattern = rootDir.getAbsolutePath().replace(File.separator, "/");
if (!pattern.startsWith("/")) {
fullPattern += "/";
}
//fullPattern = fullPattern + StringUtils.replace(pattern, File.separator, "/");
fullPattern = fullPattern + pattern.replace(File.separator, "/");
List result = new HashList(8);
doRetrieveMatchingFiles(fullPattern, rootDir, result);
return result;
}
/**
* Recursively retrieve files that match the given pattern,
* adding them to the given result list.
*
* Code taken from spring source code :
* org.springframework.core.io.support.PathMatchingResourcePatternResolver
*
* @param fullPattern the pattern to match against,
* with preprended root directory path
* @param dir the current directory
* @param result the Set of matching File instances to add to
* @throws IOException if directory contents could not be retrieved
* @since 2.2
*/
protected static void doRetrieveMatchingFiles(String fullPattern,
File dir,
List result) throws IOException {
if (log.isDebugEnabled()) {
log.debug("Searching directory [" + dir.getAbsolutePath() +
"] for files matching pattern [" + fullPattern + "]");
}
File[] dirContents = dir.listFiles();
if (dirContents == null) {
if (log.isWarnEnabled()) {
log.warn("Could not retrieve contents of directory [" + dir.getAbsolutePath() + "]");
}
return;
}
for (File content : dirContents) {
//String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/");
String currPath = content.getAbsolutePath().replace(File.separator, "/");
//if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) {
if (content.isDirectory() && (currPath + "/").matches(fullPattern + ".*")) {
if (!content.canRead()) {
if (log.isDebugEnabled()) {
log.debug("Skipping subdirectory [" + dir.getAbsolutePath() +
"] because the application is not allowed to read the directory");
}
} else {
doRetrieveMatchingFiles(fullPattern, content, result);
}
}
//if (getPathMatcher().match(fullPattern, currPath)) {
if (currPath.matches(fullPattern)) {
result.add(content.toURI().toURL());
}
}
}
} // Resource