KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > remoting > loading > CompressedClassBytes


1 /***************************************
2  * *
3  * JBoss: The OpenSource J2EE WebOS *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  ***************************************/

9 package org.jboss.remoting.loading;
10
11 import java.io.Externalizable JavaDoc;
12 import java.io.StreamCorruptedException JavaDoc;
13
14
15 /**
16  * CompressedClassBytes is a ClassBytes subclass that compresses
17  * class data, if possible.
18  *
19  * @author <a HREF="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
20  * @version $Revision: 1.2 $
21  */

22 public class CompressedClassBytes extends ClassBytes implements Externalizable JavaDoc
23 {
24    static final long serialVersionUID = 5984363018051268886L;
25
26    private static final int MIN_COMPRESS = Integer.parseInt(System.getProperty("jboss.remoting.compression.min", "1000"));
27    private static final boolean DEBUG = Boolean.getBoolean("jboss.remoting.compression.debug");
28    private int compressionLevel;
29    private int compressedSize;
30    private int originalSize;
31
32    static final int VERSION_5_0 = 500;
33    static final int CURRENT_VERSION = VERSION_5_0;
34
35    public CompressedClassBytes()
36    {
37       super(null, null);
38    }
39
40    public CompressedClassBytes(String JavaDoc className, byte data[], int compressionLevel)
41    {
42       super(className, data);
43       this.compressionLevel = compressionLevel;
44    }
45
46    public static void main(String JavaDoc args[])
47    {
48       try
49       {
50          String JavaDoc string = new String JavaDoc("Hello,world - this is a test of compression, not sure what will happen. alskjfdalksjflkajsdfljaslkfjaslkdjflksajflkajsfdlkjsalkfjaslkfdjlksajflkasjfdlkajslkfjsalkfjasldfjlksadjflkasjfdlkajdsf");
51          byte buf [] = org.jboss.remoting.loading.ClassUtil.serialize(string);
52          CompressedClassBytes cb = new CompressedClassBytes("java.lang.String", buf, 9);
53          byte b1[] = org.jboss.remoting.loading.ClassUtil.serialize(cb);
54          Object JavaDoc obj = ClassUtil.deserialize(b1, ClassLoader.getSystemClassLoader());
55       }
56       catch(Throwable JavaDoc ex)
57       {
58          ex.printStackTrace();
59       }
60    }
61
62    public void readExternal(java.io.ObjectInput JavaDoc in) throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
63    {
64       int version = in.readInt();
65
66       switch(version)
67       {
68
69          case VERSION_5_0:
70             {
71
72                compressionLevel = in.readInt();
73                originalSize = in.readInt();
74                compressedSize = in.readInt();
75                byte buf[] = new byte[compressedSize];
76                int count = in.read(buf, 0, compressedSize);
77                if(compressedSize != originalSize)
78                {
79                   this.classBytes = uncompress(buf);
80                }
81                else
82                {
83                   this.classBytes = buf;
84                }
85                if(DEBUG)
86                {
87                   System.err.println("<< reading compressed: " + compressedSize + ", original: " + originalSize + ", compressionLevel:" + compressionLevel);
88                }
89                this.className = (String JavaDoc) in.readObject();
90             }
91          default:
92             throw new StreamCorruptedException JavaDoc("Unknown version seen: " + version);
93       }
94    }
95
96    public void writeExternal(java.io.ObjectOutput JavaDoc out) throws java.io.IOException JavaDoc
97    {
98       out.writeInt(CURRENT_VERSION);
99       out.writeInt(compressionLevel);
100       out.writeInt(classBytes.length);
101       byte compressed [] = compress(classBytes);
102       out.writeInt(compressed.length);
103       out.write(compressed);
104       out.writeObject(className);
105       out.flush();
106    }
107
108
109    /**
110     * Compresses the input data.
111     *
112     * @return null if compression results in larger output.
113     */

114    public byte[] compress(byte[] input)
115    {
116       // Too small to spend time compressing
117
if(input.length < MIN_COMPRESS)
118       {
119          return input;
120       }
121
122       java.util.zip.Deflater JavaDoc deflater = new java.util.zip.Deflater JavaDoc(compressionLevel);
123       deflater.setInput(input, 0, input.length);
124       deflater.finish();
125       byte[] buff = new byte[input.length + 50];
126       deflater.deflate(buff);
127
128       int compressedSize = deflater.getTotalOut();
129
130       // Did this data compress well?
131
if(deflater.getTotalIn() != input.length)
132       {
133          if(DEBUG)
134          {
135             System.err.println(">> Attempting compression and the data didn't compress well, returning original");
136          }
137          return input;
138       }
139       if(compressedSize >= input.length - 4)
140       {
141          if(DEBUG)
142          {
143             System.err.println(">> Compressed size is larger than original .. ?");
144          }
145          return input;
146       }
147
148       byte[] output = new byte[compressedSize + 4];
149       System.arraycopy(buff, 0, output, 4, compressedSize);
150       output[0] = (byte) (input.length >> 24);
151       output[1] = (byte) (input.length >> 16);
152       output[2] = (byte) (input.length >> 8);
153       output[3] = (byte) (input.length);
154       if(DEBUG)
155       {
156          System.err.println(">> writing compressed: " + output.length + ", original: " + classBytes.length + ", compressionLevel:" + compressionLevel);
157       }
158       return output;
159    }
160
161    /**
162     * Un-compresses the input data.
163     *
164     * @throws java.io.IOException if the input is not valid.
165     */

166    public byte[] uncompress(byte[] input) throws java.io.IOException JavaDoc
167    {
168       try
169       {
170          int uncompressedSize =
171                (((input[0] & 0xff) << 24) +
172                 ((input[1] & 0xff) << 16) +
173                 ((input[2] & 0xff) << 8) +
174                 ((input[3] & 0xff)));
175
176          java.util.zip.Inflater JavaDoc inflater = new java.util.zip.Inflater JavaDoc();
177          inflater.setInput(input, 4, input.length - 4);
178          inflater.finished();
179
180          byte[] out = new byte[uncompressedSize];
181          inflater.inflate(out);
182
183          inflater.reset();
184          return out;
185
186       }
187       catch(java.util.zip.DataFormatException JavaDoc e)
188       {
189          throw new java.io.IOException JavaDoc("Input Stream is corrupt: " + e);
190       }
191    }
192 }
193
Popular Tags