+/* $Id: Copier.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.util.jar.JarFile;
+
+/**
+ * Class to recursively copy a directory.
+ */
+public class Copier {
+
+ String _destination; //target directory
+
+ /**
+ * Copy a file.
+ *
+ * @param from source file
+ * @param to destination file
+ */
+ public void copyFile(File from, File to)
+ throws IOException {
+
+ FileChannel srcChannel = new FileInputStream(from).getChannel();
+ FileChannel dstChannel = new FileOutputStream(to).getChannel();
+ try {
+ dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
+ srcChannel.close();
+ dstChannel.close();
+ }
+ finally {
+ if (srcChannel != null)
+ srcChannel.close();
+
+ if (dstChannel != null)
+ dstChannel.close();
+ }
+ }
+
+ /**
+ * Method which defines what is done for each file found in the
+ * directory tree: It is copied to the corresponding target directory.
+ *
+ * @param filename file to process
+ * @param directory the subdirectory currently processed
+ */
+ protected void processFile(String filename, String directory)
+ throws IOException {
+ File from = new File(filename);
+ File to = new File(_destination + directory + from.getName());
+ copyFile(from, to);
+ //System.out.println("Copied " + from.getPath() + " to "
+ // + to.getPath());
+ }
+
+ /**
+ * Iterate through the given directory tree. For each file found in
+ * the file, the method
+ * {@link #processFile(java.lang.String, java.lang.String)} is called.
+ *
+ * @param path the path of the directory to be browsed
+ * @param currentDir the subdirectory currently explored
+ */
+ protected void browseDirectoryTree(String path, String currentDir)
+ throws IOException {
+ File file = new File(path);
+
+ if (!file.exists()) return;
+ if (!file.isDirectory()) return;
+
+ //loop through files in directory
+ String[] files = file.list();
+
+ for (int k = 0; k < files.length; k++) {
+ File newfile = new File(file.getPath(), files[k]);
+ if (newfile.isFile())
+ processFile(path + System.getProperty("file.separator")
+ + files[k], currentDir);
+ else if (newfile.isDirectory()) {
+ File newDirectory = new File(_destination + currentDir
+ + files[k]);
+ newDirectory.mkdirs();
+ //System.out.println("Created directory "
+ // + newDirectory.getPath());
+ browseDirectoryTree(file.getPath()
+ + System.getProperty("file.separator")
+ + files[k], currentDir + files[k]
+ + System.getProperty("file.separator"));
+ }
+ }
+ }
+
+ /**
+ * Recursively copy a directory.
+ *
+ * @param source source directory
+ * @param destination target directory
+ */
+ public void copy(File source, File destination)
+ throws IOException {
+ try {
+ //treat jar archives differently
+ if (source.toString().contains("dol.jar!")) {
+ String jarName = source.toString();
+ jarName = jarName.substring(jarName.indexOf("file:") + 5, jarName.lastIndexOf("!"));
+ String sourceName = source.toString();
+ sourceName = sourceName.substring(
+ sourceName.lastIndexOf("!") + 2);
+ sourceName = sourceName.replaceAll("\\\\", "/");
+
+ JarFile jar = new JarFile(jarName);
+ JarCopier copier = new JarCopier();
+ copier.copy(jar, sourceName, destination.toString());
+ return;
+ }
+
+ _destination = destination.getPath();
+
+ if (!source.isDirectory())
+ throw (new IOException("Source is not a directory."));
+
+ File destinationDir = new File(_destination);
+ destinationDir.mkdirs();
+
+ browseDirectoryTree(source.getPath(),
+ System.getProperty("file.separator"));
+ }
+ catch (IOException e) {
+ System.out.println("An error has occured while copying \""
+ + source.getPath() + "\" to \""
+ + destination.getPath() + "\":");
+ System.out.println(e.getMessage());
+ throw e;
+ }
+ }
+
+ /**
+ * Test the implementation.
+ *
+ * @param args args[0] specifies the source directory,
+ * args[1] specifies the destination directory
+ */
+ public static void main(String args[])
+ throws Exception {
+ Copier copier = new Copier();
+ if (args.length == 2)
+ copier.copy(new File(args[0]), new File(args[1]));
+ else
+ System.out.println("usage: java Copier "
+ + "sourceDirectory targetDirectory");
+ }
+}