/****************************************************************************/ /* 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 java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; /** * 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. */ public static void ensureDir(File dir) throws PackageException { // if it does not exist, create it if ( ! dir.exists() ) { boolean res = dir.mkdir(); if ( ! res ) { throw new PackageException("Error creating the directory: " + dir); } } // but if it exists and is not a dir, that's an error else if ( ! dir.isDirectory() ) { 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. */ public static File makeTempDir(String prefix, File parent) throws PackageException { Date now = new Date(); SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); String today = fmt.format(now); File tmp; try { tmp = File.createTempFile(prefix + "-" + today + "-", ".d", parent); } catch ( IOException ex ) { throw new PackageException("Error creating a temporary file", ex); } if ( ! tmp.delete() ) { throw new PackageException("Error removing the temporary file: " + tmp); } if ( ! tmp.mkdir() ) { throw new PackageException("Error creating the temporary dir: " + tmp); } return tmp; } public static void renameTmpDir(File from, File to) throws PackageException { boolean failed = ! from.renameTo(to); // 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 stpid Windows locking handling... if ( failed && ! System.getProperty("os.name").startsWith("Windows") ) { throw new PackageException("Renaming '" + from + "' to '" + to + "' failed"); } // if the renaming fails, max. 5 times... for ( int i = 0; failed && i < 5; ++ i ) { // call the garbage collector System.gc(); // and try again failed = ! from.renameTo(to); } // if that was not enough and renaming still failed after 5 attempts if ( failed ) { // then try to copy the whole thing copyDir(from, to); boolean res = deleteDir(from); if ( ! res ) { System.err.println("Error deleting dir: " + from); } } } private static void copyDir(File from, File to) throws PackageException { File[] files = from.listFiles(); if ( files == null ) { // null if security restricted throw new PackageException("Failed to list contents of " + from); } if ( to.exists() ) { throw new PackageException("Destination '" + to + "' exists"); } if ( ! to.mkdirs() ) { throw new PackageException("Destination '" + to + "' directory cannot be created"); } if ( ! to.canWrite() ) { throw new PackageException("Destination '" + to + "' cannot be written to"); } for ( File file : files ) { File copied = new File(to, file.getName()); if ( file.isDirectory() ) { copyDir(file, copied); } else { try { byte[] buffer = new byte[4096]; InputStream in = new FileInputStream(file); OutputStream out = new FileOutputStream(copied); int count; while ( (count = in.read(buffer)) > 0 ) { out.write(buffer, 0, count); } } catch ( IOException ex ) { throw new PackageException("Error copying '" + file + "' to '" + copied + "'", ex); } } } } private static boolean deleteDir(File f) { if ( f.isDirectory() ) { boolean res = true; for ( File child : f.listFiles() ) { res = deleteDir(child) && res; } res = f.delete() && res; return res; } else { return f.delete(); } } } /* ------------------------------------------------------------------------ */ /* 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. */ /* ------------------------------------------------------------------------ */