com.github.fritaly.dualcommander.Utils.java Source code

Java tutorial

Introduction

Here is the source code for com.github.fritaly.dualcommander.Utils.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.fritaly.dualcommander;

import java.awt.Color;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.Validate;

public class Utils {

    public static int getTimestampRenderWidth() {
        final String text = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        final Font font = Utils.getDefaultFont();
        final FontRenderContext context = new FontRenderContext(new AffineTransform(), true, true);

        return (int) font.getStringBounds(text, context).getWidth();
    }

    public static Border createEmptyBorder(int space) {
        return BorderFactory.createEmptyBorder(space, space, space, space);
    }

    public static Border createRaisedBevelBorder() {
        return BorderFactory.createCompoundBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED),
                Utils.createEmptyBorder(1));
    }

    private static class NegatingComparator<T> implements Comparator<T> {

        private final Comparator<T> decorated;

        NegatingComparator(Comparator<T> decorated) {
            Validate.notNull(decorated, "The given comparator is null");

            this.decorated = decorated;
        }

        @Override
        public int compare(T o1, T o2) {
            // Swap the 2 arguments
            return decorated.compare(o2, o1);
        }
    }

    public static <T> Comparator<T> negate(Comparator<T> comparator) {
        Validate.notNull(comparator, "The given comparator is null");

        if (comparator instanceof NegatingComparator) {
            return ((NegatingComparator<T>) comparator).decorated;
        }

        return new NegatingComparator<T>(comparator);
    }

    /**
     * Recursively deletes the given file or directory and notifies the provided
     * handler when a file / directory has been deleted.
     *
     * @param file
     *            the file / directory to delete. Can't be null.
     * @param handler
     *            a possible listener to be notified of file deletions. Can be
     *            null.
     */
    public static void deleteRecursively(File file, FileHandler handler) {
        // The given file can be a file or a directory
        // The given listener can be null
        Validate.notNull(file, "The given file is null");

        if (file.isDirectory()) {
            // Delete the directory recursively
            for (File entry : file.listFiles()) {
                deleteRecursively(entry, handler);
            }
        }

        // Delete the file or the empty directory
        file.delete();

        if (handler != null) {
            handler.handle(file);
        }
    }

    public static Color getDefaultBackgroundColor() {
        return new JLabel().getBackground();
    }

    public static Font getDefaultFont() {
        return new JLabel().getFont();
    }

    private static Properties getApplicationProperties() {
        try {
            final Properties properties = new Properties();
            properties.load(Utils.class.getResourceAsStream("/application.properties"));

            return properties;
        } catch (IOException e) {
            // Should never happen
            throw new RuntimeException(
                    "Unable to load application properties from resource file 'application.properties'", e);
        }
    }

    public static String getApplicationVersion() {
        return getApplicationProperties().getProperty("version");
    }

    public static Date getApplicationReleaseDate() {
        try {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm.ss (Z)")
                    .parse(getApplicationProperties().getProperty("release.date"));
        } catch (ParseException e) {
            // Return null (happens when the value hasn't been replaced and is
            // set to @RELEASE_DATE@)
            return null;
        }
    }

    // --- The following methods were copied from commons-io's FileUtils --- //

    /**
     * The number of bytes in a kilobyte.
     */
    public static final long ONE_KB = 1024;

    /**
     * The number of bytes in a megabyte.
     */
    public static final long ONE_MB = ONE_KB * ONE_KB;

    /**
     * The file copy buffer size (30 MB)
     */
    private static final long FILE_COPY_BUFFER_SIZE = ONE_MB * 30;

    public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException {
        if (srcDir == null) {
            throw new NullPointerException("Source must not be null");
        }
        if (srcDir.exists() && srcDir.isDirectory() == false) {
            throw new IllegalArgumentException("Source '" + destDir + "' is not a directory");
        }
        if (destDir == null) {
            throw new NullPointerException("Destination must not be null");
        }
        if (destDir.exists() && destDir.isDirectory() == false) {
            throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
        }
        copyDirectory(srcDir, new File(destDir, srcDir.getName()), true);
    }

    public static void copyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException {

        copyDirectory(srcDir, destDir, null, preserveFileDate);
    }

    public static void copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate)
            throws IOException {
        if (srcDir == null) {
            throw new NullPointerException("Source must not be null");
        }
        if (destDir == null) {
            throw new NullPointerException("Destination must not be null");
        }
        if (srcDir.exists() == false) {
            throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
        }
        if (srcDir.isDirectory() == false) {
            throw new IOException("Source '" + srcDir + "' exists but is not a directory");
        }
        if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) {
            throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same");
        }

        // Cater for destination being directory within the source directory (see IO-141)
        List<String> exclusionList = null;
        if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {
            File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
            if (srcFiles != null && srcFiles.length > 0) {
                exclusionList = new ArrayList<String>(srcFiles.length);
                for (File srcFile : srcFiles) {
                    File copiedFile = new File(destDir, srcFile.getName());
                    exclusionList.add(copiedFile.getCanonicalPath());
                }
            }
        }
        doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
    }

    private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate,
            List<String> exclusionList) throws IOException {
        // recurse
        File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
        if (srcFiles == null) { // null if abstract pathname does not denote a directory, or if an I/O error occurs
            throw new IOException("Failed to list contents of " + srcDir);
        }
        if (destDir.exists()) {
            if (destDir.isDirectory() == false) {
                throw new IOException("Destination '" + destDir + "' exists but is not a directory");
            }
        } else {
            if (!destDir.mkdirs() && !destDir.isDirectory()) {
                throw new IOException("Destination '" + destDir + "' directory cannot be created");
            }
        }
        if (destDir.canWrite() == false) {
            throw new IOException("Destination '" + destDir + "' cannot be written to");
        }
        for (File srcFile : srcFiles) {
            File dstFile = new File(destDir, srcFile.getName());
            if (exclusionList == null || !exclusionList.contains(srcFile.getCanonicalPath())) {
                if (srcFile.isDirectory()) {
                    doCopyDirectory(srcFile, dstFile, filter, preserveFileDate, exclusionList);
                } else {
                    doCopyFile(srcFile, dstFile, preserveFileDate);
                }
            }
        }

        // Do this last, as the above has probably affected directory metadata
        if (preserveFileDate) {
            destDir.setLastModified(srcDir.lastModified());
        }
    }

    private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
        if (destFile.exists() && destFile.isDirectory()) {
            throw new IOException("Destination '" + destFile + "' exists but is a directory");
        }

        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel input = null;
        FileChannel output = null;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            input = fis.getChannel();
            output = fos.getChannel();
            long size = input.size();
            long pos = 0;
            long count = 0;
            while (pos < size) {
                count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos;
                pos += output.transferFrom(input, pos, count);
            }
        } finally {
            IOUtils.closeQuietly(output);
            IOUtils.closeQuietly(fos);
            IOUtils.closeQuietly(input);
            IOUtils.closeQuietly(fis);
        }

        if (srcFile.length() != destFile.length()) {
            throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'");
        }
        if (preserveFileDate) {
            destFile.setLastModified(srcFile.lastModified());
        }
    }

    public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate)
            throws IOException {
        if (destDir == null) {
            throw new NullPointerException("Destination must not be null");
        }
        if (destDir.exists() && destDir.isDirectory() == false) {
            throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory");
        }
        File destFile = new File(destDir, srcFile.getName());
        copyFile(srcFile, destFile, preserveFileDate);
    }

    public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
        if (srcFile == null) {
            throw new NullPointerException("Source must not be null");
        }
        if (destFile == null) {
            throw new NullPointerException("Destination must not be null");
        }
        if (srcFile.exists() == false) {
            throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
        }
        if (srcFile.isDirectory()) {
            throw new IOException("Source '" + srcFile + "' exists but is a directory");
        }
        if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
            throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
        }
        File parentFile = destFile.getParentFile();
        if (parentFile != null) {
            if (!parentFile.mkdirs() && !parentFile.isDirectory()) {
                throw new IOException("Destination '" + parentFile + "' directory cannot be created");
            }
        }
        if (destFile.exists() && destFile.canWrite() == false) {
            throw new IOException("Destination '" + destFile + "' exists but is read-only");
        }
        doCopyFile(srcFile, destFile, preserveFileDate);
    }

    public static Font getBoldFont(Font font) {
        Validate.notNull(font, "The given font is null");

        return new Font(font.getName(), font.getStyle() | Font.BOLD, font.getSize());
    }

    public static Scan scan(Collection<File> collection) {
        Validate.notNull(collection, "The given collection of files is null");

        final Scan scan = new Scan();

        for (File element : collection) {
            if (element.isFile()) {
                scan.visitFile(element);
            } else {
                try {
                    Files.walkFileTree(element.toPath(), scan);
                } catch (IOException e) {
                    throw new RuntimeException("Error when walking directory '" + element + "'", e);
                }
            }
        }

        return scan;
    }
}