package net.slimevoid.library.util;
import net.slimevoid.library.core.SlimevoidCore;
import net.slimevoid.library.core.lib.CoreLib;
import java.io.*;
import java.net.*;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
public class FileUtils {
/**
* List directory contents for a resource folder. Not recursive. This is
* basically a brute-force implementation. Works for regular files and also
* JARs.
*
* @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
* @author Greg Briggs
* @editor Eurymachus
*/
public static String[] getResourceListing(Class clazz, String path) throws URISyntaxException, IOException {
SlimevoidCore.console(CoreLib.MOD_ID,
"Attempting resource load from [" + path
+ "] using Class Parent ["
+ clazz.getSimpleName() + "]");
/* attempts to get a valid URL based on the class file and given path */
URL dirURL = clazz.getClassLoader().getResource(path);
if (dirURL != null && dirURL.getProtocol().equals("file")) {
/* A file path: easy enough */
SlimevoidCore.console(CoreLib.MOD_ID,
"Found resource in file path!");
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 != null) {
/* A ZIP/JAR path */
if (dirURL.getProtocol().equals("jar")
|| dirURL.getProtocol().equals("zip")) {
/* strip out only the file */
String filePath = dirURL.getPath().substring(5,
dirURL.getPath().indexOf("!"));
Enumeration<? extends ZipEntry> entries = null;
SlimevoidCore.console(CoreLib.MOD_ID,
"Jar protocol loaded!");
JarFile jar = new JarFile(URLDecoder.decode(filePath,
"UTF-8"));
entries = jar.entries();
SlimevoidCore.console(CoreLib.MOD_ID,
"JarFile initialized with the following [Path: "
+ filePath + ", Name: "
+ jar.getName()
+ ", Number of entries: "
+ entries);
Set<String> result = new HashSet<String>(); // avoid duplicates
// in
// case it is a
// subdirectory
if (entries != null) {
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);
}
/* Strip out empty names */
if (entry != "") {
result.add(entry);
}
}
}
if (result.size() > 0) {
SlimevoidCore.console(CoreLib.MOD_ID,
"Resource folder loaded ["
+ path
+ "], Number of resource files ["
+ result.size() + "]");
return result.toArray(new String[result.size()]);
}
}
} else {
SlimevoidCore.console(CoreLib.MOD_ID,
"Caution: Failed to read URL ["
+ dirURL.getPath()
+ "], unknown protocol ["
+ dirURL.getProtocol()
+ " | Pathed to [" + path + "]",
1);
}
} else {
SlimevoidCore.console(CoreLib.MOD_ID,
"Caution: Resource folder entries [" + path
+ "] could not be located!",
1);
}
UnsupportedOperationException uOE = new UnsupportedOperationException("Cannot list files for URL "
+ dirURL);
SlimevoidCore.console(CoreLib.MOD_ID,
uOE.getLocalizedMessage(),
1);
throw uOE;
}
public static boolean copyFile(final File toCopy, final File destFile) {
try {
return FileUtils.copyStream(new FileInputStream(toCopy),
new FileOutputStream(destFile));
} catch (final FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
public static boolean copyFilesRecusively(final File toCopy, final File destDir) {
assert destDir.isDirectory();
if (!toCopy.isDirectory()) {
return FileUtils.copyFile(toCopy,
new File(destDir, toCopy.getName()));
} else {
final File newDestDir = new File(destDir, toCopy.getName());
if (!newDestDir.exists() && !newDestDir.mkdir()) {
return false;
}
for (final File child : toCopy.listFiles()) {
if (!FileUtils.copyFilesRecusively(child,
newDestDir)) {
return false;
}
}
}
return true;
}
public static String removeStart(String str, String remove) {
if (isEmpty(str) || isEmpty(remove)) {
return str;
}
if (str.startsWith(remove)) {
return str.substring(remove.length());
}
return str;
}
public static boolean isEmpty(CharSequence cs) {
return cs == null || cs.length() == 0;
}
public static boolean copyJarResourcesRecursively(final File destDir, final JarURLConnection jarConnection) throws IOException {
final JarFile jarFile = jarConnection.getJarFile();
for (final Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements(); ) {
final JarEntry entry = e.nextElement();
if (entry.getName().startsWith(jarConnection.getEntryName())) {
final String filename = removeStart(entry.getName(), //
jarConnection.getEntryName());
final File f = new File(destDir, filename);
if (!entry.isDirectory()) {
final InputStream entryInputStream = jarFile.getInputStream(entry);
if (!FileUtils.copyStream(entryInputStream,
f)) {
return false;
}
entryInputStream.close();
} else {
if (!FileUtils.ensureDirectoryExists(f)) {
throw new IOException("Could not create directory: "
+ f.getAbsolutePath());
}
}
}
}
return true;
}
public static boolean copyResourcesRecursively( //
final URL originUrl, final File destination) {
try {
final URLConnection urlConnection = originUrl.openConnection();
if (urlConnection instanceof JarURLConnection) {
return FileUtils.copyJarResourcesRecursively(destination,
(JarURLConnection) urlConnection);
} else {
return FileUtils.copyFilesRecusively(new File(originUrl.getPath()),
destination);
}
} catch (final IOException e) {
e.printStackTrace();
}
return false;
}
public static boolean copyStream(final InputStream is, final File f) {
try {
return FileUtils.copyStream(is,
new FileOutputStream(f));
} catch (final FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
public static boolean copyStream(final InputStream is, final OutputStream os) {
try {
final byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) > 0) {
os.write(buf,
0,
len);
}
is.close();
os.close();
return true;
} catch (final IOException e) {
e.printStackTrace();
}
return false;
}
private static boolean ensureDirectoryExists(final File f) {
return f.exists() || f.mkdir();
}
}