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

com.ebmwebsourcing.easycommons.io.FileSystemHelper Maven / Gradle / Ivy

/****************************************************************************
 * Copyright (c) 2010-2012, EBM WebSourcing - All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of California, Berkeley nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/
 
package com.ebmwebsourcing.easycommons.io;

import static java.io.File.separator;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Random;
import java.util.regex.Pattern;

import org.apache.commons.lang.SystemUtils;

/**
 * @author Marc Jambert - EBM WebSourcing
 * @author Christophe DENEUX - Linagora
 */
public final class FileSystemHelper {

    /**
     * Error message of {@link #getRelativePath(File, File)} when the source
     * path is null
     */
    private final static String ILLEGAL_ARGUMENT_EXCEPTION_MSG_SRC_NULL = "The source path is null";

    /**
     * Error message of {@link #getRelativePath(File, File)} when the target
     * path is null
     */
    private final static String ILLEGAL_ARGUMENT_EXCEPTION_MSG_TARGET_NULL = "The target path is null";

    /**
     * Error message of {@link #getRelativePath(File, File)} when the source
     * directory is not an absolute directory.
     */
    private final static String ILLEGAL_ARGUMENT_EXCEPTION_MSG_SRC_NOT_ABSOLUTE = "The source is not an absolute directory";

    /**
     * Error message of {@link #getRelativePath(File, File)} when the source
     * directory is not a directory.
     */
    private final static String ILLEGAL_ARGUMENT_EXCEPTION_MSG_SRC_NOT_DIR = "The source is not an directory";

    /**
     * Error message of {@link #getRelativePath(File, File)} when the target
     * directory is not an absolute directory.
     */
    private final static String ILLEGAL_ARGUMENT_EXCEPTION_MSG_TARGET_NOT_ABSOLUTE = "The target is not an absolute path";

    private final static String FILE_SEPARATOR_AS_REGEXP = Pattern.quote(separator);

    private static final Random random = new Random();

    private FileSystemHelper() {
    }

    public static File createTempDir() throws IOException {
        return createTempDir("tmp"+random.nextInt());
    }

    public static File createTempDir(String prefix) throws IOException {
    	return Files.createTempDirectory(prefix).toFile();
    }

    public static File createTempDir(File parentDir, String prefix) throws IOException {
    	return Files.createTempDirectory(parentDir.toPath(), prefix).toFile();
    }

    /**
     * Cleans a directory without deleting it.
     * 
     * @param directory
     *            directory to clean
     * @throws IOException
     *             in case cleaning is unsuccessful
     */
    public static void cleanDirectory(File directory) throws IOException {
        assert directory != null;
        if (!directory.exists()) {
            String message = directory + " does not exist";
            throw new IOException(message);
        }
        if (!directory.isDirectory()) {
            String message = directory + " is not a directory";
            throw new IOException(message);
        }

        File[] files = directory.listFiles();
        if (files == null) { // null if security restricted
            throw new IOException("Failed to list contents of " + directory);
        }

        IOException exception = null;
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            try {
                forceDelete(file);
            } catch (IOException ioe) {
                exception = ioe;
            }
        }

        if (null != exception) {
            throw exception;
        }
    }

    /**
     * Deletes a file. If file is a directory, delete it and all
     * sub-directories.
     * 

* The difference between File.delete() and this method are: *

    *
  • A directory to be deleted does not have to be empty.
  • *
  • You get exceptions when a file or directory cannot be deleted. * (java.io.File methods returns a boolean)
  • *
* * @param file * file or directory to delete, must not be null * @throws NullPointerException * if the directory is null * @throws IOException * in case deletion is unsuccessful */ public static void forceDelete(File file) throws IOException { assert file != null; if (file.isDirectory()) { deleteDirectory(file); } else { if (!file.exists()) { return; } if (!file.delete()) { String message = "Unable to delete file: " + file; throw new IOException(message); } } } /** * Deletes a directory recursively. * * @param directory * directory to delete * @throws IOException * in case deletion is unsuccessful */ private static void deleteDirectory(File directory) throws IOException { if (!directory.exists()) { return; } cleanDirectory(directory); if (!directory.delete()) { String message = "Unable to delete directory " + directory + "."; throw new IOException(message); } } /** * Return relative path. *

* WARNING:
Folder path must finished with the character: * {@link File.separator} *

*
    * Example: * * * * * * * * * * * * * * * * * * * * * *
    sourcetargetrelative path
    /root/dir1/dir2//root/dir1/../
    /root//root/dir1/dir2/dir1/dir2/
    /root/dir1/dir2//root/test.xml../../test.xml
    * * * @param source * path of the source folder * @param target * path of the target folder/file * @return the relative path * @deprecated Use {@link FileSystemHelper#getRelativePath(File, File)} that * manages correctly non-relative paths and returns a correct * value for relative sub-directories (./dir1/dir2/ * ) */ @Deprecated public static String getRelativePath(String source, String target) { // Determine if the target is a file String targetFile = null; if (!source.endsWith(separator)) { throw new IllegalArgumentException(); } if (!target.endsWith(separator)) { int lastFolderIndex = target.lastIndexOf(separator) + 1; targetFile = target.substring(lastFolderIndex); target = target.substring(0, lastFolderIndex); } String[] sources = source.split(FILE_SEPARATOR_AS_REGEXP); String[] targets = target.split(FILE_SEPARATOR_AS_REGEXP); // Get the shortest of the two paths int length = sources.length < targets.length ? sources.length : targets.length; // Get the common part int common = 0; while (common < length) { if (sources[common].equals(targets[common])) { common++; } else { break; } } StringBuilder relativePathBuilder = new StringBuilder(); for (int i = common; i < sources.length; i++) { relativePathBuilder.append(".." + separator); } for (int i = common; i < targets.length; i++) { relativePathBuilder.append(targets[i] + separator); } if (targetFile != null) { relativePathBuilder.append(targetFile); } return relativePathBuilder.toString(); } /** * Return relative path. *
      * Example: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      sourcePathtargetPathrelative path
      /root/dir1/dir2//root/dir1/../
      /root//root/dir1/dir2/./dir1/dir2/
      /root/dir1/dir2//root/test.xml../../test.xml
      /root//notrelative/dir1//notrelative/dir1/
      /root/dir1/notrelative/test.xml/notrelative/test.xml
      * * * @param sourcePath * path of the source folder. MUST be an absolute directory. Not null. * @param targetPath * path of the target folder/file to relativize against sourcePath. MUST be an * absolute {@link File}. Not null * @return the relative path, or targetPath if paths are not relative * @throws IllegalArgumentException * if parameters are invalid */ public static String getRelativePath(final File sourcePath, final File targetPath) { // Check that the source path is not null if (sourcePath == null) { throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION_MSG_SRC_NULL); } // Check that the target path is not null if (targetPath == null) { throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION_MSG_TARGET_NULL); } // Check that the source path is an absolute path if (!sourcePath.isAbsolute()) { throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION_MSG_SRC_NOT_ABSOLUTE); } // Check that the source path is a directory if (!sourcePath.isDirectory()) { throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION_MSG_SRC_NOT_DIR); } // Check that the target path is an absolute path if (!targetPath.isAbsolute()) { throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION_MSG_TARGET_NOT_ABSOLUTE); } final String source; final String target; final String sourceAbsolutePath = sourcePath.getAbsolutePath(); final String targetAbsolutePath = targetPath.getAbsolutePath(); if (SystemUtils.IS_OS_WINDOWS) { // On Windows, relative paths are on the same drive. // If the drive letters of the absolute paths are not the same, the paths will be not relative final String sourceDrive = sourceAbsolutePath.substring(0, 2); final String targetDrive = targetAbsolutePath.substring(0, 2); if (targetDrive.equals(sourceDrive)) { // Drive letters are the same source = sourceAbsolutePath.substring(2); target = targetAbsolutePath.substring(2); } else { // Drive letters are different return targetPath.getAbsolutePath(); } } else { source = sourceAbsolutePath.substring(1); target = targetAbsolutePath.substring(1); } final String[] sources = source.split(FILE_SEPARATOR_AS_REGEXP); final String[] targets = target.split(FILE_SEPARATOR_AS_REGEXP); // Get the shortest of the two paths final int length = sources.length < targets.length ? sources.length : targets.length; // Get the common part int common = 0; while (common < length) { if (sources[common].equals(targets[common])) { common++; } else { break; } } if (common > 0) { final StringBuilder relativePathBuilder = new StringBuilder(); if (common == sources.length) { // target is a subdir of source relativePathBuilder.append(".").append(separator); } for (int i = common; i < sources.length; i++) { relativePathBuilder.append("..").append(separator); } for (int i = common; i < targets.length; i++) { relativePathBuilder.append(targets[i]); if (i < targets.length - 1) { relativePathBuilder.append(separator); } } return relativePathBuilder.toString(); } else { return targetPath.getAbsolutePath(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy