sascha@480: package de.intevation.gnv.utils;
sascha@480: 
sascha@480: import java.io.BufferedInputStream;
sascha@480: import java.io.File;
sascha@480: import java.io.FileInputStream;
sascha@480: import java.io.IOException;
sascha@480: import java.io.InputStream;
sascha@480: import java.io.OutputStream;
sascha@480: 
sascha@480: import java.util.Stack;
sascha@480: 
sascha@480: import java.util.zip.ZipEntry;
sascha@480: import java.util.zip.ZipOutputStream;
sascha@480: 
sascha@480: /**
ingo@806:  * A helper class to provide some methods for working with files and
ingo@806:  * directories.
sascha@807:  *
sascha@780:  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
sascha@780:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
sascha@480:  */
sascha@480: public final class FileUtils
sascha@480: {
sascha@480:     private FileUtils() {
sascha@480:     }
sascha@480: 
ingo@806:     /**
ingo@806:      * Deletes everything in a directory.
ingo@806:      *
ingo@806:      * @param dir The directory.
ingo@806:      */
ingo@775:     public final static void deleteContent(File dir) {
ingo@775:         if (dir == null || !dir.isDirectory()) {
ingo@775:             return;
ingo@775:         }
ingo@775: 
ingo@775:         File[] files = dir.listFiles();
ingo@775:         if (files != null) {
ingo@775:             for (File file: files) {
ingo@775:                 deleteRecursive(file);
ingo@775:             }
ingo@775:         }
ingo@775: 
ingo@775:         return;
ingo@775:     }
ingo@775: 
ingo@806:     /**
ingo@806:      * Delete <i>file</i> and everything in <i>file</i> if it is a directory.
ingo@806:      *
ingo@806:      * @param file The file or directory.
ingo@806:      * @return true, if deletion was successful - otherwise false.
ingo@806:      */
sascha@480:     public final static boolean deleteRecursive(File file) {
sascha@480: 
sascha@480:         if (file == null) {
sascha@480:             return false;
sascha@480:         }
sascha@480: 
sascha@480:         if (file.isDirectory()) {
sascha@480:             File [] files = file.listFiles();
sascha@480:             if (files != null) {
sascha@480:                 for (File sub: files) {
sascha@480:                     if (!deleteRecursive(sub)) {
sascha@480:                         return false;
sascha@480:                     }
sascha@480:                 }
sascha@480:             }
sascha@480:         }
sascha@480: 
sascha@480:         return file.delete();
sascha@480:     }
sascha@480: 
ingo@806:     /**
ingo@806:      * Put the given file or directory into a zip archive.
ingo@806:      *
ingo@806:      * @param file The file or directory.
ingo@806:      * @param outputStream The stream to write the archive to.
ingo@806:      * @throws IOException if an error occured while zip creation or writing to
ingo@806:      * output stream.
ingo@806:      */
sascha@480:     public static void createZipArchive(
sascha@480:         File         file,
sascha@480:         OutputStream outputStream
sascha@480:     )
sascha@480:     throws IOException
sascha@480:     {
sascha@480:         ZipOutputStream out = new ZipOutputStream(outputStream);
sascha@480: 
sascha@480:         if (file.isFile()) {
sascha@480:             copyFileToZip("", file, out);
sascha@480:         }
sascha@480:         else if (file.isDirectory()) {
sascha@480: 
sascha@480:             Stack<PrefixDir> stack = new Stack<PrefixDir>();
sascha@480:             stack.push(new PrefixDir(file.getName() + "/", file));
sascha@480: 
sascha@480:             while (!stack.isEmpty()) {
sascha@480:                 PrefixDir pd = stack.pop();
sascha@480: 
sascha@480:                 ZipEntry dirEntry = new ZipEntry(pd.prefix);
sascha@480:                 out.putNextEntry(dirEntry);
sascha@480:                 out.closeEntry();
sascha@480: 
sascha@480:                 File [] files = pd.dir.listFiles();
sascha@480:                 if (files != null) {
sascha@480:                     for (File sub: files) {
sascha@480:                         if (sub.isDirectory()) {
sascha@480:                             stack.push(new PrefixDir(
sascha@480:                                 pd.prefix + sub.getName() + "/",
sascha@480:                                 sub));
sascha@480:                         }
sascha@480:                         else if (sub.isFile()) {
sascha@480:                             copyFileToZip(pd.prefix, sub, out);
sascha@480:                         }
sascha@480:                     }
sascha@480:                 }
sascha@480:             }
sascha@480:         }
sascha@480: 
sascha@480:         out.finish();
sascha@480:     }
sascha@480: 
ingo@806:     /**
ingo@806:      * A class representing a directory with a prefix.
ingo@806:      */
sascha@480:     private static final class PrefixDir {
sascha@480: 
sascha@480:         String prefix;
sascha@480:         File   dir;
sascha@480: 
sascha@480:         public PrefixDir(String prefix, File dir) {
sascha@480:             this.prefix = prefix;
sascha@480:             this.dir    = dir;
sascha@480:         }
sascha@480: 
sascha@480:     } // class PrefixDir
sascha@480: 
ingo@806:     /**
ingo@806:      * Write a file to zip archive.
ingo@806:      *
ingo@806:      * @param prefix A prefix.
ingo@806:      * @param file The file.
ingo@806:      * @param out The output stream.
ingo@806:      * @throws IOException if an error occured while writing to zip output
ingo@806:      * stream.
ingo@806:      */
sascha@480:     private static void copyFileToZip(
sascha@480:         String          prefix,
sascha@480:         File            file,
sascha@480:         ZipOutputStream out
sascha@480:     )
sascha@480:     throws IOException
sascha@480:     {
sascha@480:         String   entryName = prefix + file.getName();
sascha@480:         ZipEntry entry     = new ZipEntry(entryName);
sascha@480:         out.putNextEntry(entry);
sascha@480:         InputStream in = null;
sascha@480:         try {
sascha@480:             in =
sascha@480:                 new BufferedInputStream(
sascha@480:                 new FileInputStream(file), 20*1024);
sascha@480: 
sascha@480:             byte [] buf = new byte[2048];
sascha@480: 
sascha@480:             int r;
sascha@480:             while ((r = in.read(buf)) > 0) {
sascha@480:                 out.write(buf, 0, r);
sascha@480:             }
sascha@480:         }
sascha@480:         finally {
sascha@480:             if (in != null) {
sascha@480:                 try { in.close(); }
sascha@480:                 catch (IOException ioe) {}
sascha@480:             }
sascha@480:         }
sascha@480:         out.closeEntry();
sascha@480:     }
sascha@480: }
sascha@480: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :