/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.eclipse.ui.target;
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.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
//mash-up of commons io helpers
public class FileHelper {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
public static void copy(File[] files, File destination) throws IOException {
for (int i = 0; i < files.length; i++) {
File file = files[i];
copy(file, destination);
}
}
public static void copy(File file, File destination) throws IOException {
if (file.isDirectory()) {
if (destination.isDirectory())
copyDirectoryToDirectory(file, destination);
else
copyDirectory(file, destination);
} else {
if (destination.isDirectory())
copyFileToDirectory(file, destination);
else
copyFile(file, destination);
}
}
public static void copyFileToDirectory(File srcFile, File destDir) throws IOException {
copyFileToDirectory(srcFile, destDir, true);
}
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");
}
copyFile(srcFile, new File(destDir, srcFile.getName()), preserveFileDate);
}
public static void copyFile(File srcFile, File destFile) throws IOException {
copyFile(srcFile, destFile, true);
}
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");
}
if (destFile.getParentFile() != null && destFile.getParentFile().exists() == false) {
if (destFile.getParentFile().mkdirs() == false) {
throw new IOException("Destination '" + destFile + "' directory cannot be created");
}
}
if (destFile.exists() && destFile.canWrite() == false) {
throw new IOException("Destination '" + destFile + "' exists but is read-only");
}
doCopyFile(srcFile, destFile, preserveFileDate);
}
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 input = new FileInputStream(srcFile);
try {
FileOutputStream output = new FileOutputStream(destFile);
try {
copy(input, output);
} finally {
closeQuietly(output);
}
} finally {
closeQuietly(input);
}
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 copyDirectoryToDirectory(File srcDir, File destDir) throws IOException {
copyDirectory(srcDir, new File(destDir, srcDir.getName()), true);
}
public static void copyDirectory(File srcDir, File destDir) throws IOException {
copyDirectory(srcDir, destDir, 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 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(srcFiles.length);
for (int i = 0; i < srcFiles.length; i++) {
File copiedFile = new File(destDir, srcFiles[i].getName());
exclusionList.add(copiedFile.getCanonicalPath());
}
}
}
doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
}
private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter,
boolean preserveFileDate, List exclusionList) throws IOException {
if (destDir.exists()) {
if (destDir.isDirectory() == false) {
throw new IOException("Destination '" + destDir + "' exists but is not a directory");
}
} else {
if (destDir.mkdirs() == false) {
throw new IOException("Destination '" + destDir + "' directory cannot be created");
}
if (preserveFileDate) {
destDir.setLastModified(srcDir.lastModified());
}
}
if (destDir.canWrite() == false) {
throw new IOException("Destination '" + destDir + "' cannot be written to");
}
// recurse
File[] files = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
if (files == null) { // null if security restricted
throw new IOException("Failed to list contents of " + srcDir);
}
for (int i = 0; i < files.length; i++) {
File copiedFile = new File(destDir, files[i].getName());
if (exclusionList == null || !exclusionList.contains(files[i].getCanonicalPath())) {
if (files[i].isDirectory()) {
doCopyDirectory(files[i], copiedFile, filter, preserveFileDate, exclusionList);
} else {
doCopyFile(files[i], copiedFile, preserveFileDate);
}
}
}
}
public static int copy(InputStream input, OutputStream output) throws IOException {
long count = copyLarge(input, output);
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
public static void closeQuietly(InputStream input) {
try {
if (input != null) {
input.close();
}
} catch (IOException ioe) {
// ignore
}
}
public static void closeQuietly(OutputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
// ignore
}
}
}