All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ehoffman.resources.ResourceUtils Maven / Gradle / Ivy

The newest version!
package org.ehoffman.resources;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Using the classpath as a filesystem. Usually via temp dirs.
 * 
 * @author rex
 */
public final class ResourceUtils {

    private static final String JBOSS_VFS_VIRTUAL_CLASSNAME = "org.jboss.vfs.VirtualFile";
    private static final int BUFFER_SIZE_4K = 4096;
    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceUtils.class);
    private static final String ERROR_COPYING_FILE = "error copying file";

    private ResourceUtils() {
    }

    public static boolean copyFile(final File toCopy, final File destFile, final boolean overwrite) {
        try {
            if (destFile.exists()) {
                if (!overwrite) {
                    return true;
                }
            } else {
                destFile.createNewFile();
            }
            return ResourceUtils.copyStream(new FileInputStream(toCopy), new FileOutputStream(destFile));
        } catch (final FileNotFoundException e) {
            LOGGER.error("error creating file to copy in to", e);
        } catch (final IOException e) {
            LOGGER.error(ERROR_COPYING_FILE, e);
        }
        return false;
    }

    private static boolean copyFilesRecusively(final File toCopy, final File destDir, final boolean overwrite) {
        if (!destDir.exists() && !destDir.mkdir()) {
            return false;
        }
        if (!toCopy.isDirectory()) {
            return ResourceUtils.copyFile(toCopy, new File(destDir, toCopy.getName()), overwrite);
        } else {
            for (final File child : toCopy.listFiles()) {
                File newDestDir = destDir;
                if (child.isDirectory()) {
                    newDestDir = new File(destDir, child.getName());
                }
                if (!ResourceUtils.copyFilesRecusively(child, newDestDir, overwrite)) {
                    return false;
                }
            }
        }
        return true;
    }

    private static String removeStart(final String value, final String potentialPrefix) {
        if (value.startsWith(potentialPrefix)) {
            return value.substring(potentialPrefix.length());
        }
        return value;
    }

    public static boolean copyJarResourcesRecursively(final File destDir, final JarURLConnection jarConnection,
            final boolean overwrite) throws IOException {
        final JarFile jarFile = jarConnection.getJarFile();
        for (final Enumeration e = jarFile.entries(); e.hasMoreElements();) {
            final JarEntry entry = e.nextElement();
            if (entry.getName().startsWith(jarConnection.getEntryName())) {

                String filename = removeStart(entry.getName(), jarConnection.getEntryName());
                if (filename.endsWith("/")) {
                    filename = filename.substring(0, filename.length() - 1);
                }
                if (filename != null && !filename.isEmpty()) {
                    final File f = new File(destDir, filename).getAbsoluteFile();
                    if (!entry.isDirectory()) {
                        InputStream entryInputStream = null;
                        try {
                            entryInputStream = jarFile.getInputStream(entry);
                            if (!ResourceUtils.copyStream(entryInputStream, f, overwrite)) {
                                return false;
                            }
                        } finally {
                            closeQuietly(entryInputStream);
                        }
                    } else {
                        if (!ResourceUtils.ensureDirectoryExists(f)) {
                            throw new IOException("Could not create directory: " + f.getAbsolutePath() + " for file " + filename);
                        }
                    }
                }
            }
        }
        return true;
    }

    public static File getHomeFolder() {
        try {
            final String homedirpath = System.getProperty("user.home");
            if (homedirpath == null) {
                return null;
            }
            final File homedir = new File(homedirpath).getAbsoluteFile();
            if (homedir.exists()) {
                return homedir;
            } else {
                return null;
            }
        } catch (final SecurityException e) {
            return null;
        }
    }

    public static boolean isHomeFolderWritable() {
        final File home = getHomeFolder();
        return home != null && home.canWrite();
    }

    public static File getWriteableTempDir() {
        try {
            final File tempdir = new File(File.createTempFile("testGetIrradiance", "test")
                   .getAbsoluteFile().getParent().toString());
            return tempdir;
        } catch (final IOException e) {
            return null;
        } catch (final SecurityException e) {
            return null;
        }
    }

    static File getLongLivedWritableDirIfPossible() {
        File destFile = null;
        if (isHomeFolderWritable()) {
            return getHomeFolder();
        }
        if (destFile == null) {
            destFile = getWriteableTempDir();
        }
        return destFile;
    }

    /**
     * 
     * @param originUrl
     * @param dirName
     *            a directory to create as a root to copy the originUrls to. The directory name is meant to be a simple single dir.
     *            that will likely end up in the users home dir if possible, or as a folder in a temp directory otherwise.
     * 
     * @return File root dir where resources end up or null;
     */
    public static File ensureResourcesAreAvailable(final URL originUrl, final String dirName, final boolean overwrite) {
        final File destFile = getLongLivedWritableDirIfPossible();
        if (destFile != null && copyResourcesRecursively(originUrl, destFile, overwrite)) {
            return destFile;
        } else {
            return null;
        }
    }

    public static boolean copyResourcesRecursively(final URL originUrl, final File destination, final boolean overwrite) {
        try {
            LOGGER.info("Attempting to copy URL :" + originUrl);
            final URLConnection urlConnection = originUrl.openConnection();
            if (urlConnection instanceof JarURLConnection) {
                return ResourceUtils.copyJarResourcesRecursively(destination, (JarURLConnection) urlConnection, overwrite);
            } else if (urlConnection.getContent().getClass().getName().equals(JBOSS_VFS_VIRTUAL_CLASSNAME)) {
                return ResourceUtils.copyFilesRecusively(JbossVitualFileSystemWTFWorkAround.fixJbossesScrewUp(urlConnection),
                        destination, overwrite);
            } else {
                return ResourceUtils.copyFilesRecusively(new File(originUrl.getPath()), destination, overwrite);
            }
        } catch (final IOException e) {
            LOGGER.error(ERROR_COPYING_FILE, e);
        }
        return false;
    }

    private static boolean copyStream(final InputStream is, final File f, final boolean overwrite) {
        if (!overwrite && f.exists()) {
            return true;
        }
        try {
            f.createNewFile();
            return ResourceUtils.copyStream(is, new FileOutputStream(f));
        } catch (final FileNotFoundException e) {
            LOGGER.error(ERROR_COPYING_FILE, e);
        } catch (final IOException e) {
            LOGGER.error(ERROR_COPYING_FILE, e);
        }
        return false;
    }

    /**
     * Reads all bytes from an input stream into a byte array.
     * Does not close the stream.
     * @param input stream read from
     * @return a byte array containing all the bytes from the stream
     * @throws IOException
     */
    public static byte[] toByteArray(final InputStream input) throws IOException {
      final ByteArrayOutputStream out = new ByteArrayOutputStream();
      copyStream(input, out);
      return out.toByteArray();
    }

    private static boolean copyStream(final InputStream is, final OutputStream os) {
        try {
            final byte[] buf = new byte[BUFFER_SIZE_4K];
            int len = 0;
            while ((len = is.read(buf)) > 0) {
                os.write(buf, 0, len);
            }
            return true;
        } catch (final IOException e) {
            LOGGER.error(ERROR_COPYING_FILE, e);
        } finally {
            closeQuietly(is);
            closeQuietly(os);
        }
        return false;
    }

    private static boolean ensureDirectoryExists(final File f) {
        return (f.exists() && f.isDirectory()) || f.mkdirs();
    }

    private static void closeQuietly(final Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (final IOException e) {
                LOGGER.warn("Could not close cleanly", e);
            }
        }
    }

    public static boolean deleteRecursively(final File root) {
        if (root != null && root.exists()) {
            if (root.isDirectory()) {
                final File[] children = root.listFiles();
                if (children != null) {
                    for (int i = 0; i < children.length; i++) {
                        deleteRecursively(children[i]);
                    }
                }
            }
            return root.delete();
        }
        return false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy