summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/satserver/util/Archive.java
diff options
context:
space:
mode:
authorSimon Rettberg2014-06-03 16:47:36 +0200
committerSimon Rettberg2014-06-03 16:47:36 +0200
commit32dc5354e2916387a2c62eadae0a4568023f1151 (patch)
tree7fd9a0173d6073e86d1d48e545646b1bc8c1a5eb /src/main/java/org/openslx/satserver/util/Archive.java
downloadtmlite-bwlp-32dc5354e2916387a2c62eadae0a4568023f1151.tar.gz
tmlite-bwlp-32dc5354e2916387a2c62eadae0a4568023f1151.tar.xz
tmlite-bwlp-32dc5354e2916387a2c62eadae0a4568023f1151.zip
Initial commit
Diffstat (limited to 'src/main/java/org/openslx/satserver/util/Archive.java')
-rw-r--r--src/main/java/org/openslx/satserver/util/Archive.java217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/satserver/util/Archive.java b/src/main/java/org/openslx/satserver/util/Archive.java
new file mode 100644
index 0000000..dcc1380
--- /dev/null
+++ b/src/main/java/org/openslx/satserver/util/Archive.java
@@ -0,0 +1,217 @@
+package org.openslx.satserver.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+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.nio.charset.StandardCharsets;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.ar.ArArchiveEntry;
+import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
+import org.apache.commons.compress.archivers.dump.DumpArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.compressors.CompressorStreamFactory;
+import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
+import org.apache.commons.io.FileUtils;
+
+public class Archive
+{
+
+ /**
+ * Create input stream from given archive file. The archive format will be guessed
+ * from the firt couple of bytes in the file, which should work for most archive
+ * formats (see apache commons-compress docs for detailed information)
+ *
+ * @param fileName archive to open for reading
+ * @return ArchiveInputStream stream to read archive from
+ * @throws FileNotFoundException
+ * @throws ArchiveException
+ * @throws IllegalArgumentException
+ */
+ public static ArchiveInputStream getArchiveInputStream( String fileName )
+ throws FileNotFoundException, ArchiveException, IllegalArgumentException
+ {
+ // Get an input stream for the archive handler
+ // 1) Get input stream from file
+ InputStream fileStream = new BufferedInputStream( new FileInputStream( fileName ) );
+ // 2) Might be compressed, so try to get a decompressed stream
+ InputStream archiveStream;
+ try {
+ archiveStream = new BufferedInputStream( new CompressorStreamFactory().createCompressorInputStream( fileStream ) );
+ } catch ( Exception e ) {
+ // Might be uncompressed archive, like tar - just try file input stream
+ archiveStream = fileStream;
+ }
+ // 3) Try to create archive input stream - if it succeeds we can read the archive :)
+ return new ArchiveStreamFactory().createArchiveInputStream( archiveStream );
+ }
+
+ /**
+ * Create tar archive with the given name. Optional compression method is
+ * determined by the file extension.
+ *
+ * @param outputFile name of archive to create; can be relative or absolute path
+ * @return {@link TarArchiveOutputStream} to write archive entries to
+ * @throws IOException
+ */
+ @SuppressWarnings( "resource" )
+ public static TarArchiveOutputStream createTarArchive( String outputFile ) throws IOException
+ {
+ OutputStream outputStream = new BufferedOutputStream( new FileOutputStream( outputFile ) );
+ OutputStream compressedOutputStream;
+ if ( outputFile.endsWith( ".tar.gz" ) || outputFile.endsWith( ".tgz" ) ) {
+ compressedOutputStream = new BufferedOutputStream( new GzipCompressorOutputStream( outputStream ) );
+ } else if ( outputFile.endsWith( ".tar.bz2" ) || outputFile.endsWith( ".tbz" ) ) {
+ compressedOutputStream = new BufferedOutputStream( new BZip2CompressorOutputStream( outputStream ) );
+ } else if ( outputFile.endsWith( ".tar.xz" ) || outputFile.endsWith( ".txz" ) ) {
+ compressedOutputStream = new BufferedOutputStream( new XZCompressorOutputStream( outputStream ) );
+ } else if ( outputFile.endsWith( ".tar.Z" ) || outputFile.endsWith( ".tar.z" ) || outputFile.endsWith( ".tz" ) ) {
+ compressedOutputStream = new BufferedOutputStream( new XZCompressorOutputStream( outputStream ) );
+ } else if ( outputFile.endsWith( ".tar.lzma" ) ) {
+ compressedOutputStream = new BufferedOutputStream( new XZCompressorOutputStream( outputStream ) );
+ } else if ( outputFile.endsWith( ".tar" ) ) {
+ compressedOutputStream = outputStream;
+ } else {
+ outputStream.close();
+ return null;
+ }
+ try {
+ return new TarArchiveOutputStream( compressedOutputStream );
+ } catch ( Throwable t ) {
+ compressedOutputStream.close();
+ return null;
+ }
+ }
+
+ public static TarArchiveEntry createTarArchiveEntry( ArchiveEntry inEntry, int defaultUser, int defaultGroup, int defaultDirMode, int defaultFileMode )
+ {
+ if ( inEntry instanceof TarArchiveEntry ) {
+ // Source is tar - easy
+ return (TarArchiveEntry)inEntry;
+ }
+ final TarArchiveEntry outEntry = new TarArchiveEntry( inEntry.getName() );
+ outEntry.setSize( inEntry.getSize() );
+ if ( inEntry instanceof ArArchiveEntry ) {
+ // Source is ar - has most of the stuff tar supports; transform
+ outEntry.setIds( ( (ArArchiveEntry)inEntry ).getUserId(), ( (ArArchiveEntry)inEntry ).getGroupId() );
+ outEntry.setMode( ( (ArArchiveEntry)inEntry ).getMode() );
+ outEntry.setModTime( ( (ArArchiveEntry)inEntry ).getLastModifiedDate() );
+ } else if ( inEntry instanceof DumpArchiveEntry ) {
+ // Source is dump (whatever the fuck that is) - has most of the stuff tar supports; transform
+ outEntry.setIds( ( (DumpArchiveEntry)inEntry ).getUserId(), ( (DumpArchiveEntry)inEntry ).getGroupId() );
+ outEntry.setMode( ( (DumpArchiveEntry)inEntry ).getMode() );
+ outEntry.setModTime( ( (DumpArchiveEntry)inEntry ).getLastModifiedDate() );
+ } else if ( inEntry instanceof CpioArchiveEntry ) {
+ // Source is cpio - has most of the stuff tar supports; transform
+ outEntry.setIds( (int) ( (CpioArchiveEntry)inEntry ).getUID(), (int) ( (CpioArchiveEntry)inEntry ).getGID() );
+ outEntry.setMode( (int) ( ( (CpioArchiveEntry)inEntry ).getMode() & 07777 ) );
+ outEntry.setModTime( ( (CpioArchiveEntry)inEntry ).getLastModifiedDate() );
+ } else if ( inEntry instanceof ZipArchiveEntry ) {
+ // Source is ZIP - might not have unix stuff
+ outEntry.setIds( defaultUser, defaultGroup );
+ int mode = ( (ZipArchiveEntry)inEntry ).getUnixMode();
+ if ( mode != 0 ) { // Has unix permissions
+ outEntry.setMode( mode );
+ } else if ( inEntry.isDirectory() ) { // Use default passed in
+ outEntry.setMode( defaultDirMode );
+ } else { // Use default passed in
+ outEntry.setMode( defaultFileMode );
+ }
+ outEntry.setModTime( ( (ZipArchiveEntry)inEntry ).getLastModifiedDate() );
+ } else {
+ outEntry.setIds( defaultUser, defaultGroup );
+ if ( inEntry.isDirectory() ) {
+ outEntry.setMode( defaultDirMode );
+ } else {
+ outEntry.setMode( defaultFileMode );
+ Calendar cal = GregorianCalendar.getInstance();
+ cal.set( 2014, 4, 2, 13, 57 );
+ outEntry.setModTime( cal.getTime() );
+ }
+ }
+ return outEntry;
+ }
+
+ public static boolean tarAddFile( TarArchiveOutputStream tar, String inArchiveFileName, File sourceFile, int mode )
+ {
+ if ( !sourceFile.exists() || !sourceFile.isFile() )
+ return false;
+ InputStream in;
+ try {
+ in = new FileInputStream( sourceFile );
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ return false;
+ }
+ TarArchiveEntry entry = new TarArchiveEntry( inArchiveFileName );
+ long size = FileUtils.sizeOf( sourceFile );
+ entry.setIds( 0, 0 );
+ entry.setMode( mode );
+ entry.setSize( size );
+ try {
+ tar.putArchiveEntry( entry );
+ Util.streamCopy( in, tar, size );
+ tar.closeArchiveEntry();
+ } catch ( IOException e ) {
+ e.printStackTrace();
+ return false;
+ } finally {
+ Util.multiClose( in );
+ }
+ return true;
+ }
+
+ public static boolean tarCreateFileFromString( TarArchiveOutputStream tar, String fileName, String contents, int mode )
+ {
+ return tarCreateFileFromString( tar, fileName, contents.getBytes( StandardCharsets.UTF_8 ), mode );
+ }
+
+ public static boolean tarCreateFileFromString( TarArchiveOutputStream tar, String fileName, byte[] contents, int mode )
+ {
+ TarArchiveEntry entry = new TarArchiveEntry( fileName );
+ entry.setIds( 0, 0 );
+ entry.setMode( mode );
+ entry.setSize( contents.length );
+ try {
+ tar.putArchiveEntry( entry );
+ tar.write( contents );
+ tar.closeArchiveEntry();
+ } catch ( IOException e ) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean tarCreateSymlink( TarArchiveOutputStream tar, String target, String linkName )
+ {
+ TarArchiveEntry entry = new TarArchiveEntry( linkName, TarArchiveEntry.LF_SYMLINK );
+ entry.setIds( 0, 0 );
+ entry.setMode( 0777 );
+ entry.setLinkName( target );
+ try {
+ tar.putArchiveEntry( entry );
+ tar.closeArchiveEntry();
+ } catch ( IOException e ) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+}