001 /**
002 *
003 * Copyright 2004 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.deployment.util;
018
019 import java.io.BufferedOutputStream;
020 import java.io.File;
021 import java.io.FileInputStream;
022 import java.io.FileOutputStream;
023 import java.io.IOException;
024 import java.io.InputStream;
025 import java.io.InputStreamReader;
026 import java.io.OutputStream;
027 import java.io.Reader;
028 import java.io.Writer;
029 import java.net.MalformedURLException;
030 import java.net.URL;
031 import java.util.Collection;
032 import java.util.Collections;
033 import java.util.Enumeration;
034 import java.util.LinkedList;
035 import java.util.jar.JarFile;
036 import java.util.jar.JarOutputStream;
037 import java.util.jar.Manifest;
038 import java.util.zip.ZipEntry;
039 import java.util.zip.ZipFile;
040
041 /**
042 * @version $Rev: 399178 $ $Date: 2006-05-02 23:57:29 -0700 (Tue, 02 May 2006) $
043 */
044 public final class DeploymentUtil {
045 private DeploymentUtil() {
046 }
047
048 public static final File DUMMY_JAR_FILE;
049 static {
050 try {
051 DUMMY_JAR_FILE = DeploymentUtil.createTempFile();
052 new JarOutputStream(new FileOutputStream(DeploymentUtil.DUMMY_JAR_FILE), new Manifest()).close();
053 } catch (IOException e) {
054 throw new ExceptionInInitializerError(e);
055 }
056 }
057
058 // be careful to clean up the temp directory
059 public static File createTempDir() throws IOException {
060 File tempDir = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
061 tempDir.delete();
062 tempDir.mkdirs();
063 return tempDir;
064 }
065
066 // be careful to clean up the temp file... we tell the vm to delete this on exit
067 // but VMs can't be trusted to acutally delete the file
068 public static File createTempFile() throws IOException {
069 File tempFile = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
070 tempFile.deleteOnExit();
071 return tempFile;
072 }
073
074 public static void copyFile(File source, File destination) throws IOException {
075 File destinationDir = destination.getParentFile();
076 if (false == destinationDir.exists() && false == destinationDir.mkdirs()) {
077 throw new java.io.IOException("Cannot create directory : " + destinationDir);
078 }
079
080 InputStream in = null;
081 OutputStream out = null;
082 try {
083 in = new FileInputStream(source);
084 out = new FileOutputStream(destination);
085 writeAll(in, out);
086 } finally {
087 close(in);
088 close(out);
089 }
090 }
091
092 private static void writeAll(InputStream in, OutputStream out) throws IOException {
093 byte[] buffer = new byte[4096];
094 int count;
095 while ((count = in.read(buffer)) > 0) {
096 out.write(buffer, 0, count);
097 }
098 out.flush();
099 }
100 public static File toTempFile(JarFile jarFile, String path) throws IOException {
101 return toTempFile(createJarURL(jarFile, path));
102 }
103
104 public static File toTempFile(URL url) throws IOException {
105 InputStream in = null;
106 OutputStream out = null;
107 try {
108 in = url.openStream();
109
110 File tempFile = createTempFile();
111 out = new FileOutputStream(tempFile);
112
113 writeAll(in, out);
114 return tempFile;
115 } finally {
116 close(out);
117 close(in);
118 }
119 }
120
121 public static String readAll(URL url) throws IOException {
122 Reader reader = null;
123 try {
124 reader = new InputStreamReader(url.openStream());
125
126 char[] buffer = new char[4000];
127 StringBuffer out = new StringBuffer();
128 for(int count = reader.read(buffer); count >= 0; count = reader.read(buffer)) {
129 out.append(buffer, 0, count);
130 }
131 return out.toString();
132 } finally {
133 close(reader);
134 }
135 }
136
137 public static File toFile(JarFile jarFile) throws IOException {
138 if (jarFile instanceof UnpackedJarFile) {
139 return ((UnpackedJarFile) jarFile).getBaseDir();
140 } else {
141 throw new IOException("jarFile is not a directory");
142 }
143 }
144
145 // be careful with this method as it can leave a temp lying around
146 public static File toFile(JarFile jarFile, String path) throws IOException {
147 if (jarFile instanceof UnpackedJarFile) {
148 File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
149 File file = new File(baseDir, path);
150 if (!file.isFile()) {
151 throw new IOException("No such file: " + file.getAbsolutePath());
152 }
153 return file;
154 } else {
155 String urlString = "jar:" + new File(jarFile.getName()).toURL() + "!/" + path;
156 return toTempFile(new URL(urlString));
157 }
158 }
159
160 public static URL createJarURL(JarFile jarFile, String path) throws MalformedURLException {
161 if (jarFile instanceof NestedJarFile) {
162 NestedJarFile nestedJar = (NestedJarFile) jarFile;
163 if (nestedJar.isUnpacked()) {
164 JarFile baseJar = nestedJar.getBaseJar();
165 String basePath = nestedJar.getBasePath();
166 if (baseJar instanceof UnpackedJarFile) {
167 File baseDir = ((UnpackedJarFile) baseJar).getBaseDir();
168 baseDir = new File(baseDir, basePath);
169 return new File(baseDir, path).toURL();
170 }
171 }
172 }
173
174 if (jarFile instanceof UnpackedJarFile) {
175 File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
176 return new File(baseDir, path).toURL();
177 } else {
178 String urlString = "jar:" + new File(jarFile.getName()).toURL() + "!/" + path;
179 return new URL(urlString);
180 }
181 }
182
183 public static JarFile createJarFile(File jarFile) throws IOException {
184 if (jarFile.isDirectory()) {
185 return new UnpackedJarFile(jarFile);
186 } else {
187 return new JarFile(jarFile);
188 }
189 }
190
191 public static void copyToPackedJar(JarFile inputJar, File outputFile) throws IOException {
192 if (inputJar.getClass() == JarFile.class) {
193 // this is a plain old jar... nothign special
194 copyFile(new File(inputJar.getName()), outputFile);
195 } else if (inputJar instanceof NestedJarFile && ((NestedJarFile)inputJar).isPacked()) {
196 NestedJarFile nestedJarFile = (NestedJarFile)inputJar;
197 JarFile baseJar = nestedJarFile.getBaseJar();
198 String basePath = nestedJarFile.getBasePath();
199 if (baseJar instanceof UnpackedJarFile) {
200 // our target jar is just a file in upacked jar (a plain old directory)... now
201 // we just need to find where it is and copy it to the outptu
202 copyFile(((UnpackedJarFile)baseJar).getFile(basePath), outputFile);
203 } else {
204 // out target is just a plain old jar file directly accessabel from the file system
205 copyFile(new File(baseJar.getName()), outputFile);
206 }
207 } else {
208 // copy out the module contents to a standalone jar file (entry by entry)
209 JarOutputStream out = null;
210 try {
211 out = new JarOutputStream(new FileOutputStream(outputFile));
212 byte[] buffer = new byte[4096];
213 Enumeration entries = inputJar.entries();
214 while (entries.hasMoreElements()) {
215 ZipEntry entry = (ZipEntry) entries.nextElement();
216 InputStream in = inputJar.getInputStream(entry);
217 try {
218 out.putNextEntry(new ZipEntry(entry.getName()));
219 try {
220 int count;
221 while ((count = in.read(buffer)) > 0) {
222 out.write(buffer, 0, count);
223 }
224 } finally {
225 out.closeEntry();
226 }
227 } finally {
228 close(in);
229 }
230 }
231 } finally {
232 close(out);
233 }
234 }
235 }
236
237 public static void jarDirectory(File sourceDirecotry, File destinationFile) throws IOException {
238 JarFile inputJar = new UnpackedJarFile(sourceDirecotry);
239 try {
240 copyToPackedJar(inputJar, destinationFile);
241 } finally {
242 close(inputJar);
243 }
244 }
245
246 public static void unzipToDirectory(ZipFile zipFile, File destDir) throws IOException {
247 Enumeration entries = zipFile.entries();
248 try {
249 while (entries.hasMoreElements()) {
250 ZipEntry entry = (ZipEntry) entries.nextElement();
251 if (entry.isDirectory()) {
252 File dir = new File(destDir, entry.getName());
253 boolean success = dir.mkdirs();
254 if (!success) {
255 throw new IOException("Cannot create directory " + dir.getAbsolutePath());
256 }
257 } else {
258 File file = new File(destDir, entry.getName());
259 OutputStream out = null;
260 InputStream in = null;
261 try {
262 out = new BufferedOutputStream(new FileOutputStream(file));
263 in = zipFile.getInputStream(entry);
264 writeAll(in, out);
265 } finally {
266 if (null != out) {
267 out.close();
268 }
269 if (null != in) {
270 in.close();
271 }
272 }
273 }
274 }
275 } finally {
276 zipFile.close();
277 }
278 }
279
280
281 public static boolean recursiveDelete(File root, Collection unableToDeleteCollection) {
282 if (root == null) {
283 return true;
284 }
285
286 if (root.isDirectory()) {
287 File[] files = root.listFiles();
288 if (files != null) {
289 for (int i = 0; i < files.length; i++) {
290 File file = files[i];
291 if (file.isDirectory()) {
292 recursiveDelete(file);
293 } else {
294 if (!file.delete() && unableToDeleteCollection != null) {
295 unableToDeleteCollection.add(file);
296 }
297 }
298 }
299 }
300 }
301 return root.delete();
302 }
303
304 public static boolean recursiveDelete(File root) {
305 return recursiveDelete(root,null);
306 }
307
308 public static Collection listRecursiveFiles(File file) {
309 LinkedList list = new LinkedList();
310 listRecursiveFiles(file, list);
311 return Collections.unmodifiableCollection(list);
312 }
313
314 public static void listRecursiveFiles(File file, Collection collection) {
315 File[] files = file.listFiles();
316 if ( null == files ) {
317 return;
318 }
319 for (int i = 0; i < files.length; i++) {
320 collection.add(files[i]);
321 if (files[i].isDirectory()) {
322 listRecursiveFiles(files[i], collection);
323 }
324 }
325 }
326
327 public static void flush(OutputStream thing) {
328 if (thing != null) {
329 try {
330 thing.flush();
331 } catch(Exception ignored) {
332 }
333 }
334 }
335
336 public static void flush(Writer thing) {
337 if (thing != null) {
338 try {
339 thing.flush();
340 } catch(Exception ignored) {
341 }
342 }
343 }
344
345 public static void close(JarFile thing) {
346 if (thing != null) {
347 try {
348 thing.close();
349 } catch(Exception ignored) {
350 }
351 }
352 }
353
354 public static void close(InputStream thing) {
355 if (thing != null) {
356 try {
357 thing.close();
358 } catch(Exception ignored) {
359 }
360 }
361 }
362
363 public static void close(OutputStream thing) {
364 if (thing != null) {
365 try {
366 thing.close();
367 } catch(Exception ignored) {
368 }
369 }
370 }
371
372 public static void close(Reader thing) {
373 if (thing != null) {
374 try {
375 thing.close();
376 } catch(Exception ignored) {
377 }
378 }
379 }
380
381 public static void close(Writer thing) {
382 if (thing != null) {
383 try {
384 thing.close();
385 } catch(Exception ignored) {
386 }
387 }
388 }
389
390 public static final class EmptyInputStream extends InputStream {
391 public int read() {
392 return -1;
393 }
394
395 public int read(byte b[]) {
396 return -1;
397 }
398
399 public int read(byte b[], int off, int len) {
400 return -1;
401 }
402
403 public long skip(long n) {
404 return 0;
405 }
406
407 public int available() {
408 return 0;
409 }
410
411 public void close() {
412 }
413
414 public synchronized void mark(int readlimit) {
415 }
416
417 public synchronized void reset() {
418 }
419
420 public boolean markSupported() {
421 return false;
422 }
423 }
424 }