blob: 1dfee9828967dcb71c5fb1c3943282da9da15c50 [file] [log] [blame]
Torsten Curdt444238f2008-07-10 21:36:43 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Torsten Curdtca165392008-07-10 10:17:44 +000019package org.apache.commons.compress.compressors;
20
Torsten Curdt6a703232009-01-07 13:16:01 +000021import java.io.IOException;
Torsten Curdtca165392008-07-10 10:17:44 +000022import java.io.InputStream;
23import java.io.OutputStream;
Torsten Curdtca165392008-07-10 10:17:44 +000024
Torsten Curdtca165392008-07-10 10:17:44 +000025import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
26import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
27import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
28import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
29
Torsten Curdt6a703232009-01-07 13:16:01 +000030/**
Christian Grobmeier0ef0fc42009-04-14 04:56:41 +000031 * <p>Factory to create Compressor[In|Out]putStreams from names. To add other
Stefan Bodewigc4a65f02009-03-13 05:23:22 +000032 * implementations you should extend CompressorStreamFactory and override the
Christian Grobmeier0ef0fc42009-04-14 04:56:41 +000033 * appropriate methods (and call their implementation from super of course).</p>
Torsten Curdt6a703232009-01-07 13:16:01 +000034 *
Christian Grobmeier0ef0fc42009-04-14 04:56:41 +000035 * Example (Compressing a file):
36 *
37 * <pre>
38 * final OutputStream out = new FileOutputStream(output);
39 * CompressorOutputStream cos =
40 * new CompressorStreamFactory().createCompressorOutputStream("bzip2", out);
41 * IOUtils.copy(new FileInputStream(input), cos);
42 * cos.close();
43 * </pre>
44 *
45 * Example (Compressing a file):
46 * <pre>
47 * final InputStream is = new FileInputStream(input);
48 * CompressorInputStream in =
49 * new CompressorStreamFactory().createCompressorInputStream("bzip2", is);
50 * IOUtils.copy(in, new FileOutputStream(output));
51 * in.close();
52 * </pre>
53 *
Sebastian Bazley44dbd932009-03-28 00:03:11 +000054 * @Immutable
Torsten Curdt6a703232009-01-07 13:16:01 +000055 */
Torsten Curdtca165392008-07-10 10:17:44 +000056public class CompressorStreamFactory {
Torsten Curdt6a703232009-01-07 13:16:01 +000057
Stefan Bodewigbed564b2010-02-18 12:34:02 +000058 private static final String BZ = "bzip2";
59 private static final String GZ = "gz";
Torsten Curdt2e3acfa2010-02-12 14:14:31 +000060
61 /**
62 * Create an compressor input stream from an input stream, autodetecting
63 * the compressor type from the first few bytes of the stream. The InputStream
64 * must support marks, like BufferedInputStream.
65 *
66 * @param in the input stream
67 * @return the compressor input stream
68 * @throws CompressorInputStream if the compressor name is not known
69 * @throws IllegalArgumentException if the stream is null or does not support mark
70 */
71 public CompressorInputStream createCompressorInputStream(final InputStream in)
72 throws CompressorException {
73 if (in == null) {
74 throw new IllegalArgumentException("Stream must not be null.");
75 }
76
77 if (!in.markSupported()) {
78 throw new IllegalArgumentException("Mark is not supported.");
79 }
80
81 final byte[] signature = new byte[12];
82 in.mark(signature.length);
83 try {
84 int signatureLength = in.read(signature);
85 in.reset();
86
87 if (BZip2CompressorInputStream.matches(signature, signatureLength)) {
88 return new BZip2CompressorInputStream(in);
89 }
90
91 if (GzipCompressorInputStream.matches(signature, signatureLength)) {
92 return new GzipCompressorInputStream(in);
93 }
94
95 } catch (IOException e) {
96 throw new CompressorException("Failed to detect Compressor from InputStream.", e);
97 }
98
99 throw new CompressorException("No Compressor found for the stream signature.");
100 }
101
Sebastian Bazleydc281aa2009-03-16 14:42:56 +0000102 /**
103 * Create a compressor input stream from a compressor name and an input stream.
104 *
105 * @param name of the compressor, i.e. "gz" or "bzip2"
106 * @param in the input stream
107 * @return compressor input stream
108 * @throws CompressorException if the compressor name is not known
109 * @throws IllegalArgumentException if the name or input stream is null
110 */
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000111 public CompressorInputStream createCompressorInputStream(final String name,
112 final InputStream in) throws CompressorException {
113 if (name == null || in == null) {
114 throw new IllegalArgumentException(
115 "Compressor name and stream must not be null.");
116 }
Torsten Curdt6a703232009-01-07 13:16:01 +0000117
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000118 try {
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000119
Stefan Bodewigbed564b2010-02-18 12:34:02 +0000120 if (GZ.equalsIgnoreCase(name)) {
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000121 return new GzipCompressorInputStream(in);
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000122 }
123
Stefan Bodewigbed564b2010-02-18 12:34:02 +0000124 if (BZ.equalsIgnoreCase(name)) {
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000125 return new BZip2CompressorInputStream(in);
126 }
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000127
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000128 } catch (IOException e) {
129 throw new CompressorException(
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000130 "Could not create CompressorInputStream.", e);
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000131 }
Christian Grobmeierc75d2d32009-04-14 04:46:49 +0000132 throw new CompressorException("Compressor: " + name + " not found.");
Torsten Curdtca165392008-07-10 10:17:44 +0000133 }
134
Christian Grobmeierc75d2d32009-04-14 04:46:49 +0000135 /**
136 * Create an compressor output stream from an compressor name and an input stream.
137 *
138 * @param name the compressor name, i.e. "gz" or "bzip2"
139 * @param out the output stream
140 * @return the compressor output stream
141 * @throws CompressorException if the archiver name is not known
142 * @throws IllegalArgumentException if the archiver name or stream is null
143 */
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000144 public CompressorOutputStream createCompressorOutputStream(
145 final String name, final OutputStream out)
146 throws CompressorException {
147 if (name == null || out == null) {
148 throw new IllegalArgumentException(
149 "Compressor name and stream must not be null.");
150 }
Torsten Curdt6a703232009-01-07 13:16:01 +0000151
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000152 try {
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000153
Stefan Bodewigbed564b2010-02-18 12:34:02 +0000154 if (GZ.equalsIgnoreCase(name)) {
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000155 return new GzipCompressorOutputStream(out);
Stefan Bodewigae0f9842010-02-12 15:22:02 +0000156 }
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000157
Stefan Bodewigbed564b2010-02-18 12:34:02 +0000158 if (BZ.equalsIgnoreCase(name)) {
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000159 return new BZip2CompressorOutputStream(out);
160 }
Torsten Curdt2e3acfa2010-02-12 14:14:31 +0000161
Stefan Bodewigc4a65f02009-03-13 05:23:22 +0000162 } catch (IOException e) {
163 throw new CompressorException(
164 "Could not create CompressorOutputStream", e);
165 }
Christian Grobmeierc75d2d32009-04-14 04:46:49 +0000166 throw new CompressorException("Compressor: " + name + " not found.");
Torsten Curdtca165392008-07-10 10:17:44 +0000167 }
168}