KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > enhancer > ByteCodeEnhancerHelper


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 //ByteCodeEnhancerHelper - Java Source
25

26
27 //***************** package ***********************************************
28

29 package com.sun.jdo.api.persistence.enhancer;
30
31
32 //***************** import ************************************************
33

34 import java.io.IOException JavaDoc;
35 import java.io.InputStream JavaDoc;
36 import java.io.OutputStream JavaDoc;
37 import java.io.ByteArrayInputStream JavaDoc;
38 import java.io.ByteArrayOutputStream JavaDoc;
39
40 import java.util.zip.CRC32 JavaDoc;
41 import java.util.zip.ZipEntry JavaDoc;
42 import java.util.zip.ZipInputStream JavaDoc;
43 import java.util.zip.ZipOutputStream JavaDoc;
44
45
46 //#########################################################################
47
/**
48  * This is a helper-class to perform some useful operations outside a
49  * byte code enhancer and delegate the real work to the enhancer.
50  */

51 //#########################################################################
52

53 public class ByteCodeEnhancerHelper
54 {
55
56
57     /**********************************************************************
58      * Enhances a classfile.
59      *
60      * @param enhancer The enhancer to delegate the work to.
61      * @param in The input stream with the Java class.
62      * @param out The output stream to write the enhanced class to.
63      *
64      * @return Has the input stream been enhanced?
65      *
66      * @exception EnhancerUserException If something went wrong.
67      * @exception EnhancerFatalError If something went wrong.
68      *
69      * @see ByteCodeEnhancer#enhanceClassFile
70      *********************************************************************/

71
72     public static final boolean enhanceClassFile (ByteCodeEnhancer enhancer,
73                                                   InputStream JavaDoc in,
74                                                   OutputStream JavaDoc out)
75                                 throws EnhancerUserException,
76                                        EnhancerFatalError
77     {
78
79         return enhancer.enhanceClassFile (in, new OutputStreamWrapper (out));
80
81     } //ByteCodeEnhancerHelper.enhanceClassFile()
82

83
84     /**********************************************************************
85      * Enhances a zip file. The zip file is given as a uip input stream.
86      * It's entries are read and - if necessary - individually enhanced.
87      * The output stream has the same compression (if any) as the input
88      * stream.
89      *
90      * @param enhancer The enhancer.
91      * @param zip_in The zip input stream.
92      * @param zip_out The zip output stream.
93      *
94      * @param <code>true</code> if at least one entry of the zip file has
95      * been enhanced, <code>false</code> otherwise.
96      *
97      * @exception EnhancerUserException If something went wrong.
98      * @exception EnhancerFatalError If something went wrong.
99      *
100      * @see ByteCodeEnhancer#enhanceClassFile
101      *********************************************************************/

102
103     public static final boolean enhanceZipFile (ByteCodeEnhancer enhancer,
104                                                 ZipInputStream JavaDoc zip_in,
105                                                 ZipOutputStream JavaDoc zip_out)
106                                 throws EnhancerUserException,
107                                        EnhancerFatalError
108     {
109
110         boolean enhanced = false;
111         try
112         {
113             CRC32 JavaDoc crc32 = new CRC32 JavaDoc ();
114             ZipEntry JavaDoc entry;
115             while ((entry = zip_in.getNextEntry ()) != null)
116             {
117                 InputStream JavaDoc in = zip_in;
118                 ZipEntry JavaDoc out_entry = new ZipEntry JavaDoc (entry);
119
120                 //try to enhance
121
if (isClassFileEntry (entry)) //enhance the classfile
122
{
123                     //we have to copy the classfile, because if it won't be enhanced,
124
//the OutputStream is empty and we have to re-read the InputStream,
125
//which is impossiblewith a ZipInputStream (no mark/reset)
126
in = openZipEntry (zip_in);
127                     in.mark (Integer.MAX_VALUE);
128                     ByteArrayOutputStream JavaDoc tmp = new ByteArrayOutputStream JavaDoc ();
129                     if (enhancer.enhanceClassFile (in, tmp))
130                     {
131                         enhanced = true;
132                         byte [] bytes = tmp.toByteArray ();
133                         tmp.close ();
134                         in.close ();
135                         modifyZipEntry (out_entry, bytes, crc32);
136                         in = new ByteArrayInputStream JavaDoc (bytes);
137                     }
138                     else
139                     {
140                         //the classfile has not been enhanced
141
in.reset ();
142                     }
143                 }
144
145                 //copy the entry
146
zip_out.putNextEntry (out_entry);
147                 copyZipEntry (in, zip_out);
148                 zip_out.closeEntry ();
149
150                 if (in != zip_in)
151                 {
152                     in.close ();
153                 }
154             }
155         }
156         catch (IOException JavaDoc ex)
157         {
158             throw new EnhancerFatalError (ex);
159         }
160
161         return enhanced;
162
163     } //ByteCodeEnhancerHelper.enhanceZipFile()
164

165
166     /**********************************************************************
167      * Copies a zip entry from one stream to another.
168      *
169      * @param in The inout stream.
170      * @param out The output stream.
171      *
172      * @exception IOException If the stream access failed.
173      *********************************************************************/

174
175     private static final void copyZipEntry (InputStream JavaDoc in,
176                                             OutputStream JavaDoc out)
177                               throws IOException JavaDoc
178     {
179
180         int b;
181         while ((in.available () > 0) && (b = in.read ()) > -1)
182         {
183             out.write (b);
184         }
185
186     } //ByteCodeEnhancerHelper.copyZipEntry()
187

188
189     /**********************************************************************
190      * Opens the next zip entry of a zip input stream and copies it to
191      * a <code>java.io.ByteArrayOutputStream</code>. It's byte array is made
192      * available via an <code>java.io.ByteArrayInputStream</code> which is
193      * returned.
194      *
195      * @param in The zip input stream.
196      *
197      * @return The newly created input stream with the next zip entry.
198      *
199      * @exception IOException If an I/O operation failed.
200      *********************************************************************/

201
202     private static final InputStream JavaDoc openZipEntry (ZipInputStream JavaDoc in)
203                                      throws IOException JavaDoc
204     {
205
206         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc ();
207         copyZipEntry (in, out);
208
209         return new ByteArrayInputStream JavaDoc (out.toByteArray ());
210
211     } //ByteCodeEnhancerHelper.openZipEntry()
212

213
214     /**********************************************************************
215      * Modifies the given zip entry so that it can be added to zip file.
216      * The given zip entry represents an enhanced class, so the zip entry
217      * has to get the correct size and checksum (but only it the entry won't
218      * be compressed).
219      *
220      * @param entry The zip entry to modify.
221      * @param bytes The uncompressed byte representation of the classfile.
222      * @param crc32 The checksum evaluator.
223      *********************************************************************/

224
225     private static final void modifyZipEntry (ZipEntry JavaDoc entry,
226                                               byte [] bytes,
227                                               CRC32 JavaDoc crc32)
228     {
229
230         entry.setSize (bytes.length);
231         if (entry.getMethod () == 0) //no compression (ZipInputStream.STORED - not accessible)
232
{
233             crc32.reset ();
234             crc32.update (bytes);
235             entry.setCrc (crc32.getValue ());
236             entry.setCompressedSize (bytes.length);
237         }
238
239     } //ByteCodeEnhancerHelper.modifyZipEntry()
240

241
242     /**********************************************************************
243      * Determines if a given entry represents a classfile.
244      *
245      * @return Does the given entry represent a classfile?
246      *********************************************************************/

247
248     private static final boolean isClassFileEntry (ZipEntry JavaDoc entry)
249     {
250
251         return entry.getName ().endsWith (".class");
252
253     } //ByteCodeEnhancerHelper.isClassFileEntry()
254

255
256 } //ByteCodeEnhancerHelper
257

258
259 //ByteCodeEnhancer - Java Source End
260
Popular Tags