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

nl.hsac.fitnesse.fixture.util.FileUtil Maven / Gradle / Ivy

There is a newer version: 5.3.18
Show newest version
package nl.hsac.fitnesse.fixture.util;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.Collection;
import java.util.Scanner;

/**
 * File utilities.
 */
public final class FileUtil {
    private static final int BUFFER_SIZE = 4096;
    private static final String FILE_ENCODING = "UTF-8";
    private static final String[] HTML_EXTENSIONS = {"html"};

    private FileUtil() {
        // ensure no instance is made.
    }

    /**
     * Reads content of UTF-8 file on classpath to String.
     *
     * @param filename file to read.
     * @return file's content.
     * @throws IllegalArgumentException if file could not be found.
     * @throws IllegalStateException if file could not be read.
     */
    public static String loadFile(String filename) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream is = classLoader.getResourceAsStream(filename);
        if (is == null) {
            throw new IllegalArgumentException("Unable to locate: " + filename);
        }
        return streamToString(is, filename);
    }

    /**
     * Copies UTF-8 input stream's content to a string (closes the stream).
     *
     * @param inputStream input stream (UTF-8) to read.
     * @param fileName description for stream in error messages.
     * @return content of stream
     * @throws RuntimeException if content could not be read.
     */
    public static String streamToString(InputStream inputStream, String fileName) {
        return streamToString(inputStream, fileName, null);
    }

    /**
     * Copies first  or all lines from UTF-8 input stream's content to a
     * string and closes the stream.
     *
     * @param is input stream (UTF-8) to read.
     * @param name description for stream in error messages.
     * @param numberOfLines number of lines to be read from input stream - if null, all lines are read
     * @return content of stream
     * @throws RuntimeException if content could not be read.
     */
    public static String streamToString(InputStream is, String name, Integer numberOfLines) {
        String result = null;
        try {
            try {
                if (numberOfLines == null) {
                    // read complete file into string
                    result = new Scanner(is, FILE_ENCODING).useDelimiter("\\A").next();
                } else {
                    // read only given number of lines
                    Scanner scanner = new Scanner(is, FILE_ENCODING);
                    int resultNrOfLines = 1;
                    result = "";
                    while (scanner.hasNext()) {
                        result = result + scanner.nextLine() + System.lineSeparator();
                        if (++resultNrOfLines > numberOfLines) {
                            break;
                        }
                    }
                    scanner.close();
                    if (result.isEmpty()) {
                        result = null;
                    }
                }
            } catch (java.util.NoSuchElementException e) {
                throw new IllegalStateException("Unable to read: " + name + ". Error: " + e.getMessage(), e);
            }
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                // what the hell?!
                throw new RuntimeException("Unable to close: " + name, e);
            }
        }
        return result;
    }

    /**
     * Copies source file to target.
     * @param source source file to copy.
     * @param target destination to copy to.
     * @return target as File.
     * @throws IOException when unable to copy.
     */
    public static File copyFile(String source, String target) throws IOException {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(target).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } finally {
            if (inputChannel != null) {
                inputChannel.close();
            }
            if (outputChannel != null) {
                outputChannel.close();
            }
        }
        return new File(target);
    }

    /**
     * Copy the contents of the given InputStream to the given OutputStream.
     * Closes both streams when done.
     *
     * @param in the stream to copy from
     * @param out the stream to copy to
     * @return the number of bytes copied
     * @throws java.io.IOException in case of I/O errors
     */
    public static int copy(InputStream in, OutputStream out) throws IOException {
        try {
            int byteCount = 0;
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = -1;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
                byteCount += bytesRead;
            }
            out.flush();
            return byteCount;
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            try {
                out.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    /**
     * Writes content to file, in UTF-8 encoding.
     *
     * @param filename file to create or overwrite.
     * @param content content to write.
     * @return file reference to file.
     */
    public static File writeFile(String filename, String content) {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(filename, FILE_ENCODING);
            pw.write(content);
            pw.flush();
        } catch (FileNotFoundException e) {
            throw new IllegalArgumentException("Unable to write to: " + filename, e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
        return new File(filename);
    }

    public static File  writeFromScanner(String filename, Scanner sc) {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(filename, FILE_ENCODING);

            while (sc.hasNextLine()) {
                String next = sc.nextLine();
                pw.write(next + System.getProperty("line.separator"));
            }
        } catch (FileNotFoundException e){
            throw new IllegalArgumentException("Unable to write to: " + filename + ".tmp", e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }  finally {
            if(pw != null) {
                pw.flush();
                pw.close();
            }
        }
        return new File(filename);
    }

    /**
     * Saves byte[] to new file.
     *
     * @param baseName name for file created (without extension),
     *                 if a file already exists with the supplied name an
     *                 '_index' will be added.
     * @param extension extension for file.
     * @param content data to store in file.
     * @return absolute path of created file.
     */
    public static String saveToFile(String baseName, String extension, byte[] content) {
        String result;
        File output = determineFilename(baseName, extension);
        FileOutputStream target = null;
        try {
            target = new FileOutputStream(output);
            target.write(content);
            result = output.getAbsolutePath();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (target != null) {
                try {
                    target.close();
                } catch (IOException ex) {
                    // what to to?
                }
            }
        }
        return result;
    }

    private static File determineFilename(String baseName, String extension) {
        if (!StringUtils.isEmpty(extension)) {
            extension = "." + extension;
        }
        File output = new File(baseName + extension);
        // ensure directory exists
        File parent = output.getAbsoluteFile().getParentFile();
        if (!parent.exists()) {
            if (!parent.mkdirs()) {
                throw new IllegalArgumentException(
                        "Unable to create directory: "
                                + parent.getAbsolutePath());
            }
        }
        int i = 0;
        // determine first filename not yet in use.
        while (output.exists()) {
            i++;
            String name = String.format("%s_%s%s", baseName, i, extension);
            output = new File(name);
        }
        return output;
    }

    /**
     * FitNesse has an issue where .html files in the files section break the wiki server
     * we ensure all generated reports have .HTML extension.
     * Furthermore we update the content of the .html files, by also updating the extension there,
     * expecting to fix links between files.
     * @param dir directory to look for .html files in
     * @throws IOException when unable to
     */
    public static void ensureNoHtmlFiles(String dir) throws IOException {
        Collection htmlFiles = FileUtils.listFiles(new File(dir), HTML_EXTENSIONS, true);
        for (File f : htmlFiles) {
            String htmlFile = f.getAbsolutePath();
            String srcContent = FileUtil.streamToString(new FileInputStream(f), htmlFile);
            if (!f.delete()) {
                throw new IOException("Unable to delete " + htmlFile);
            }

            // fix links inside content
            String targetContent = srcContent.replace(".html", ".HTML");
            String targetName = htmlFile.replace(".html", ".HTML");
            File target = FileUtil.writeFile(targetName, targetContent);
            if (!target.exists()) {
                throw new IOException("Unable to create " + targetName);
            }
        }
    }

    /**
     * Determines a file's relative path related to a base directory (a parent some levels up in the tree).
     * @param base base directory.
     * @param child file to get relative path for.
     * @return relative path.
     */
    public static String getRelativePath(String base, String child) {
        return new File(base).toURI().relativize(new File(child).toURI()).getPath();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy