org.expath.pkg.repo.FileHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pkg-java Show documentation
Show all versions of pkg-java Show documentation
Java Library implementing the core EXPath Packaging features
/****************************************************************************/
/* File: FileHelper.java */
/* Author: F. Georges - H2O Consulting */
/* Date: 2011-04-14 */
/* Tags: */
/* Copyright (c) 2011 Florent Georges (see end of file.) */
/* ------------------------------------------------------------------------ */
package org.expath.pkg.repo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Centralize some file-related utilities.
*
* @author Florent Georges
*/
public class FileHelper
{
/**
* Create a directory if it does not exist yet.
*
* Throw an error if the directory already exists and is not actually a
* directory, or if there is an error creating it.
*
* @param dir the directory path
*
* @throws PackageException if an error occurs
*/
public static void ensureDir(Path dir)
throws PackageException
{
// if it does not exist, create it
if ( ! Files.exists(dir) ) {
try {
Files.createDirectories(dir);
} catch (final IOException e) {
throw new PackageException("Error creating the directory: " + dir, e);
}
}
// but if it exists and is not a dir, that's an error
else if ( ! Files.isDirectory(dir) ) {
throw new PackageException("The directory is not a directory: " + dir);
}
}
/**
* Create a new directory within {@code parent}.
*
* The new directory is empty, and its name is based on {@code prefix},
* and on the current date after the prefix.
*
* @param prefix the prefix for the temporary directory
* @param parent the directory in which to create the temporary directory
*
* @return the path to the temporary directory.
*
* @throws PackageException if an error occurs
*/
public static Path makeTempDir(final String prefix, final Path parent)
throws PackageException
{
Date now = new Date();
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
String today = fmt.format(now);
try {
return Files.createTempDirectory(parent, prefix + "-" + today + "-");
}
catch ( IOException ex ) {
throw new PackageException("Error creating a temporary file", ex);
}
}
public static void renameTmpDir(Path from, Path to)
throws PackageException
{
try {
Files.move(from, to);
} catch (final IOException e) {
// if renaming failed and we're not on Windows, that's an error
// if renaming failed and we're on Windows, we try several things, as
// this can be related to tricky Windows locking handling...
if (!System.getProperty("os.name").startsWith("Windows") ) {
throw new PackageException("Renaming '" + from + "' to '" + to + "' failed", e);
}
// windows - then try to copy the whole thing
try {
copy(from, to);
} catch (final IOException ioe) {
throw new PackageException("Copying '" + from + "' to '" + to + "' failed", ioe);
}
boolean res = deleteQuietly(from);
if ( ! res ) {
System.err.println("Error deleting dir: " + from);
}
}
}
/**
* Copies a path within the filesystem
*
* If the path is a directory its contents
* will be recursively copied.
*
* Note that copying of a directory is not an atomic-operation
* and so if an error occurs during copying, some of the directories
* descendants may have already been copied.
*
* @param source the source file or directory
* @param destination the destination file or directory
*
* @throws IOException if an error occurs whilst copying a file or directory
*/
public static void copy(final Path source, final Path destination) throws IOException {
if (!Files.isDirectory(source)) {
Files.copy(source, destination);
} else {
if (Files.exists(destination) && !Files.isDirectory(destination)) {
throw new IOException("Cannot copy a directory to a file");
}
Files.walkFileTree(source, copyDirVisitor(source, destination));
}
}
private final static SimpleFileVisitor copyDirVisitor(final Path source, final Path destination) throws IOException {
if (!Files.isDirectory(source)) {
throw new IOException("source must be a directory");
}
if (!Files.isDirectory(destination)) {
throw new IOException("destination must be a directory");
}
return new CopyDirVisitor(source, destination);
}
private static class CopyDirVisitor extends SimpleFileVisitor {
private final Path source;
private final Path destination;
public CopyDirVisitor(final Path source, final Path destination) {
this.source = source;
this.destination = destination;
}
@Override
public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException {
final Path relSourceDir = source.relativize(dir);
final Path targetDir = destination.resolve(relSourceDir);
Files.createDirectories(targetDir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
final Path relSourceFile = source.relativize(file);
final Path targetFile = destination.resolve(relSourceFile);
Files.copy(file, targetFile);
return FileVisitResult.CONTINUE;
}
}
public static boolean deleteQuietly(final Path path) {
try {
if (!Files.isDirectory(path)) {
return Files.deleteIfExists(path);
} else {
Files.walkFileTree(path, deleteDirVisitor);
}
return true;
} catch (final IOException ioe) {
LOG.info("Failed to delete " + path.toString(), ioe);
return false;
}
}
private final static SimpleFileVisitor deleteDirVisitor = new DeleteDirVisitor();
private static class DeleteDirVisitor extends SimpleFileVisitor {
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
Files.deleteIfExists(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
if (exc != null) {
throw exc;
}
Files.deleteIfExists(dir);
return FileVisitResult.CONTINUE;
}
}
/**
* A list of the entries in the directory. The listing is not recursive.
*
* @param directory The directory to list the entries for
*
* @return The list of entries
*
* @throws IOException if the an error occurs whilst listing the directories
*/
public static List list(final Path directory) throws IOException {
try(final Stream entries = Files.list(directory)) {
return entries.collect(Collectors.toList());
}
}
public static boolean isEmpty(final Path directory) {
try(final Stream entries = Files.list(directory)) {
return !entries.findFirst().isPresent();
} catch (final IOException e) {
return true;
}
}
/** The logger. */
private static final Logger LOG = LoggerFactory.getLogger(FileHelper.class);
}
/* ------------------------------------------------------------------------ */
/* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS COMMENT. */
/* */
/* The contents of this file are subject to the Mozilla Public License */
/* Version 1.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.mozilla.org/MPL/. */
/* */
/* Software distributed under the License is distributed on an "AS IS" */
/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
/* the License for the specific language governing rights and limitations */
/* under the License. */
/* */
/* The Original Code is: all this file. */
/* */
/* The Initial Developer of the Original Code is Florent Georges. */
/* */
/* Contributor(s): none. */
/* ------------------------------------------------------------------------ */
© 2015 - 2024 Weber Informatics LLC | Privacy Policy