X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=kona%2Fsrc%2Forg%2Fgffs%2Fcompression%2FPackTar.java;fp=kona%2Fsrc%2Forg%2Fgffs%2Fcompression%2FPackTar.java;h=c7a4cddb0fb80801a983580a3c360f04ce43b7e9;hb=7b39f7e279005c8466ef508220a532ce2aa4abf8;hp=0000000000000000000000000000000000000000;hpb=3fbd372b35b15a19fb171d5ae34294ff7b1e6485;p=feisty_meow.git diff --git a/kona/src/org/gffs/compression/PackTar.java b/kona/src/org/gffs/compression/PackTar.java new file mode 100644 index 00000000..c7a4cddb --- /dev/null +++ b/kona/src/org/gffs/compression/PackTar.java @@ -0,0 +1,150 @@ +package org.gffs.compression; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Iterator; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.TrueFileFilter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class PackTar +{ + static private Log _logger = LogFactory.getLog(PackTar.class); + + /** + * returns the "longName" with the "prefix" stripped off the front. if the name doesn't contain the prefix, then an error is thrown. + */ + public static String stripOutPrefix(String prefix, String longName) throws IOException + { + int indy = longName.indexOf(prefix, 0); + if (indy < 0) + throw new IOException("failure to find prefix in string, prefix=" + prefix + " and string=" + longName); + return longName.substring(indy + prefix.length()); + } + + /** + * adds the file pointed at by "source" to the archive in "tarOut" as a compressed file. if "source" is a directory, then the directory is + * recursed and added. the names in the archive will be stripped of the "prefix" string before being added to the archive; for example, if + * the source path "/home/fred/wumpus" and the prefix string is "/home/fred/", then the files in the archive will be named "wumpus/A", + * "wumpus/B", etc. + */ + public static void compressArchive(ArchiveOutputStream tarOut, String prefix, File source) throws IOException + { + _logger.debug("entered into compress archive on source " + source + " prefix " + prefix + " and tarout " + tarOut); + + if (!source.exists()) { + // Don't unpack into an existing directory. + String msg = "Directory " + source.getAbsolutePath() + " doesn't exist yet. Cannot pack."; + _logger.error(msg); + throw new IOException(msg); + } + + // traverse the whole tree of the directory (or just write this directly if it's a file). + if (source.isFile()) { + String choppedName = stripOutPrefix(prefix, source.getPath()); + if (_logger.isDebugEnabled()) + _logger.debug("adding a file to the archive (chopped): " + choppedName); + ArchiveEntry f = tarOut.createArchiveEntry(source, choppedName); + tarOut.putArchiveEntry(f); + IOUtils.copy(new FileInputStream(source), tarOut); + tarOut.closeArchiveEntry(); + } else if (source.isDirectory()) { + // traverse the directory tree at just this height and add everything recursively. + + if (_logger.isDebugEnabled()) + _logger.debug("iterating over a directory to add its contents to the archive: " + source); + + Iterator spidey = FileUtils.iterateFiles(source, new IOFileFilter() + { + @Override + public boolean accept(File arg0) + { + return true; + } + + @Override + public boolean accept(File arg0, String arg1) + { + return true; + } + }, TrueFileFilter.INSTANCE); + + File item = null; + while (spidey.hasNext()) { + item = spidey.next(); + + if (_logger.isTraceEnabled()) + _logger.debug("recursing on item: " + item); + + compressArchive(tarOut, prefix, item); + } + } else { + String msg = "source is not a file or directory although it exists. unknown how to process."; + _logger.error(msg); + throw new IOException(msg); + } + + } + + /** + * returns the same string as presented, but ensures that the last character will be a directory separator (/). + */ + public static String findAppropriatePrefix(String toChop) + { + if (toChop.endsWith("/")) + return toChop; // already ready. + else + return toChop + "/"; // add a slash on the end. + } + + public synchronized static void compressTarGZ(File tarFile, File dest) throws IOException + { + TarArchiveOutputStream tarOut = new TarArchiveOutputStream(new GzipCompressorOutputStream(new FileOutputStream(tarFile))); + compressArchive(tarOut, findAppropriatePrefix(dest.getPath()), dest); + tarOut.close(); + } + + public synchronized static void compressTar(File tarFile, File dest) throws IOException + { + TarArchiveOutputStream tarOut = new TarArchiveOutputStream(new FileOutputStream(tarFile)); + compressArchive(tarOut, findAppropriatePrefix(dest.getPath()), dest); + tarOut.close(); + } + + public synchronized static void compressZip(File zipFile, File dest) throws IOException + { + ZipArchiveOutputStream tarOut = new ZipArchiveOutputStream(new FileOutputStream(zipFile)); + compressArchive(tarOut, findAppropriatePrefix(dest.getPath()), dest); + tarOut.close(); + } + + static public void main(String[] args) throws Throwable + { + // future: could use our cool code above to handle any archive type they pass. + if (args.length != 2) { + System.err.println("USAGE: PackTar {tar.gz file} {source location}"); + System.exit(1); + } + + try { + PackTar.compressTarGZ(new File(args[0]), new File(args[1])); + } catch (Throwable t) { + _logger.error("failed to compress tar file " + args[0] + " from " + args[1]); + System.exit(1); + } + + System.out.println("successfully compressed archive file " + args[0] + " from " + args[1]); + } + +}