View Javadoc

1   /**
2    *
3    * Copyright 2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.geronimo.deployment.util;
18  
19  import java.io.BufferedOutputStream;
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.FileOutputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.InputStreamReader;
26  import java.io.OutputStream;
27  import java.io.Reader;
28  import java.io.Writer;
29  import java.net.MalformedURLException;
30  import java.net.URL;
31  import java.util.Collection;
32  import java.util.Collections;
33  import java.util.Enumeration;
34  import java.util.LinkedList;
35  import java.util.jar.JarFile;
36  import java.util.jar.JarOutputStream;
37  import java.util.jar.Manifest;
38  import java.util.zip.ZipEntry;
39  import java.util.zip.ZipFile;
40  
41  /**
42   * @version $Rev: 399178 $ $Date: 2006-05-02 23:57:29 -0700 (Tue, 02 May 2006) $
43   */
44  public final class DeploymentUtil {
45      private DeploymentUtil() {
46      }
47  
48      public static final File DUMMY_JAR_FILE;
49      static {
50          try {
51              DUMMY_JAR_FILE = DeploymentUtil.createTempFile();
52              new JarOutputStream(new FileOutputStream(DeploymentUtil.DUMMY_JAR_FILE), new Manifest()).close();
53          } catch (IOException e) {
54              throw new ExceptionInInitializerError(e);
55          }
56      }
57  
58      // be careful to clean up the temp directory
59      public static File createTempDir() throws IOException {
60          File tempDir = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
61          tempDir.delete();
62          tempDir.mkdirs();
63          return tempDir;
64      }
65  
66      // be careful to clean up the temp file... we tell the vm to delete this on exit
67      // but VMs can't be trusted to acutally delete the file
68      public static File createTempFile() throws IOException {
69          File tempFile = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
70          tempFile.deleteOnExit();
71          return tempFile;
72      }
73  
74      public static void copyFile(File source, File destination) throws IOException {
75          File destinationDir = destination.getParentFile();
76          if (false == destinationDir.exists() && false == destinationDir.mkdirs()) {
77              throw new java.io.IOException("Cannot create directory : " + destinationDir);
78          }
79          
80          InputStream in = null;
81          OutputStream out = null;
82          try {
83              in = new FileInputStream(source);
84              out = new FileOutputStream(destination);
85              writeAll(in, out);
86          } finally {
87              close(in);
88              close(out);
89          }
90      }
91  
92      private static void writeAll(InputStream in, OutputStream out) throws IOException {
93          byte[] buffer = new byte[4096];
94          int count;
95          while ((count = in.read(buffer)) > 0) {
96              out.write(buffer, 0, count);
97          }
98          out.flush();
99      }
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 }