COMPRESS-385, first draft
Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/30fce9d4 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/30fce9d4 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/30fce9d4 Branch: refs/heads/master Commit: 30fce9d42c5675e9cae0db0401181f84a73a293b Parents: 0811386 Author: tballison <talli...@mitre.org> Authored: Fri Apr 14 11:18:19 2017 -0400 Committer: Stefan Bodewig <bode...@apache.org> Committed: Tue Apr 18 14:40:25 2017 +0200 ---------------------------------------------------------------------- RELEASE-NOTES.txt | 12 ++ .../compressors/CompressorStreamFactory.java | 110 +++++++++++-------- .../compressors/DetectCompressorTestCase.java | 63 ++++++++++- 3 files changed, 136 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/30fce9d4/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 21c9c4c..b16a4ea 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -5,6 +5,18 @@ compression and archive formats. These include: bzip2, gzip, pack200, lzma, xz, Snappy, traditional Unix Compress, DEFLATE and ar, cpio, jar, tar, zip, dump, 7z, arj. +Release 1.14 +------------ + +Commons Compress 1.13 is the first version to require Java 7 at +runtime. + +Changes in this version include: + +New features: +o detect(InputStream) now available in CompressorStreamFactory + Issue: Compress-385. + Release 1.13 ------------ http://git-wip-us.apache.org/repos/asf/commons-compress/blob/30fce9d4/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java b/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java index 55da36a..c347cca 100644 --- a/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java +++ b/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java @@ -374,20 +374,17 @@ public class CompressorStreamFactory implements CompressorStreamProvider { } /** - * Create an compressor input stream from an input stream, autodetecting the - * compressor type from the first few bytes of the stream. The InputStream - * must support marks, like BufferedInputStream. - * - * @param in - * the input stream - * @return the compressor input stream - * @throws CompressorException - * if the compressor name is not known - * @throws IllegalArgumentException - * if the stream is null or does not support mark - * @since 1.1 + * Try to detect the type of compressor stream. + * + * @param in input stream + * @return type of compressor stream detected + * @throws CompressorException if no compressor stream type was detected + * or if something else went wrong + * @throws IllegalArgumentException if stream is null or does not support mark + * + * @since 1.14 */ - public CompressorInputStream createCompressorInputStream(final InputStream in) throws CompressorException { + public static String detect(final InputStream in) throws CompressorException { if (in == null) { throw new IllegalArgumentException("Stream must not be null."); } @@ -398,52 +395,69 @@ public class CompressorStreamFactory implements CompressorStreamProvider { final byte[] signature = new byte[12]; in.mark(signature.length); + int signatureLength = -1; try { - final int signatureLength = IOUtils.readFully(in, signature); + signatureLength = IOUtils.readFully(in, signature); in.reset(); + } catch (IOException e) { + throw new CompressorException("Failed while reading signature from InputStream.", e); + } - if (BZip2CompressorInputStream.matches(signature, signatureLength)) { - return new BZip2CompressorInputStream(in, decompressConcatenated); - } - - if (GzipCompressorInputStream.matches(signature, signatureLength)) { - return new GzipCompressorInputStream(in, decompressConcatenated); - } + if (BZip2CompressorInputStream.matches(signature, signatureLength)) { + return BZIP2; + } - if (Pack200CompressorInputStream.matches(signature, signatureLength)) { - return new Pack200CompressorInputStream(in); - } + if (GzipCompressorInputStream.matches(signature, signatureLength)) { + return GZIP; + } - if (FramedSnappyCompressorInputStream.matches(signature, signatureLength)) { - return new FramedSnappyCompressorInputStream(in); - } + if (Pack200CompressorInputStream.matches(signature, signatureLength)) { + return PACK200; + } - if (ZCompressorInputStream.matches(signature, signatureLength)) { - return new ZCompressorInputStream(in); - } + if (FramedSnappyCompressorInputStream.matches(signature, signatureLength)) { + return SNAPPY_FRAMED; + } - if (DeflateCompressorInputStream.matches(signature, signatureLength)) { - return new DeflateCompressorInputStream(in); - } + if (ZCompressorInputStream.matches(signature, signatureLength)) { + return Z; + } - if (XZUtils.matches(signature, signatureLength) && XZUtils.isXZCompressionAvailable()) { - return new XZCompressorInputStream(in, decompressConcatenated); - } + if (DeflateCompressorInputStream.matches(signature, signatureLength)) { + return DEFLATE; + } - if (LZMAUtils.matches(signature, signatureLength) && LZMAUtils.isLZMACompressionAvailable()) { - return new LZMACompressorInputStream(in); - } + if (XZUtils.matches(signature, signatureLength)) { + return XZ; + } - if (FramedLZ4CompressorInputStream.matches(signature, signatureLength)) { - return new FramedLZ4CompressorInputStream(in); - } + if (LZMAUtils.matches(signature, signatureLength)) { + return LZMA; + } - } catch (final IOException e) { - throw new CompressorException("Failed to detect Compressor from InputStream.", e); + if (FramedLZ4CompressorInputStream.matches(signature, signatureLength)) { + return LZ4_FRAMED; } throw new CompressorException("No Compressor found for the stream signature."); } + /** + * Create an compressor input stream from an input stream, autodetecting the + * compressor type from the first few bytes of the stream. The InputStream + * must support marks, like BufferedInputStream. + * + * @param in + * the input stream + * @return the compressor input stream + * @throws CompressorException + * if the compressor name is not known + * @throws IllegalArgumentException + * if the stream is null or does not support mark + * @since 1.1 + */ + public CompressorInputStream createCompressorInputStream(final InputStream in) throws CompressorException { + return createCompressorInputStream(detect(in), in); + } /** * Creates a compressor input stream from a compressor name and an input @@ -459,7 +473,7 @@ public class CompressorStreamFactory implements CompressorStreamProvider { * the input stream * @return compressor input stream * @throws CompressorException - * if the compressor name is not known + * if the compressor name is not known or not available * @throws IllegalArgumentException * if the name or input stream is null */ @@ -486,10 +500,16 @@ public class CompressorStreamFactory implements CompressorStreamProvider { } if (XZ.equalsIgnoreCase(name)) { + if (! XZUtils.isXZCompressionAvailable()) { + throw new CompressorException("XZ compression is not available."); + } return new XZCompressorInputStream(in, actualDecompressConcatenated); } if (LZMA.equalsIgnoreCase(name)) { + if (! LZMAUtils.isLZMACompressionAvailable()) { + throw new CompressorException("LZMA compression is not available"); + } return new LZMACompressorInputStream(in); } http://git-wip-us.apache.org/repos/asf/commons-compress/blob/30fce9d4/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java b/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java index 674a2a0..187d931 100644 --- a/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java +++ b/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java @@ -19,16 +19,18 @@ package org.apache.commons.compress.compressors; import static org.apache.commons.compress.AbstractTestCase.getFile; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; -import org.apache.commons.compress.compressors.CompressorException; -import org.apache.commons.compress.compressors.CompressorInputStream; -import org.apache.commons.compress.compressors.CompressorStreamFactory; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.apache.commons.compress.compressors.deflate.DeflateCompressorInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; @@ -118,6 +120,47 @@ public final class DetectCompressorTestCase { } @Test + public void testDetect() throws Exception { + assertEquals(CompressorStreamFactory.BZIP2, detect("bla.txt.bz2")); + assertEquals(CompressorStreamFactory.GZIP, detect("bla.tgz")); + assertEquals(CompressorStreamFactory.PACK200, detect("bla.pack")); + assertEquals(CompressorStreamFactory.XZ, detect("bla.tar.xz")); + assertEquals(CompressorStreamFactory.DEFLATE, detect("bla.tar.deflatez")); + + try { + CompressorStreamFactory.detect(new BufferedInputStream(new ByteArrayInputStream(new byte[0]))); + fail("shouldn't be able to detect empty stream"); + } catch (CompressorException e) { + assertTrue(e.getMessage().contains("No Compressor found")); + } + + try { + CompressorStreamFactory.detect(null); + fail("shouldn't be able to detect null stream"); + } catch (IllegalArgumentException e) { + assertEquals("Stream must not be null.", e.getMessage()); + } + + try { + CompressorStreamFactory.detect(new BufferedInputStream(new BadInputStream())); + fail("Expected IOException"); + } catch (CompressorException e) { + assertEquals("Failed while reading signature from InputStream.", e.getMessage()); + } + + + } + + private String detect(String testFileName) throws IOException, CompressorException { + String name = null; + try (InputStream is = new BufferedInputStream( + new FileInputStream(getFile(testFileName)))) { + name = CompressorStreamFactory.detect(is); + } + return name; + } + + @Test public void testOverride() { CompressorStreamFactory fac = new CompressorStreamFactory(); assertFalse(fac.getDecompressConcatenated()); @@ -174,4 +217,16 @@ public final class DetectCompressorTestCase { getFile(resource)))); } + private static class BadInputStream extends InputStream { + @Override + public int read() throws IOException { + throw new IOException("Bad"); + } + + @Override + public int read(byte[] bytes, int offset, int length) throws IOException { + throw new IOException("Bad"); + } + } + }