com.ejisto.util.IOUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.ejisto.util.IOUtils.java

Source

/*
 * Ejisto, a powerful developer assistant
 *
 * Copyright (C) 2010-2013 Celestino Bellone
 *
 * Ejisto is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Ejisto 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.ejisto.util;

import com.ejisto.constants.StringConstants;
import com.ejisto.core.ApplicationException;
import com.ejisto.modules.dao.entities.WebApplicationDescriptor;
import com.ejisto.modules.dao.entities.WebApplicationDescriptorElement;
import com.ejisto.modules.repository.SettingsRepository;
import com.ejisto.util.visitor.*;
import lombok.extern.log4j.Log4j;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.ejisto.constants.StringConstants.*;
import static com.ejisto.util.visitor.CopyType.*;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static org.apache.commons.io.FilenameUtils.getBaseName;
import static org.apache.commons.io.FilenameUtils.getName;

@Log4j
public final class IOUtils {

    private static final String COPIED_FILES_PREFIX = "ejisto__";
    private static final FileExtensionFilter jarFilter = new FileExtensionFilter(FileExtensionFilter.ALL_JARS,
            true);
    private static final String[] jarExtension = new String[] { "jar" };
    private static final String[] classExtension = new String[] { "class" };

    public static String copyFile(String filePath, File destDir) {
        File original = new File(filePath);
        return copyFile(original, destDir);
    }

    public static String copyFile(File original, File destDir) {
        try {
            File copy = new File(destDir, original.getName());
            FileUtils.copyFile(original, copy);
            return copy.getName();
        } catch (IOException e) {
            throw new ApplicationException(e);
        }
    }

    public static void copyFullDirContent(Path srcPath, Path targetPath) {
        copyDirContent(srcPath, targetPath, FileMatchers.all(), null, INCLUDE_ALL);
    }

    private static void copyDirContent(Path srcDir, Path targetDir, FileMatcher matcher,
            final String copiedFilesPrefix, CopyType copyType) {
        try {
            Files.walkFileTree(srcDir, new ConditionMatchingCopyFileVisitor(
                    new CopyOptions(srcDir, targetDir, matcher, copiedFilesPrefix, copyType)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void initPath(Path outputPath) throws IOException {
        if (!Files.exists(outputPath)) {
            Files.createDirectories(outputPath);
        }
    }

    public static void writeFile(InputStream inputStream, File baseDir, String filename) throws IOException {
        File out = new File(baseDir, filename);
        if (!out.getParentFile().exists() && !out.getParentFile().mkdirs()) {
            throw new IOException("Unable to write file " + out.getAbsolutePath());
        }
        FileOutputStream outputStream = new FileOutputStream(out);
        org.apache.commons.io.IOUtils.copy(inputStream, outputStream);
        org.apache.commons.io.IOUtils.closeQuietly(outputStream);
    }

    public static byte[] readFile(File file) throws IOException {
        return Files.readAllBytes(file.toPath());
    }

    public static String readInputStream(InputStream inputStream, String characterSet) throws IOException {
        byte[] read = org.apache.commons.io.IOUtils.toByteArray(inputStream);
        return new String(read, Charset.forName(characterSet));
    }

    public static String getFilenameWithoutExt(File file) {
        return getBaseName(file.getName());
    }

    private static List<WebApplicationDescriptorElement> getClasspathEntries(String basePath, URL[] baseUrls) {
        File base = new File(basePath);
        List<WebApplicationDescriptorElement> elements = new ArrayList<>();
        for (URL url : baseUrls) {
            elements.add(new WebApplicationDescriptorElement(url.getPath()));
        }
        elements.addAll(toWebApplicationDescriptorElement(getAllFiles(base, jarExtension)));
        return elements;
    }

    public static List<WebApplicationDescriptorElement> getClasspathEntries(String basePath)
            throws MalformedURLException {
        return getClasspathEntries(basePath, getSystemClasspathEntries());
    }

    private static URL[] getSystemClasspathEntries() throws MalformedURLException {
        String[] paths = System.getProperty("java.class.path").split(File.pathSeparator);
        URL[] urls = new URL[paths.length];
        for (int i = 0; i < paths.length; i++) {
            urls[i] = new File(paths[i]).toURI().toURL();
        }
        return urls;
    }

    public static URL[] addServerLibs(URL[] entries, String serverLibDir) throws MalformedURLException {
        Collection<File> jars = getAllFiles(new File(serverLibDir), new String[] { "jar" });
        URL[] ret = new URL[entries.length + jars.size()];
        System.arraycopy(entries, 0, ret, 0, entries.length);
        int pos = entries.length;
        for (File jar : jars) {
            ret[pos++] = jar.toURI().toURL();
        }
        return ret;
    }

    private static Collection<File> getAllFiles(File dir, String[] extensions) {
        if (!dir.exists() || !dir.isDirectory()) {
            return emptyList();
        }
        return FileUtils.listFiles(dir, extensions, true);
    }

    public static Collection<File> listJarFiles(Path dir) {
        return getAllFiles(dir.toFile(), jarExtension);
    }

    public static URL[] toUrlArray(WebApplicationDescriptor descriptor) throws MalformedURLException {
        List<URL> urls = new ArrayList<>();
        File base = new File(descriptor.getInstallationPath(), "WEB-INF");
        File classes = new File(base, "classes");
        File lib = new File(base, "lib");
        if (classes.exists()) {
            urls.add(classes.toURI().toURL());
        }
        for (WebApplicationDescriptorElement element : descriptor.getClassPathElements()) {
            urls.add(new File(lib, element.getPath()).toURI().toURL());
        }
        return urls.toArray(new URL[urls.size()]);
    }

    private static List<WebApplicationDescriptorElement> toWebApplicationDescriptorElement(Collection<File> in) {
        return in.stream().map(f -> new WebApplicationDescriptorElement(f.getName())).collect(Collectors.toList());
    }

    public static Collection<String> findAllWebApplicationClasses(String basePath,
            WebApplicationDescriptor descriptor) throws IOException {
        HashSet<String> ret = new HashSet<>();
        File webInf = new File(basePath, "WEB-INF");
        ret.addAll(findAllClassNamesInDirectory(new File(webInf, "classes")));
        ret.addAll(findAllClassNamesInJarDirectory(new File(webInf, "lib"), descriptor));
        return ret;
    }

    private static Collection<String> findAllClassNamesInDirectory(File directory) {
        int index = directory.getAbsolutePath().length();
        return getAllFiles(directory, classExtension).stream().filter(LambdaUtil.isDirectory().negate())
                .map(File::getPath).map(p -> translatePath(p.substring(index + 1, p.length() - 6)))
                .collect(Collectors.toSet());
    }

    private static Collection<String> findAllClassNamesInJarDirectory(File directory,
            WebApplicationDescriptor descriptor) throws IOException {
        HashSet<String> ret = new HashSet<>();
        for (File file : getAllFiles(directory, jarExtension)) {
            if (!descriptor.isBlacklistedEntry(file.getName())) {
                ret.addAll(findAllClassesInJarFile(file));
            }
        }
        return ret;
    }

    public static Collection<String> findAllClassesInJarFile(File jarFile) throws IOException {
        final List<String> ret = new ArrayList<>();
        Map<String, String> env = new HashMap<>();
        env.put("create", "false");
        try (FileSystem targetFs = FileSystems.newFileSystem(URI.create("jar:file:" + jarFile.getAbsolutePath()),
                env)) {
            final Path root = targetFs.getPath("/");
            Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    String ext = ".class";
                    if (attrs.isRegularFile() && file.getFileName().toString().endsWith(ext)) {
                        String path = root.relativize(file).toString();
                        ret.add(translatePath(path.substring(0, path.length() - ext.length()), "/"));
                    }
                    return FileVisitResult.CONTINUE;
                }
            });
        }
        return ret;
    }

    private static String translatePath(String in, String separator) {
        return in.replaceAll(Pattern.quote(separator), ".");
    }

    private static String translatePath(String in) {
        return translatePath(in, File.separator);
    }

    public static boolean deleteFile(String path) {
        return deleteFile(new File(path));
    }

    public static boolean deleteFile(File file) {
        if (!file.isDirectory()) {
            return FileUtils.deleteQuietly(file);
        }
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    public static boolean emptyDir(File file) {
        Path directory = file.toPath();
        if (!Files.isDirectory(directory)) {
            return true;
        }
        try {
            Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    if (exc == null) {
                        Files.delete(dir);
                        return FileVisitResult.CONTINUE;
                    }
                    return FileVisitResult.TERMINATE;
                }
            });
        } catch (IOException e) {
            IOUtils.log.error(format("error while trying to empty the directory %s", directory.toString()), e);
            return false;
        }
        return true;
    }

    public static void zipDirectory(File src, String outputFilePath) throws IOException {
        Path out = Paths.get(outputFilePath);
        if (Files.exists(out)) {
            Files.delete(out);
        }
        String filePath = out.toUri().getPath();
        Map<String, String> env = new HashMap<>();
        env.put("create", "true");
        try (FileSystem targetFs = FileSystems.newFileSystem(URI.create("jar:file:" + filePath), env)) {
            Files.walkFileTree(src.toPath(), new CopyFileVisitor(src.toPath(), targetFs.getPath("/")));
        }
    }

    @SafeVarargs
    public static void unzipFile(File src, String outputDirectory, FileVisitor<Path>... additionalVisitor)
            throws IOException {
        unzipFile(src, Paths.get(outputDirectory), additionalVisitor);
    }

    @SafeVarargs
    public static void unzipFile(File src, Path outputDirectory, FileVisitor<Path>... additionalVisitor)
            throws IOException {
        if (!Files.exists(outputDirectory)) {
            Files.createDirectories(outputDirectory);
        }
        if (!Files.isDirectory(outputDirectory)) {
            throw new IllegalStateException(outputDirectory.toUri() + " is not a directory");
        }
        try (FileSystem fileSystem = FileSystems.newFileSystem(URI.create("jar:file:" + src.getAbsolutePath()),
                Collections.<String, Object>emptyMap())) {
            final Path srcRoot = fileSystem.getPath("/");
            FileVisitor<Path> visitor = new MultipurposeFileVisitor<>(new CopyFileVisitor(srcRoot, outputDirectory),
                    additionalVisitor);
            Files.walkFileTree(srcRoot, visitor);
        }
    }

    public static String retrieveFilenameFromPath(String filename) {
        return getName(filename);
    }

    public static String guessWebApplicationUri(WebApplicationDescriptor descriptor,
            SettingsRepository settingsRepository) {
        return guessWebApplicationUri(descriptor.getContextPath(), settingsRepository);
    }

    public static String guessWebApplicationUri(String contextPath, SettingsRepository settingsRepository) {
        return format("http://localhost:%s%s/", settingsRepository.getSettingValue(DEFAULT_SERVER_PORT),
                contextPath);
    }

    public static int findFirstAvailablePort(int startPort) {
        for (int port = startPort, max = port + 100; port < max; port++) {
            if (isPortAvailable(port)) {
                return port;
            }
        }
        throw new RuntimeException("Unable to find a port");
    }

    private static boolean isPortAvailable(int port) {
        try (DatagramSocket udp = new DatagramSocket(port); ServerSocket tcp = new ServerSocket(port)) {
            tcp.setReuseAddress(true);
            udp.setReuseAddress(true);
            return true;
        } catch (IOException ex) {
            return false;
        }
    }

    public static void copyEjistoLibs(boolean embeddable, Path targetDir) {
        //special handling for development mode
        Path libDir = Paths.get(System.getProperty("user.dir"), getActualLibDirectory());
        String fileSuffix = embeddable ? "session-recorder" : "runtime";
        copyDirContent(libDir, targetDir,
                FileMatchers.regexpMatcher("^ejisto-application-.*?-" + fileSuffix + "-libraries.*$",
                        INCLUDE_ONLY_MATCHING_RESOURCES),
                null, INCLUDE_ONLY_ROOT_MATCHING_RESOURCES);
    }

    private static String getActualLibDirectory() {
        return Boolean.getBoolean(StringConstants.DEV_MODE.getValue()) ? "" : "lib";
    }

    public static String getEjistoCoreClasspathEntry(SettingsRepository settingsRepository) {
        return System.getProperty("user.dir") + File.separator + "lib" + File.separator + "ejisto-core-"
                + settingsRepository.getSettingValue(EJISTO_VERSION) + ".jar";
    }

    public static URL fileToUrl(File f) {
        try {
            return f.toURI().toURL();
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

    private static String getLocalAddress() throws UnknownHostException {
        return InetAddress.getLocalHost().getHostAddress();
    }

    public static String getHttpInterfaceAddress() throws IOException {
        return format("http://%s:%s", getLocalAddress(), System.getProperty(HTTP_LISTEN_PORT.getValue()));
    }
}