Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
GZipCompression |
|
| 7.0;7 |
1 | /* | |
2 | * $Id: GZipCompression.java 7976 2007-08-21 14:26:13Z dirk.olmes $ | |
3 | * -------------------------------------------------------------------------------------- | |
4 | * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com | |
5 | * | |
6 | * The software in this package is published under the terms of the CPAL v1.0 | |
7 | * license, a copy of which has been included with this distribution in the | |
8 | * LICENSE.txt file. | |
9 | */ | |
10 | ||
11 | package org.mule.util.compression; | |
12 | ||
13 | import java.io.ByteArrayInputStream; | |
14 | import java.io.IOException; | |
15 | import java.util.zip.GZIPInputStream; | |
16 | import java.util.zip.GZIPOutputStream; | |
17 | ||
18 | import org.apache.commons.io.IOUtils; | |
19 | import org.apache.commons.io.output.ByteArrayOutputStream; | |
20 | import org.apache.commons.logging.Log; | |
21 | import org.apache.commons.logging.LogFactory; | |
22 | ||
23 | /** | |
24 | * <code>GZipCompression</code> is a CompressionStrategy implementation using the | |
25 | * GZip library included in the JDK java.util.zip. This is the default | |
26 | * CompressionStrategy used by the CompressionHelper discovery when no other | |
27 | * implementation is discovered. | |
28 | */ | |
29 | 0 | public class GZipCompression implements CompressionStrategy |
30 | { | |
31 | public static final int DEFAULT_BUFFER_SIZE = 32768; | |
32 | ||
33 | /** | |
34 | * The logger for this class | |
35 | */ | |
36 | 0 | private static final Log logger = LogFactory.getLog(GZipCompression.class); |
37 | ||
38 | /** | |
39 | * Determines if a byte array is compressed. The java.util.zip GZip | |
40 | * implementaiton does not expose the GZip header so it is difficult to determine | |
41 | * if a string is compressed. | |
42 | * | |
43 | * @param bytes an array of bytes | |
44 | * @return true if the array is compressed or false otherwise | |
45 | * @throws java.io.IOException if the byte array couldn't be read | |
46 | */ | |
47 | public boolean isCompressed(byte[] bytes) throws IOException | |
48 | { | |
49 | 0 | if ((bytes == null) || (bytes.length < 2)) |
50 | { | |
51 | 0 | return false; |
52 | } | |
53 | else | |
54 | { | |
55 | 0 | return ((bytes[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (bytes[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8))); |
56 | } | |
57 | } | |
58 | ||
59 | /** | |
60 | * Used for compressing a byte array into a new byte array using GZIP | |
61 | * | |
62 | * @param bytes An array of bytes to compress | |
63 | * @return a compressed byte array | |
64 | * @throws java.io.IOException if it fails to write to a GZIPOutputStream | |
65 | * @see java.util.zip.GZIPOutputStream | |
66 | */ | |
67 | public byte[] compressByteArray(byte[] bytes) throws IOException | |
68 | { | |
69 | // TODO add strict behaviour as option | |
70 | 0 | if (bytes == null || isCompressed(bytes)) |
71 | { | |
72 | // nothing to compress | |
73 | 0 | if (logger.isDebugEnabled()) |
74 | { | |
75 | 0 | logger.debug("Data already compressed; doing nothing"); |
76 | } | |
77 | 0 | return bytes; |
78 | } | |
79 | ||
80 | 0 | if (logger.isDebugEnabled()) |
81 | { | |
82 | 0 | logger.debug("Compressing message of size: " + bytes.length); |
83 | } | |
84 | ||
85 | 0 | ByteArrayOutputStream baos = null; |
86 | 0 | GZIPOutputStream gzos = null; |
87 | ||
88 | try | |
89 | { | |
90 | 0 | baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE); |
91 | 0 | gzos = new GZIPOutputStream(baos); |
92 | ||
93 | 0 | gzos.write(bytes, 0, bytes.length); |
94 | 0 | gzos.finish(); |
95 | 0 | gzos.close(); |
96 | ||
97 | 0 | byte[] compressedByteArray = baos.toByteArray(); |
98 | 0 | baos.close(); |
99 | ||
100 | 0 | if (logger.isDebugEnabled()) |
101 | { | |
102 | 0 | logger.debug("Compressed message to size: " + compressedByteArray.length); |
103 | } | |
104 | ||
105 | 0 | return compressedByteArray; |
106 | } | |
107 | 0 | catch (IOException ioex) |
108 | { | |
109 | 0 | throw ioex; |
110 | } | |
111 | finally | |
112 | { | |
113 | 0 | IOUtils.closeQuietly(gzos); |
114 | 0 | IOUtils.closeQuietly(baos); |
115 | } | |
116 | } | |
117 | ||
118 | /** | |
119 | * Used for uncompressing a byte array into a uncompressed byte array using GZIP | |
120 | * | |
121 | * @param bytes An array of bytes to uncompress | |
122 | * @return an uncompressed byte array | |
123 | * @throws java.io.IOException if it fails to read from a GZIPInputStream | |
124 | * @see java.util.zip.GZIPInputStream | |
125 | */ | |
126 | public byte[] uncompressByteArray(byte[] bytes) throws IOException | |
127 | { | |
128 | // TODO add strict behaviour as option | |
129 | 0 | if (!isCompressed(bytes)) |
130 | { | |
131 | /* | |
132 | * if (strict) { // throw a specific exception here to allow users of | |
133 | * this method to // diffientiate between general IOExceptions and an | |
134 | * invalid format logger.warn("Data is not of type GZIP compressed." + " | |
135 | * The data may not have been compressed in the first place."); throw new | |
136 | * CompressionException("Not in GZIP format"); } | |
137 | */ | |
138 | ||
139 | // nothing to uncompress | |
140 | 0 | if (logger.isDebugEnabled()) |
141 | { | |
142 | 0 | logger.debug("Data already uncompressed; doing nothing"); |
143 | } | |
144 | 0 | return bytes; |
145 | } | |
146 | ||
147 | 0 | if (logger.isDebugEnabled()) |
148 | { | |
149 | 0 | logger.debug("Uncompressing message of size: " + bytes.length); |
150 | } | |
151 | ||
152 | 0 | ByteArrayInputStream bais = null; |
153 | 0 | GZIPInputStream gzis = null; |
154 | 0 | ByteArrayOutputStream baos = null; |
155 | ||
156 | try | |
157 | { | |
158 | 0 | bais = new ByteArrayInputStream(bytes); |
159 | 0 | gzis = new GZIPInputStream(bais); |
160 | 0 | baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE); |
161 | ||
162 | 0 | IOUtils.copy(gzis, baos); |
163 | 0 | gzis.close(); |
164 | 0 | bais.close(); |
165 | ||
166 | 0 | byte[] uncompressedByteArray = baos.toByteArray(); |
167 | 0 | baos.close(); |
168 | ||
169 | 0 | if (logger.isDebugEnabled()) |
170 | { | |
171 | 0 | logger.debug("Uncompressed message to size: " + uncompressedByteArray.length); |
172 | } | |
173 | ||
174 | 0 | return uncompressedByteArray; |
175 | } | |
176 | 0 | catch (IOException ioex) |
177 | { | |
178 | 0 | throw ioex; |
179 | } | |
180 | finally | |
181 | { | |
182 | 0 | IOUtils.closeQuietly(gzis); |
183 | 0 | IOUtils.closeQuietly(bais); |
184 | 0 | IOUtils.closeQuietly(baos); |
185 | } | |
186 | } | |
187 | ||
188 | } |