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 }