KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > zip > ZipFile


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 /* Byron Nevins, April 2000
25  * ZipFile -- A utility class for exploding archive (zip) files.
26  */

27
28 package com.sun.enterprise.util.zip;
29
30 import com.sun.enterprise.util.OS;
31 import java.io.*;
32 import java.util.*;
33 import java.util.zip.*;
34 import java.util.jar.JarFile JavaDoc;
35
36 import com.sun.enterprise.util.io.FileUtils;
37 import com.sun.enterprise.util.Assertion;
38 import com.sun.enterprise.util.diagnostics.Reporter;
39
40 import com.sun.logging.LogDomains;
41 import java.util.logging.Logger JavaDoc;
42 import java.util.logging.Level JavaDoc;
43
44
45 ///////////////////////////////////////////////////////////////////////////////
46

47 public class ZipFile
48 {
49     public ZipFile(String JavaDoc zipFilename, String JavaDoc explodeDirName) throws ZipFileException
50     {
51         this(new File JavaDoc(zipFilename), new File JavaDoc(explodeDirName));
52     }
53         
54     ///////////////////////////////////////////////////////////////////////////
55

56     public ZipFile(InputStream inStream, String JavaDoc anExplodeDirName) throws ZipFileException
57     {
58         this(new BufferedInputStream(inStream, BUFFER_SIZE), new File JavaDoc(anExplodeDirName));
59     }
60     
61     ///////////////////////////////////////////////////////////////////////////
62

63     public ZipFile(File JavaDoc zipFile, File JavaDoc anExplodeDir) throws ZipFileException
64     {
65         checkZipFile(zipFile);
66         BufferedInputStream bis = null;
67         
68         try
69         {
70             bis = new BufferedInputStream(new FileInputStream(zipFile), BUFFER_SIZE);
71                         ctor(bis, anExplodeDir);
72                         this.zipFile = zipFile;
73         }
74         catch(Throwable JavaDoc e)
75         {
76                     if (bis != null) {
77                         try {
78                             bis.close();
79                         } catch (Throwable JavaDoc thr) {
80                             throw new ZipFileException(thr);
81                         }
82                     }
83             throw new ZipFileException(e);
84         }
85         }
86         
87     ///////////////////////////////////////////////////////////////////////////
88

89     public ZipFile(InputStream inStream, File JavaDoc anExplodeDir) throws ZipFileException
90     {
91         ctor(inStream, anExplodeDir);
92     }
93
94     /** Explodes files as usual, and then explodes every jar file found. All
95      * explosions are copied relative the same root directory.<p>It does a case-sensitive check for files that end with ".jar"
96          * will comment out for later possbile use
97     public ArrayList explodeAll() throws ZipFileException
98     {
99         return doExplode(this);
100     }
101          */

102         
103     //////////////////////////////////////////////////////////////////////////////////////////////////////////////
104

105     public ArrayList explode() throws ZipFileException
106     {
107         files = new ArrayList();
108         ZipInputStream zin = null;
109
110         try
111         {
112             zin = zipStream; // new ZipInputStream(new FileInputStream(zipFile));
113
ZipEntry ze;
114
115             while( (ze = zin.getNextEntry()) != null )
116             {
117                 String JavaDoc filename = ze.getName();
118                 
119                 /*
120                 if(isManifest(filename))
121                 {
122                     continue; // don't bother with manifest file...
123                 }
124                 */

125                 
126                 File JavaDoc fullpath = null;
127                 
128                 if(isDirectory(filename))
129                 {
130                     // just a directory -- make it and move on...
131
fullpath = new File JavaDoc(explodeDir, filename.substring(0, filename.length() - 1));
132                                         if (OS.isWindows()) {
133                                             FileUtils.validateWindowsFilePathLength(fullpath);
134                                         }
135                     fullpath.mkdir();
136                     continue;
137                 }
138                     
139                 fullpath = new File JavaDoc(explodeDir, filename);
140                                 if (OS.isWindows() ) {
141                                     FileUtils.validateWindowsFilePathLength(fullpath);
142                                 }
143                                 
144                 File JavaDoc newDir = fullpath.getParentFile();
145
146                 if(newDir.mkdirs())
147                 { // note: it returns false if dir already exists...
148
Reporter.verbose("Created new directory: " + newDir);//NOI18N
149
}
150
151                 if(fullpath.delete()) { // wipe-out pre-existing files
152
Reporter.info("deleted pre-existing file: " + fullpath); //NOI18N
153
/*
154                                          *Report that a file is being overwritten.
155                                          */

156                                         if (_utillogger.isLoggable(Level.FINE) ) {
157                                             _utillogger.log(Level.FINE, "File " + fullpath.getAbsolutePath() + " is being overwritten during expansion of " + (zipFile != null ? ("file " + zipFile.getAbsolutePath() ) : "stream"));
158                                         }
159                                 }
160
161                 BufferedOutputStream os = new BufferedOutputStream(getOutputStream(filename), BUFFER_SIZE);
162
163                 if(os == null) // e.g. if we asked to write to a directory instead of a file...
164
continue;
165
166                 int totalBytes = 0;
167
168                 for(int numBytes = zin.read(buffer); numBytes > 0; numBytes = zin.read(buffer))
169                 {
170                     os.write(buffer, 0, numBytes);
171                     totalBytes += numBytes;
172                 }
173                 os.close();
174                 Reporter.verbose("Wrote " + totalBytes + " to " + filename);//NOI18N
175
files.add(filename);
176             }
177         }
178         catch(IOException e)
179         {
180             throw new ZipFileException(e);
181         }
182         finally
183         {
184             Reporter.verbose("Closing zin...");//NOI18N
185
try
186             {
187                 zin.close();
188             }
189             catch(IOException e)
190             {
191                 throw new ZipFileException("Got an exception while trying to close Jar input stream: " + e);//NOI18N
192
}
193         }
194         Reporter.info("Successfully Exploded ZipFile" + " to " + explodeDir.getPath());//NOI18N
195
return files;
196     }
197     
198     /**
199      * Extracts the named jar file from the ear.
200      *
201      * @param jarEntryName name of the jar file
202      * @param earFile application archive
203      * @param jarFile locaton of the jar file where the jar entry
204      * will be extracted
205      *
206      * @return the named jar file from the ear
207      *
208      * @exception ZipFileException if an error while extracting the jar
209      */

210     public static void extractJar(String JavaDoc jarEntryName, JarFile JavaDoc earFile,
211             File JavaDoc jarFile) throws ZipFileException
212     {
213         
214         try
215         {
216             if (OS.isWindows()) {
217                             FileUtils.validateWindowsFilePathLength(jarFile);
218                         }
219                         File JavaDoc parent = jarFile.getParentFile();
220             if (!parent.exists())
221             {
222                 parent.mkdirs();
223             }
224
225             ZipEntry jarEntry = earFile.getEntry(jarEntryName);
226             if (jarEntryName == null)
227             {
228                 throw new ZipFileException(jarEntryName
229                                      + " not found in " + earFile.getName());
230             }
231
232             InputStream is = earFile.getInputStream(jarEntry);
233             FileOutputStream fos = new FileOutputStream(jarFile);
234                         // the FileUtils.copy will buffer the streams,
235
// so we won't buffer them here.
236
FileUtils.copy(is, fos);
237         }
238         catch (IOException e)
239         {
240             throw new ZipFileException(e);
241         }
242     }
243
244     ///////////////////////////////////////////////////////////////////////////
245

246     public ArrayList getFileList()
247     {
248         return files;
249     }
250     
251     /***********************************************************************
252     /******************************** Private ******************************
253     /***********************************************************************/

254     private static ArrayList doExplode(ZipFile zf) throws ZipFileException
255         {
256             ArrayList finalList = new ArrayList(50);
257             ArrayList zipFileList = new ArrayList();
258             ArrayList tmpList = null;
259             ZipFile tmpZf = null;
260             Iterator itr = null;
261             String JavaDoc fileName = null;
262
263             zipFileList.add(zf);
264             while (zipFileList.size() > 0)
265             {
266                 // get "last" jar to explode
267
tmpZf = (ZipFile)zipFileList.remove(zipFileList.size() - 1);
268                 tmpList = tmpZf.explode();
269
270                 // traverse list of files
271
itr = tmpList.iterator();
272                 while (itr.hasNext())
273                 {
274                     fileName = (String JavaDoc)itr.next();
275                     if ( ! fileName.endsWith(".jar") )
276                     {
277                         // add non-jar file to finalList
278
finalList.add(fileName);
279                     }
280                     else
281                     {
282                         // create ZipFile and add to zipFileList
283
File JavaDoc f = new File JavaDoc(tmpZf.explodeDir, fileName);
284                         ZipFile newZf = new ZipFile(f, tmpZf.explodeDir);
285                         zipFileList.add(newZf);
286                     }
287
288                     if (tmpZf != zf) // don't remove first ZipFile
289
{
290                         tmpZf.explodeDir.delete();
291                     }
292                 }
293             }
294             return finalList;
295         }
296
297     //////////////////////////////////////////////////////////////////////////////////////////////////////////////
298

299     private void ctor(InputStream inStream, File JavaDoc anExplodeDir) throws ZipFileException
300     {
301         insist(anExplodeDir != null);
302         explodeDir = anExplodeDir;
303
304         try
305         {
306             zipStream = new ZipInputStream(inStream);
307             checkExplodeDir();
308         }
309         catch(Throwable JavaDoc t)
310         {
311                     if (zipStream != null) {
312                         try {
313                             zipStream.close();
314                         } catch (Throwable JavaDoc thr) {
315                         }
316                     }
317             throw new ZipFileException(t.toString());
318         }
319     }
320         
321     ///////////////////////////////////////////////////////////////////////////
322

323     private boolean isDirectory(String JavaDoc s)
324     {
325         char c = s.charAt(s.length() - 1);
326         
327         return c== '/' || c == '\\';
328     }
329
330     /////////////////////////////////////////////////////////////////////////////////////////
331

332     private void checkZipFile(File JavaDoc zipFile) throws ZipFileException
333     {
334         insist(zipFile != null);
335         
336         String JavaDoc zipFileName = zipFile.getPath();
337
338         insist( zipFile.exists(), "zipFile (" + zipFileName + ") doesn't exist" );//NOI18N
339
insist( !zipFile.isDirectory(), "zipFile (" + zipFileName + ") is actually a directory!" );//NOI18N
340
}
341
342     /////////////////////////////////////////////////////////////////////////////////////////
343

344     private void checkExplodeDir() throws ZipFileException
345     {
346         String JavaDoc explodeDirName = explodeDir.getPath();
347         
348         // just in case...
349
explodeDir.mkdirs();
350         
351         insist(explodeDir.exists(), "Target Directory doesn't exist: " + explodeDirName );//NOI18N
352
insist(explodeDir.isDirectory(), "Target Directory isn't a directory: " + explodeDirName );//NOI18N
353
insist(explodeDir.canWrite(), "Can't write to Target Directory: " + explodeDirName );//NOI18N
354
}
355
356     /////////////////////////////////////////////////////////////////////////////////////////
357

358     private static boolean isSpecial(String JavaDoc filename)
359     {
360         return filename.toUpperCase().startsWith(specialDir.toUpperCase());
361     }
362
363     /////////////////////////////////////////////////////////////////////////////////////////
364

365     private FileOutputStream getOutputStream(String JavaDoc filename) throws ZipFileException
366     {
367         File JavaDoc f = new File JavaDoc(explodeDir, filename);
368
369         if(f.isDirectory())
370         {
371             Reporter.warn("Weird! A directory is listed as an entry in the jar file -- skipping...");//NOI18N
372
return null;
373         }
374
375         try
376         {
377             return new FileOutputStream(f);
378         }
379         catch(FileNotFoundException e)
380         {
381             throw new ZipFileException("filename: " + f.getPath() + " " + e);
382         }
383         catch(IOException e)
384         {
385             throw new ZipFileException(e);
386         }
387     }
388
389     /////////////////////////////////////////////////////////////////////////////////////////
390

391     private boolean isManifest(String JavaDoc filename)
392     {
393         if(filename.toLowerCase().endsWith("manifest.mf"))//NOI18N
394
return false;
395         
396         return false;
397     }
398
399     /////////////////////////////////////////////////////////////////////////////////////////
400
//////////// //////////////////////////
401
//////////// Internal Error-Checking Stuff //////////////////////////
402
//////////// //////////////////////////
403
/////////////////////////////////////////////////////////////////////////////////////////
404

405     private static void pr(String JavaDoc s)
406     {
407         System.out.println( s );
408     }
409
410     /////////////////////////////////////////////////////////////////////////////////////////
411

412     private static void insist(String JavaDoc s) throws ZipFileException
413     {
414         if( s == null || s.length() < 0 )
415             throw new ZipFileException();
416         else
417             return;
418     }
419
420     /////////////////////////////////////////////////////////////////////////////////////////
421

422     private static void insist(String JavaDoc s, String JavaDoc mesg) throws ZipFileException
423     {
424         if( s == null || s.length() < 0 )
425             throw new ZipFileException( mesg );
426         else
427             return;
428     }
429
430     /////////////////////////////////////////////////////////////////////////////////////////
431

432     private static void insist(boolean b) throws ZipFileException
433     {
434         if( !b )
435             throw new ZipFileException();
436         else
437             return;
438     }
439
440     /////////////////////////////////////////////////////////////////////////////////////////
441

442     private static void insist(boolean b, String JavaDoc mesg) throws ZipFileException
443     {
444         if( !b )
445             throw new ZipFileException( mesg );
446         else
447             return;
448     }
449
450     /////////////////////////////////////////////////////////////////////////////////////////
451

452         private static final int BUFFER_SIZE = 0x10000; //64k
453
private File JavaDoc explodeDir = null;
454     private ArrayList files = null;
455     private static final String JavaDoc specialDir = "META-INF/";//NOI18N
456
private byte[] buffer = new byte[BUFFER_SIZE];
457     private ZipInputStream zipStream = null;
458         private Logger JavaDoc _utillogger = LogDomains.getLogger(LogDomains.UTIL_LOGGER);
459         private File JavaDoc zipFile = null;
460 }
461
462 ////////////////
463
Popular Tags