diff options
author | Simon Rettberg | 2014-06-03 16:47:36 +0200 |
---|---|---|
committer | Simon Rettberg | 2014-06-03 16:47:36 +0200 |
commit | 32dc5354e2916387a2c62eadae0a4568023f1151 (patch) | |
tree | 7fd9a0173d6073e86d1d48e545646b1bc8c1a5eb /src/main/java/org/openslx/satserver | |
download | tmlite-bwlp-32dc5354e2916387a2c62eadae0a4568023f1151.tar.gz tmlite-bwlp-32dc5354e2916387a2c62eadae0a4568023f1151.tar.xz tmlite-bwlp-32dc5354e2916387a2c62eadae0a4568023f1151.zip |
Initial commit
Diffstat (limited to 'src/main/java/org/openslx/satserver')
-rw-r--r-- | src/main/java/org/openslx/satserver/util/Archive.java | 217 | ||||
-rw-r--r-- | src/main/java/org/openslx/satserver/util/Constants.java | 8 | ||||
-rw-r--r-- | src/main/java/org/openslx/satserver/util/Util.java | 66 |
3 files changed, 291 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; + } + +} diff --git a/src/main/java/org/openslx/satserver/util/Constants.java b/src/main/java/org/openslx/satserver/util/Constants.java new file mode 100644 index 0000000..b8394f0 --- /dev/null +++ b/src/main/java/org/openslx/satserver/util/Constants.java @@ -0,0 +1,8 @@ +package org.openslx.satserver.util; + +public class Constants +{ + + public static final String BASEDIR = System.getProperty( "user.dir" ); + +} diff --git a/src/main/java/org/openslx/satserver/util/Util.java b/src/main/java/org/openslx/satserver/util/Util.java new file mode 100644 index 0000000..a6d354a --- /dev/null +++ b/src/main/java/org/openslx/satserver/util/Util.java @@ -0,0 +1,66 @@ +package org.openslx.satserver.util; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class Util +{ + + /** + * Check if the given string starts with any of the additionally passed strings. + * Ugly boilerplate. + * + * @param stringToCheck a string we want to check the starting of + * @param compareTo list of strings we compare stringToCheck to + * @return true if stringToCheck starts with any of the strings in compareTo + */ + public static boolean startsWith( String stringToCheck, String... compareTo ) + { + for ( String check : compareTo ) { + if ( stringToCheck.startsWith( check ) ) + return true; + } + return false; + } + + /** + * Close all given Closables. Can handle null references. + * @param streams one or more closables/streams + */ + public static void multiClose( Closeable... streams ) + { + if ( streams == null ) + return; + for ( Closeable stream : streams ) { + if ( stream != null ) { + try { + stream.close(); + } catch ( IOException e ) { + // Ignore - nothing meaningful to do + } + } + } + } + + public static boolean streamCopy( InputStream in, OutputStream out, long bytes ) + { + byte buffer[] = new byte[ 7900 ]; + while ( bytes > 0 ) { + try { + int ret = in.read( buffer, 0, (int) ( bytes > buffer.length ? buffer.length : bytes ) ); + if ( ret == -1 ) + return false; + bytes -= ret; + out.write( buffer, 0, ret ); + } catch ( IOException e ) { + e.printStackTrace(); + return false; + } + } + return true; + } + + +} |