From 33e381aa295d612a71a40099d3d2ab5e6f3137bb Mon Sep 17 00:00:00 2001 From: Robinson Date: Sat, 26 Jun 2021 14:55:09 +0200 Subject: [PATCH] Added getDirectoryContents --- src/dorkbox/util/LocationResolver.java | 63 ++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/dorkbox/util/LocationResolver.java b/src/dorkbox/util/LocationResolver.java index 0c06558..29d1278 100644 --- a/src/dorkbox/util/LocationResolver.java +++ b/src/dorkbox/util/LocationResolver.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLDecoder; @@ -31,8 +32,12 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.Vector; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -333,6 +338,64 @@ class LocationResolver { } } + /** + * List directory contents for a resource folder. Not recursive. + * This is basically a brute-force implementation. + * Works for regular files and also JARs. + * + * @author Greg Briggs + * @param clazz Any java class that lives in the same place as the resources you want. + * @param path Should end with "/", but not start with one. + * @return Just the name of each member item, not the full paths. + * + * + * @throws URISyntaxException + * @throws IOException + */ + String[] getDirectoryContents(Class clazz, String path) throws URISyntaxException, IOException { + URL dirURL = clazz.getClassLoader().getResource(path); + if (dirURL != null && dirURL.getProtocol().equals("file")) { + /* A file path: easy enough */ + return new File(dirURL.toURI()).list(); + } + + if (dirURL == null) { + /* + * In case of a jar file, we can't actually find a directory. + * Have to assume the same jar as clazz. + */ + String me = clazz.getName().replace(".", "/") + ".class"; + dirURL = clazz.getClassLoader().getResource(me); + } + + if (dirURL.getProtocol() + .equals("jar")) { + /* A JAR path */ + String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); //strip out only the JAR file + + JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")); + Enumeration entries = jar.entries(); //gives ALL entries in jar + Set result = new HashSet(); //avoid duplicates in case it is a subdirectory + + while (entries.hasMoreElements()) { + String name = entries.nextElement().getName(); + if (name.startsWith(path)) { //filter according to the path + String entry = name.substring(path.length()); + int checkSubdir = entry.indexOf("/"); + if (checkSubdir >= 0) { + // if it is a subdirectory, we just return the directory name + entry = entry.substring(0, checkSubdir); + } + result.add(entry); + } + } + return result.toArray(new String[result.size()]); + } + + throw new UnsupportedOperationException("Cannot list files for URL " + dirURL); + } + + @SuppressWarnings("Duplicates") private static class Root {