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 2011/09/04 05:42:27 UTC
svn commit: r1164958 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/compressors/
main/java/org/apache/commons/compress/compressors/pack200/
test/java/org/apache/commons/compress/compressors/ test/resources/
Author: bodewig
Date: Sun Sep 4 03:42:27 2011
New Revision: 1164958
URL: http://svn.apache.org/viewvc?rev=1164958&view=rev
Log:
Pack200 support. COMPRESS-142
Added:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/InMemoryStreamSwitcher.java (with props)
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorInputStream.java (with props)
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorOutputStream.java (with props)
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamMode.java (with props)
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamSwitcher.java (with props)
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/TempFileStreamSwitcher.java (with props)
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/package.html (with props)
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/compressors/Pack200TestCase.java (with props)
commons/proper/compress/trunk/src/test/resources/bla.pack (with props)
Modified:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java?rev=1164958&r1=1164957&r2=1164958&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java Sun Sep 4 03:42:27 2011
@@ -26,6 +26,8 @@ import org.apache.commons.compress.compr
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream;
+import org.apache.commons.compress.compressors.pack200.Pack200CompressorOutputStream;
/**
* <p>Factory to create Compressor[In|Out]putStreams from names. To add other
@@ -40,7 +42,7 @@ import org.apache.commons.compress.compr
* new CompressorStreamFactory().createCompressorOutputStream(CompressorStreamFactory.BZIP2, out);
* IOUtils.copy(new FileInputStream(input), cos);
* cos.close();
- * </pre>
+ * </pre>
*
* Example (Compressing a file):
* <pre>
@@ -65,6 +67,11 @@ public class CompressorStreamFactory {
* @since Commons Compress 1.1
*/
public static final String GZIP = "gz";
+ /**
+ * Constant used to identify the PACK200 compression algorithm.
+ * @since Commons Compress 1.3
+ */
+ public static final String PACK200 = "pack200";
/**
* Create an compressor input stream from an input stream, autodetecting
@@ -92,26 +99,30 @@ public class CompressorStreamFactory {
try {
int signatureLength = in.read(signature);
in.reset();
-
+
if (BZip2CompressorInputStream.matches(signature, signatureLength)) {
return new BZip2CompressorInputStream(in);
}
-
+
if (GzipCompressorInputStream.matches(signature, signatureLength)) {
return new GzipCompressorInputStream(in);
}
+ if (Pack200CompressorInputStream.matches(signature, signatureLength)) {
+ return new Pack200CompressorInputStream(in);
+ }
+
} catch (IOException e) {
throw new CompressorException("Failed to detect Compressor from InputStream.", e);
}
throw new CompressorException("No Compressor found for the stream signature.");
}
-
+
/**
* Create a compressor input stream from a compressor name and an input stream.
*
- * @param name of the compressor, i.e. "gz" or "bzip2"
+ * @param name of the compressor, i.e. "gz", "bzip2" or "pack200"
* @param in the input stream
* @return compressor input stream
* @throws CompressorException if the compressor name is not known
@@ -125,15 +136,19 @@ public class CompressorStreamFactory {
}
try {
-
+
if (GZIP.equalsIgnoreCase(name)) {
return new GzipCompressorInputStream(in);
}
-
+
if (BZIP2.equalsIgnoreCase(name)) {
return new BZip2CompressorInputStream(in);
}
-
+
+ if (PACK200.equalsIgnoreCase(name)) {
+ return new Pack200CompressorInputStream(in);
+ }
+
} catch (IOException e) {
throw new CompressorException(
"Could not create CompressorInputStream.", e);
@@ -144,7 +159,7 @@ public class CompressorStreamFactory {
/**
* Create an compressor output stream from an compressor name and an input stream.
*
- * @param name the compressor name, i.e. "gz" or "bzip2"
+ * @param name the compressor name, i.e. "gz", "bzip2" or "pack200"
* @param out the output stream
* @return the compressor output stream
* @throws CompressorException if the archiver name is not known
@@ -163,11 +178,15 @@ public class CompressorStreamFactory {
if (GZIP.equalsIgnoreCase(name)) {
return new GzipCompressorOutputStream(out);
}
-
+
if (BZIP2.equalsIgnoreCase(name)) {
return new BZip2CompressorOutputStream(out);
}
-
+
+ if (PACK200.equalsIgnoreCase(name)) {
+ return new Pack200CompressorOutputStream(out);
+ }
+
} catch (IOException e) {
throw new CompressorException(
"Could not create CompressorOutputStream", e);
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/InMemoryStreamSwitcher.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/InMemoryStreamSwitcher.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/InMemoryStreamSwitcher.java (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/InMemoryStreamSwitcher.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.pack200;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * StreamSwitcher that caches all data written to the output side in
+ * memory.
+ * @since Apache Commons Compress 1.3
+ */
+class InMemoryStreamSwitcher extends StreamSwitcher {
+ InMemoryStreamSwitcher() {
+ super(new ByteArrayOutputStream());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ InputStream getInputView() throws IOException {
+ return new ByteArrayInputStream(((ByteArrayOutputStream) out)
+ .toByteArray());
+ }
+}
\ No newline at end of file
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/InMemoryStreamSwitcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorInputStream.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorInputStream.java (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorInputStream.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.pack200;
+
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Pack200;
+
+import org.apache.commons.compress.compressors.CompressorInputStream;
+
+/**
+ * An input stream that decompresses from the Pack200 format to be read
+ * as any other stream.
+ *
+ * @NotThreadSafe
+ * @since Apache Commons Compress 1.3
+ */
+public class Pack200CompressorInputStream extends CompressorInputStream {
+ private final InputStream originalInput;
+ private final StreamSwitcher streamSwitcher;
+
+ /**
+ * Decompresses the given stream, caching the decompressed data in
+ * memory.
+ *
+ * <p>When reading from a file the File-arg constructor may
+ * provide better performance.</p>
+ */
+ public Pack200CompressorInputStream(final InputStream in)
+ throws IOException {
+ this(in, StreamMode.IN_MEMORY);
+ }
+
+ /**
+ * Decompresses the given stream using the given strategy to cache
+ * the results.
+ *
+ * <p>When reading from a file the File-arg constructor may
+ * provide better performance.</p>
+ */
+ public Pack200CompressorInputStream(final InputStream in,
+ final StreamMode mode)
+ throws IOException {
+ this(in, null, mode, null);
+ }
+
+ /**
+ * Decompresses the given stream, caching the decompressed data in
+ * memory and using the given properties.
+ *
+ * <p>When reading from a file the File-arg constructor may
+ * provide better performance.</p>
+ */
+ public Pack200CompressorInputStream(final InputStream in,
+ final Map<String, String> props)
+ throws IOException {
+ this(in, StreamMode.IN_MEMORY, props);
+ }
+
+ /**
+ * Decompresses the given stream using the given strategy to cache
+ * the results and the given properties.
+ *
+ * <p>When reading from a file the File-arg constructor may
+ * provide better performance.</p>
+ */
+ public Pack200CompressorInputStream(final InputStream in,
+ final StreamMode mode,
+ final Map<String, String> props)
+ throws IOException {
+ this(in, null, mode, props);
+ }
+
+ /**
+ * Decompresses the given file, caching the decompressed data in
+ * memory.
+ */
+ public Pack200CompressorInputStream(final File f) throws IOException {
+ this(f, StreamMode.IN_MEMORY);
+ }
+
+ /**
+ * Decompresses the given file using the given strategy to cache
+ * the results.
+ */
+ public Pack200CompressorInputStream(final File f, final StreamMode mode)
+ throws IOException {
+ this(null, f, mode, null);
+ }
+
+ /**
+ * Decompresses the given file, caching the decompressed data in
+ * memory and using the given properties.
+ */
+ public Pack200CompressorInputStream(final File f,
+ final Map<String, String> props)
+ throws IOException {
+ this(f, StreamMode.IN_MEMORY, props);
+ }
+
+ /**
+ * Decompresses the given file using the given strategy to cache
+ * the results and the given properties.
+ */
+ public Pack200CompressorInputStream(final File f, final StreamMode mode,
+ final Map<String, String> props)
+ throws IOException {
+ this(null, f, mode, props);
+ }
+
+ private Pack200CompressorInputStream(final InputStream in, final File f,
+ final StreamMode mode,
+ final Map<String, String> props)
+ throws IOException {
+ originalInput = in;
+ streamSwitcher = mode.newStreamSwitcher();
+ JarOutputStream jarOut = new JarOutputStream(streamSwitcher);
+ Pack200.Unpacker u = Pack200.newUnpacker();
+ if (props != null) {
+ u.properties().putAll(props);
+ }
+ if (f == null) {
+ u.unpack(new FilterInputStream(in) {
+ @Override
+ public void close() {
+ // unpack would close this stream but we
+ // want to give the user code more control
+ }
+ },
+ jarOut);
+ } else {
+ u.unpack(f, jarOut);
+ }
+ jarOut.close();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int read() throws IOException {
+ return streamSwitcher.getInput().read();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int read(byte[] b) throws IOException {
+ return streamSwitcher.getInput().read(b);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int read(byte[] b, int off, int count) throws IOException {
+ return streamSwitcher.getInput().read(b, off, count);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int available() throws IOException {
+ return streamSwitcher.getInput().available();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean markSupported() {
+ try {
+ return streamSwitcher.getInput().markSupported();
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void mark(int limit) {
+ try {
+ streamSwitcher.getInput().mark(limit);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void reset() throws IOException {
+ streamSwitcher.getInput().reset();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public long skip(long count) throws IOException {
+ return streamSwitcher.getInput().skip(count);
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ streamSwitcher.stop();
+ } finally {
+ if (originalInput != null) {
+ originalInput.close();
+ }
+ }
+ }
+
+ private static final byte[] CAFE_DOOD = new byte[] {
+ (byte) 0xCA, (byte) 0xFE, (byte) 0xD0, (byte) 0x0D
+ };
+
+ /**
+ * Checks if the signature matches what is expected for a pack200
+ * file (0xCAFED00D).
+ *
+ * @param signature
+ * the bytes to check
+ * @param length
+ * the number of bytes to check
+ * @return true, if this stream is a pack200 compressed stream,
+ * false otherwise
+ */
+ public static boolean matches(byte[] signature, int length) {
+ if (length < 4) {
+ return false;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if (signature[i] != CAFE_DOOD[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorInputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorOutputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorOutputStream.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorOutputStream.java (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorOutputStream.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.pack200;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.jar.JarInputStream;
+import java.util.jar.Pack200;
+
+import org.apache.commons.compress.compressors.CompressorOutputStream;
+
+/**
+ * An output stream that compresses using the Pack200 format.
+ *
+ * @NotThreadSafe
+ * @since Apache Commons Compress 1.3
+ */
+public class Pack200CompressorOutputStream extends CompressorOutputStream {
+ private boolean finished = false;
+ private final OutputStream originalOutput;
+ private final StreamSwitcher streamSwitcher;
+ private final Map<String, String> properties;
+
+ /**
+ * Compresses the given stream, caching the compressed data in
+ * memory.
+ */
+ public Pack200CompressorOutputStream(final OutputStream out)
+ throws IOException {
+ this(out, StreamMode.IN_MEMORY);
+ }
+
+ /**
+ * Compresses the given stream using the given strategy to cache
+ * the results.
+ */
+ public Pack200CompressorOutputStream(final OutputStream out,
+ final StreamMode mode)
+ throws IOException {
+ this(out, mode, null);
+ }
+
+ /**
+ * Compresses the given stream, caching the compressed data in
+ * memory and using the given properties.
+ */
+ public Pack200CompressorOutputStream(final OutputStream out,
+ final Map<String, String> props)
+ throws IOException {
+ this(out, StreamMode.IN_MEMORY, props);
+ }
+
+ /**
+ * Compresses the given stream using the given strategy to cache
+ * the results and the given properties.
+ */
+ public Pack200CompressorOutputStream(final OutputStream out,
+ final StreamMode mode,
+ final Map<String, String> props)
+ throws IOException {
+ originalOutput = out;
+ streamSwitcher = mode.newStreamSwitcher();
+ properties = props;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void write(int b) throws IOException {
+ streamSwitcher.write(b);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b) throws IOException {
+ streamSwitcher.write(b);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b, int from, int length) throws IOException {
+ streamSwitcher.write(b, from, length);
+ }
+
+ @Override
+ public void close() throws IOException {
+ finish();
+ try {
+ streamSwitcher.stop();
+ } finally {
+ originalOutput.close();
+ }
+ }
+
+ public void finish() throws IOException {
+ if (!finished) {
+ finished = true;
+ Pack200.Packer p = Pack200.newPacker();
+ if (properties != null) {
+ p.properties().putAll(properties);
+ }
+ p.pack(new JarInputStream(streamSwitcher.getInput()),
+ originalOutput);
+ }
+ }
+}
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/Pack200CompressorOutputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamMode.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamMode.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamMode.java (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamMode.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.pack200;
+
+import java.io.IOException;
+
+/**
+ * The different modes the Pack200 streams can use to wrap input and
+ * output.
+ * @since Apache Commons Compress 1.3
+ */
+public enum StreamMode {
+ /** Cache output in memory */
+ IN_MEMORY() {
+ StreamSwitcher newStreamSwitcher() {
+ return new InMemoryStreamSwitcher();
+ }
+ },
+ /** Cache output in a temporary file */
+ TEMP_FILE() {
+ StreamSwitcher newStreamSwitcher() throws IOException {
+ return new TempFileStreamSwitcher();
+ }
+ };
+
+ abstract StreamSwitcher newStreamSwitcher() throws IOException;
+}
\ No newline at end of file
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamMode.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamSwitcher.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamSwitcher.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamSwitcher.java (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamSwitcher.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.pack200;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Provides an InputStream to read all data written to this
+ * OutputStream.
+ *
+ * @ThreadSafe
+ * @since Apache Commons Compress 1.3
+ */
+abstract class StreamSwitcher extends FilterOutputStream {
+ private InputStream input;
+ private final Object INPUT_LOCK = new Object();
+
+ protected StreamSwitcher(OutputStream out) {
+ super(out);
+ }
+
+ protected StreamSwitcher() {
+ this(null);
+ }
+
+ /**
+ * Provides the input view.
+ */
+ InputStream getInput() throws IOException {
+ synchronized (INPUT_LOCK) {
+ if (input == null) {
+ input = getInputView();
+ }
+ }
+ return input;
+ }
+
+ /**
+ * Creates the input view.
+ */
+ abstract InputStream getInputView() throws IOException;
+
+ /**
+ * Closes input and output and releases all associated resources.
+ */
+ void stop() throws IOException {
+ close();
+ synchronized (INPUT_LOCK) {
+ if (input != null) {
+ input.close();
+ input = null;
+ }
+ }
+ }
+}
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/StreamSwitcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/TempFileStreamSwitcher.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/TempFileStreamSwitcher.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/TempFileStreamSwitcher.java (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/TempFileStreamSwitcher.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.compress.compressors.pack200;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * StreamSwitcher that caches all data written to the output side in
+ * a temporary file.
+ * @since Apache Commons Compress 1.3
+ */
+class TempFileStreamSwitcher extends StreamSwitcher {
+ private final File f;
+
+ TempFileStreamSwitcher() throws IOException {
+ f = File.createTempFile("commons-compress", "packtemp");
+ f.deleteOnExit();
+ out = new FileOutputStream(f);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ InputStream getInputView() throws IOException {
+ out.close();
+ return new FileInputStream(f) {
+ @Override
+ public void close() throws IOException {
+ super.close();
+ f.delete();
+ }
+ };
+ }
+}
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/TempFileStreamSwitcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/package.html
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/package.html?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/package.html (added)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/package.html Sun Sep 4 03:42:27 2011
@@ -0,0 +1,65 @@
+<html>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+ <body>
+ <p>Provides stream classes for compressing and decompressing
+ streams using the Pack200 algorithm used to compress Java
+ archives.</p>
+
+ <p>The streams of this package only work on JAR archives, i.e. a
+ {@link
+ org.apache.commons.compress.compressors.pack200.Pack200CompressorOutputStream
+ Pack200CompressorOutputStream} expects to be wrapped around a
+ stream that a valid JAR archive will be written to and a {@link
+ org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream
+ Pack200CompressorInputStream} provides a stream to read from a
+ JAR archive.</p>
+
+ <p>JAR archives compressed with Pack200 will in general be
+ different from the original archive when decompressed again.
+ For details see
+ the <a href="http://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.html">API
+ documentation of Pack200</a>.</p>
+
+ <p>The streams of this package work on non-deflated streams,
+ i.e. archives like those created with the <code>--no-gzip</code>
+ option of the JDK's <code>pack200</code> command line tool. If
+ you want to work on deflated streams you must use an additional
+ stream layer - for example by using Apache Commons Compress'
+ gzip package.</p>
+
+ <p>The Pack200 API provided by the Java class library doesn't lend
+ itself to real stream
+ processing. <code>Pack200CompressorInputStream</code> will
+ uncompress its input immediately and then provide
+ an <code>InputStream</code> to a cached result.
+ Likewise <code>Pack200CompressorOutputStream</code> will not
+ write anything to the given OutputStream
+ until <code>finish</code> or <code>close</code> is called - at
+ which point the cached output written so far gets
+ compressed.</p>
+
+ <p>Two different caching modes are available - "in memory", which
+ is the default, and "temporary file". By default data is cached
+ in memory but you should switch to the temporary file option if
+ your archives are really big.</p>
+
+ <p>
+ </body>
+</html>
Propchange: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/compressors/pack200/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/compressors/Pack200TestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/compressors/Pack200TestCase.java?rev=1164958&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/compressors/Pack200TestCase.java (added)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/compressors/Pack200TestCase.java Sun Sep 4 03:42:27 2011
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.compress.compressors;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.compress.AbstractTestCase;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream;
+import org.apache.commons.compress.compressors.pack200.Pack200CompressorOutputStream;
+import org.apache.commons.compress.compressors.pack200.StreamMode;
+import org.apache.commons.compress.utils.IOUtils;
+
+public final class Pack200TestCase extends AbstractTestCase {
+
+ public void testJarUnarchiveAllInMemory() throws Exception {
+ jarUnarchiveAll(false, StreamMode.IN_MEMORY);
+ }
+
+ public void testJarUnarchiveAllFileArgInMemory() throws Exception {
+ jarUnarchiveAll(true, StreamMode.IN_MEMORY);
+ }
+
+ public void testJarUnarchiveAllTempFile() throws Exception {
+ jarUnarchiveAll(false, StreamMode.TEMP_FILE);
+ }
+
+ public void testJarUnarchiveAllFileTempFile() throws Exception {
+ jarUnarchiveAll(true, StreamMode.TEMP_FILE);
+ }
+
+ private void jarUnarchiveAll(boolean useFile, StreamMode mode)
+ throws Exception {
+ final File input = getFile("bla.pack");
+ final InputStream is = useFile
+ ? new Pack200CompressorInputStream(input, mode)
+ : new Pack200CompressorInputStream(new FileInputStream(input),
+ mode);
+ try {
+ final ArchiveInputStream in = new ArchiveStreamFactory()
+ .createArchiveInputStream("jar", is);
+
+ ArchiveEntry entry = in.getNextEntry();
+ while (entry != null) {
+ File archiveEntry = new File(dir, entry.getName());
+ archiveEntry.getParentFile().mkdirs();
+ if (entry.isDirectory()) {
+ archiveEntry.mkdir();
+ entry = in.getNextEntry();
+ continue;
+ }
+ OutputStream out = new FileOutputStream(archiveEntry);
+ IOUtils.copy(in, out);
+ out.close();
+ entry = in.getNextEntry();
+ }
+
+ in.close();
+ } finally {
+ is.close();
+ }
+ }
+
+ public void testJarArchiveCreationInMemory() throws Exception {
+ jarArchiveCreation(StreamMode.IN_MEMORY);
+ }
+
+ public void testJarArchiveCreationTempFile() throws Exception {
+ jarArchiveCreation(StreamMode.TEMP_FILE);
+ }
+
+ private void jarArchiveCreation(StreamMode mode) throws Exception {
+ final File output = new File(dir, "bla.pack");
+
+ final File file1 = getFile("test1.xml");
+ final File file2 = getFile("test2.xml");
+
+ final OutputStream out =
+ new Pack200CompressorOutputStream(new FileOutputStream(output),
+ mode);
+ try {
+ final ArchiveOutputStream os = new ArchiveStreamFactory()
+ .createArchiveOutputStream("jar", out);
+
+ os.putArchiveEntry(new ZipArchiveEntry("testdata/test1.xml"));
+ IOUtils.copy(new FileInputStream(file1), os);
+ os.closeArchiveEntry();
+
+ os.putArchiveEntry(new ZipArchiveEntry("testdata/test2.xml"));
+ IOUtils.copy(new FileInputStream(file2), os);
+ os.closeArchiveEntry();
+
+ os.close();
+ } finally {
+ out.close();
+ }
+
+ final InputStream is = new Pack200CompressorInputStream(output);
+ try {
+ final ArchiveInputStream in = new ArchiveStreamFactory()
+ .createArchiveInputStream("jar", is);
+ List<String> files = new ArrayList<String>();
+ files.add("testdata/test1.xml");
+ files.add("testdata/test2.xml");
+ checkArchiveContent(in, files);
+ in.close();
+ } finally {
+ is.close();
+ }
+ }
+
+ public void testGoodSignature() throws Exception {
+ final InputStream is = new FileInputStream(getFile("bla.pack"));
+ try {
+ byte[] sig = new byte[4];
+ is.read(sig);
+ assertTrue(Pack200CompressorInputStream.matches(sig, 4));
+ } finally {
+ is.close();
+ }
+ }
+
+ public void testBadSignature() throws Exception {
+ final InputStream is = new FileInputStream(getFile("bla.jar"));
+ try {
+ byte[] sig = new byte[4];
+ is.read(sig);
+ assertFalse(Pack200CompressorInputStream.matches(sig, 4));
+ } finally {
+ is.close();
+ }
+ }
+}
Propchange: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/compressors/Pack200TestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/compress/trunk/src/test/resources/bla.pack
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/resources/bla.pack?rev=1164958&view=auto
==============================================================================
Binary file - no diff available.
Propchange: commons/proper/compress/trunk/src/test/resources/bla.pack
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream