001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019 package org.apache.commons.compress.compressors;
020
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.OutputStream;
024
025 import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
026 import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
027 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
028 import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
029
030 /**
031 * <p>Factory to create Compressor[In|Out]putStreams from names. To add other
032 * implementations you should extend CompressorStreamFactory and override the
033 * appropriate methods (and call their implementation from super of course).</p>
034 *
035 * Example (Compressing a file):
036 *
037 * <pre>
038 * final OutputStream out = new FileOutputStream(output);
039 * CompressorOutputStream cos =
040 * new CompressorStreamFactory().createCompressorOutputStream(CompressorStreamFactory.BZIP2, out);
041 * IOUtils.copy(new FileInputStream(input), cos);
042 * cos.close();
043 * </pre>
044 *
045 * Example (Compressing a file):
046 * <pre>
047 * final InputStream is = new FileInputStream(input);
048 * CompressorInputStream in =
049 * new CompressorStreamFactory().createCompressorInputStream(CompressorStreamFactory.BZIP2, is);
050 * IOUtils.copy(in, new FileOutputStream(output));
051 * in.close();
052 * </pre>
053 *
054 * @Immutable
055 */
056 public class CompressorStreamFactory {
057
058 /**
059 * Constant used to identify the BZIP2 compression algorithm.
060 * @since Commons Compress 1.1
061 */
062 public static final String BZIP2 = "bzip2";
063 /**
064 * Constant used to identify the GZIP compression algorithm.
065 * @since Commons Compress 1.1
066 */
067 public static final String GZIP = "gz";
068
069 /**
070 * Create an compressor input stream from an input stream, autodetecting
071 * the compressor type from the first few bytes of the stream. The InputStream
072 * must support marks, like BufferedInputStream.
073 *
074 * @param in the input stream
075 * @return the compressor input stream
076 * @throws CompressorException if the compressor name is not known
077 * @throws IllegalArgumentException if the stream is null or does not support mark
078 * @since Commons Compress 1.1
079 */
080 public CompressorInputStream createCompressorInputStream(final InputStream in)
081 throws CompressorException {
082 if (in == null) {
083 throw new IllegalArgumentException("Stream must not be null.");
084 }
085
086 if (!in.markSupported()) {
087 throw new IllegalArgumentException("Mark is not supported.");
088 }
089
090 final byte[] signature = new byte[12];
091 in.mark(signature.length);
092 try {
093 int signatureLength = in.read(signature);
094 in.reset();
095
096 if (BZip2CompressorInputStream.matches(signature, signatureLength)) {
097 return new BZip2CompressorInputStream(in);
098 }
099
100 if (GzipCompressorInputStream.matches(signature, signatureLength)) {
101 return new GzipCompressorInputStream(in);
102 }
103
104 } catch (IOException e) {
105 throw new CompressorException("Failed to detect Compressor from InputStream.", e);
106 }
107
108 throw new CompressorException("No Compressor found for the stream signature.");
109 }
110
111 /**
112 * Create a compressor input stream from a compressor name and an input stream.
113 *
114 * @param name of the compressor, i.e. "gz" or "bzip2"
115 * @param in the input stream
116 * @return compressor input stream
117 * @throws CompressorException if the compressor name is not known
118 * @throws IllegalArgumentException if the name or input stream is null
119 */
120 public CompressorInputStream createCompressorInputStream(final String name,
121 final InputStream in) throws CompressorException {
122 if (name == null || in == null) {
123 throw new IllegalArgumentException(
124 "Compressor name and stream must not be null.");
125 }
126
127 try {
128
129 if (GZIP.equalsIgnoreCase(name)) {
130 return new GzipCompressorInputStream(in);
131 }
132
133 if (BZIP2.equalsIgnoreCase(name)) {
134 return new BZip2CompressorInputStream(in);
135 }
136
137 } catch (IOException e) {
138 throw new CompressorException(
139 "Could not create CompressorInputStream.", e);
140 }
141 throw new CompressorException("Compressor: " + name + " not found.");
142 }
143
144 /**
145 * Create an compressor output stream from an compressor name and an input stream.
146 *
147 * @param name the compressor name, i.e. "gz" or "bzip2"
148 * @param out the output stream
149 * @return the compressor output stream
150 * @throws CompressorException if the archiver name is not known
151 * @throws IllegalArgumentException if the archiver name or stream is null
152 */
153 public CompressorOutputStream createCompressorOutputStream(
154 final String name, final OutputStream out)
155 throws CompressorException {
156 if (name == null || out == null) {
157 throw new IllegalArgumentException(
158 "Compressor name and stream must not be null.");
159 }
160
161 try {
162
163 if (GZIP.equalsIgnoreCase(name)) {
164 return new GzipCompressorOutputStream(out);
165 }
166
167 if (BZIP2.equalsIgnoreCase(name)) {
168 return new BZip2CompressorOutputStream(out);
169 }
170
171 } catch (IOException e) {
172 throw new CompressorException(
173 "Could not create CompressorOutputStream", e);
174 }
175 throw new CompressorException("Compressor: " + name + " not found.");
176 }
177 }