You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2017/04/18 14:40:48 UTC

[3/4] commons-compress git commit: COMPRESS-385, first draft

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 <ta...@mitre.org>
Authored: Fri Apr 14 11:18:19 2017 -0400
Committer: Stefan Bodewig <bo...@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");
+        }
+    }
+
 }