View Javadoc

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  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      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          if ((bytes == null) || (bytes.length < 2))
50          {
51              return false;
52          }
53          else
54          {
55              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          if (bytes == null || isCompressed(bytes))
71          {
72              // nothing to compress
73              if (logger.isDebugEnabled())
74              {
75                  logger.debug("Data already compressed; doing nothing");
76              }
77              return bytes;
78          }
79  
80          if (logger.isDebugEnabled())
81          {
82              logger.debug("Compressing message of size: " + bytes.length);
83          }
84  
85          ByteArrayOutputStream baos = null;
86          GZIPOutputStream gzos = null;
87  
88          try
89          {
90              baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
91              gzos = new GZIPOutputStream(baos);
92  
93              gzos.write(bytes, 0, bytes.length);
94              gzos.finish();
95              gzos.close();
96  
97              byte[] compressedByteArray = baos.toByteArray();
98              baos.close();
99  
100             if (logger.isDebugEnabled())
101             {
102                 logger.debug("Compressed message to size: " + compressedByteArray.length);
103             }
104 
105             return compressedByteArray;
106         }
107         catch (IOException ioex)
108         {
109             throw ioex;
110         }
111         finally
112         {
113             IOUtils.closeQuietly(gzos);
114             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         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             if (logger.isDebugEnabled())
141             {
142                 logger.debug("Data already uncompressed; doing nothing");
143             }
144             return bytes;
145         }
146 
147         if (logger.isDebugEnabled())
148         {
149             logger.debug("Uncompressing message of size: " + bytes.length);
150         }
151 
152         ByteArrayInputStream bais = null;
153         GZIPInputStream gzis = null;
154         ByteArrayOutputStream baos = null;
155 
156         try
157         {
158             bais = new ByteArrayInputStream(bytes);
159             gzis = new GZIPInputStream(bais);
160             baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
161 
162             IOUtils.copy(gzis, baos);
163             gzis.close();
164             bais.close();
165 
166             byte[] uncompressedByteArray = baos.toByteArray();
167             baos.close();
168 
169             if (logger.isDebugEnabled())
170             {
171                 logger.debug("Uncompressed message to size: " + uncompressedByteArray.length);
172             }
173 
174             return uncompressedByteArray;
175         }
176         catch (IOException ioex)
177         {
178             throw ioex;
179         }
180         finally
181         {
182             IOUtils.closeQuietly(gzis);
183             IOUtils.closeQuietly(bais);
184             IOUtils.closeQuietly(baos);
185         }
186     }
187 
188 }