KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > util > ZipUtil


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.util;
57
58 import java.io.BufferedInputStream JavaDoc;
59 import java.io.BufferedOutputStream JavaDoc;
60 import java.io.File JavaDoc;
61 import java.io.FileInputStream JavaDoc;
62 import java.io.FileOutputStream JavaDoc;
63 import java.io.IOException JavaDoc;
64 import java.io.InputStream JavaDoc;
65 import java.io.OutputStream JavaDoc;
66 import java.util.Enumeration JavaDoc;
67 import java.util.zip.ZipEntry JavaDoc;
68 import java.util.zip.ZipFile JavaDoc;
69 import java.util.zip.ZipOutputStream JavaDoc;
70
71 /**
72  * Utility class to perform zip/unzip operations on files and directories.
73  *
74  * @author Andrei Adamchik
75  */

76 public class ZipUtil {
77
78     /**
79      * Constructor for ZipUtil.
80      */

81     public ZipUtil() {
82         super();
83     }
84
85     /**
86       * Unpacks a zip file to the target directory.
87       *
88       * @param zipFile
89       * @param destDir
90       * @throws IOException
91       */

92     public static void unzip(File JavaDoc zipFile, File JavaDoc destDir) throws IOException JavaDoc {
93         ZipFile JavaDoc zip = new ZipFile JavaDoc(zipFile);
94
95         try {
96             Enumeration JavaDoc en = zip.entries();
97             int bufSize = 8 * 1024;
98
99             while (en.hasMoreElements()) {
100                 ZipEntry JavaDoc entry = (ZipEntry JavaDoc) en.nextElement();
101                 File JavaDoc file =
102                     (destDir != null)
103                         ? new File JavaDoc(destDir, entry.getName())
104                         : new File JavaDoc(entry.getName());
105
106                 if (entry.isDirectory()) {
107                     if (!file.mkdirs()) {
108                         throw new IOException JavaDoc(
109                             "Error creating directory: " + file);
110                     }
111                 } else {
112                     File JavaDoc parent = file.getParentFile();
113                     if (parent != null && !parent.exists()) {
114                         if (!parent.mkdirs()) {
115                             throw new IOException JavaDoc(
116                                 "Error creating directory: " + parent);
117                         }
118                     }
119
120                     InputStream JavaDoc in = zip.getInputStream(entry);
121                     try {
122                         OutputStream JavaDoc out =
123                             new BufferedOutputStream JavaDoc(
124                                 new FileOutputStream JavaDoc(file),
125                                 bufSize);
126
127                         try {
128                             Util.copyPipe(in, out, bufSize);
129                         } finally {
130                             out.close();
131                         }
132
133                     } finally {
134                         in.close();
135                     }
136                 }
137             }
138         } finally {
139             zip.close();
140         }
141     }
142
143     /**
144       * Recursively zips a set of root entries into a zipfile, compressing the
145       * contents.
146       *
147       * @param zipFile target zip file.
148       * @param parentDir a directory containing source files to zip.
149       * @param sources an array of files and/or directories to zip.
150       * @param pathSeparator path separator for zip entries.
151       *
152       * @throws IOException
153       */

154     public static void zip(
155         File JavaDoc zipFile,
156         File JavaDoc parentDir,
157         File JavaDoc[] sources,
158         char pathSeparator)
159         throws IOException JavaDoc {
160             
161         String JavaDoc stripPath = (parentDir != null) ? parentDir.getPath() : "";
162         if (stripPath.length() > 0 && !stripPath.endsWith(File.separator)) {
163             stripPath += File.separator;
164         }
165
166         ZipOutputStream JavaDoc out =
167             new ZipOutputStream JavaDoc(new FileOutputStream JavaDoc(zipFile));
168         out.setMethod(ZipOutputStream.DEFLATED);
169
170         try {
171             // something like an Ant directory scanner wouldn't hurt here
172
for (int i = 0; i < sources.length; i++) {
173                 if (!sources[i].exists()) {
174                     throw new IllegalArgumentException JavaDoc(
175                         "File or directory does not exist: " + sources[i]);
176                 }
177
178                 if (sources[i].isDirectory()) {
179                     zipDirectory(out, stripPath, sources[i], pathSeparator);
180                 } else {
181                     zipFile(out, stripPath, sources[i], pathSeparator);
182                 }
183             }
184         } finally {
185             out.close();
186         }
187     }
188
189     /**
190      * Uses code fragments from Jakarta-Ant, Copyright: Apache Software
191      * Foundation.
192      */

193     private static void zipDirectory(
194         ZipOutputStream JavaDoc out,
195         String JavaDoc stripPath,
196         File JavaDoc dir,
197         char pathSeparator)
198         throws IOException JavaDoc {
199
200         String JavaDoc[] entries = dir.list();
201
202         if (entries == null || entries.length == 0) {
203             return;
204         }
205
206         // recurse via entries
207
for (int i = 0; i < entries.length; i++) {
208             File JavaDoc file = new File JavaDoc(dir, entries[i]);
209             if (file.isDirectory()) {
210                 zipDirectory(out, stripPath, file, pathSeparator);
211             } else {
212                 zipFile(out, stripPath, file, pathSeparator);
213             }
214         }
215     }
216
217     /**
218      * Uses code fragments from Jakarta-Ant, Copyright: Apache Software
219      * Foundation.
220      */

221     private static void zipFile(
222         ZipOutputStream JavaDoc out,
223         String JavaDoc stripPath,
224         File JavaDoc file,
225         char pathSeparator)
226         throws IOException JavaDoc {
227         ZipEntry JavaDoc ze =
228             new ZipEntry JavaDoc(processPath(file.getPath(), stripPath, pathSeparator));
229         ze.setTime(file.lastModified());
230         out.putNextEntry(ze);
231
232         byte[] buffer = new byte[8 * 1024];
233         BufferedInputStream JavaDoc in =
234             new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(file), buffer.length);
235
236         try {
237             int count = 0;
238             while ((count = in.read(buffer, 0, buffer.length)) >= 0) {
239                 if (count != 0) {
240                     out.write(buffer, 0, count);
241                 }
242             }
243         } finally {
244             in.close();
245         }
246     }
247
248     private static String JavaDoc processPath(
249         String JavaDoc path,
250         String JavaDoc stripPath,
251         char pathSeparator) {
252         if (!path.startsWith(stripPath)) {
253             throw new IllegalArgumentException JavaDoc(
254                 "Invalid entry: "
255                     + path
256                     + "; expected to start with "
257                     + stripPath);
258         }
259
260         return path.substring(stripPath.length()).replace(
261             File.separatorChar,
262             pathSeparator);
263     }
264 }
265
Popular Tags