1 22 package org.jboss.util.file; 23 24 import java.io.BufferedInputStream ; 25 import java.io.BufferedOutputStream ; 26 import java.io.File ; 27 import java.io.FileFilter ; 28 import java.io.FileInputStream ; 29 import java.io.FileNotFoundException ; 30 import java.io.FileOutputStream ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.io.OutputStream ; 34 import java.net.JarURLConnection ; 35 import java.net.URL ; 36 import java.net.URLConnection ; 37 import java.util.jar.JarInputStream ; 38 import java.util.jar.JarOutputStream ; 39 import java.util.jar.Manifest ; 40 import java.util.zip.ZipEntry ; 41 42 47 public final class JarUtils 48 { 49 52 private JarUtils() 53 { 54 } 55 56 69 public static void jar(OutputStream out, File src) throws IOException 70 { 71 jar(out, new File [] { src }, null, null, null); 72 } 73 74 87 public static void jar(OutputStream out, File [] src) throws IOException 88 { 89 jar(out, src, null, null, null); 90 } 91 92 109 public static void jar(OutputStream out, File [] src, FileFilter filter) 110 throws IOException 111 { 112 jar(out, src, filter, null, null); 113 } 114 115 134 public static void jar(OutputStream out, File [] src, FileFilter filter, 135 String prefix, Manifest man) throws IOException 136 { 137 138 for (int i = 0; i < src.length; i++) 139 { 140 if (!src[i].exists()) 141 { 142 throw new FileNotFoundException (src.toString()); 143 } 144 } 145 146 JarOutputStream jout; 147 if (man == null) 148 { 149 jout = new JarOutputStream (out); 150 } 151 else 152 { 153 jout = new JarOutputStream (out, man); 154 } 155 if (prefix != null && prefix.length() > 0 && !prefix.equals("/")) 156 { 157 if (prefix.charAt(0) == '/') 159 { 160 prefix = prefix.substring(1); 161 } 162 if (prefix.charAt(prefix.length() - 1) != '/') 164 { 165 prefix = prefix + "/"; 166 } 167 } 168 else 169 { 170 prefix = ""; 171 } 172 JarInfo info = new JarInfo(jout, filter); 173 for (int i = 0; i < src.length; i++) 174 { 175 jar(src[i], prefix, info); 176 } 177 jout.close(); 178 } 179 180 185 private static class JarInfo 186 { 187 public JarOutputStream out; 188 public FileFilter filter; 189 public byte[] buffer; 190 191 public JarInfo(JarOutputStream out, FileFilter filter) 192 { 193 this.out = out; 194 this.filter = filter; 195 buffer = new byte[1024]; 196 } 197 } 198 199 203 private static void jar(File src, String prefix, JarInfo info) 204 throws IOException 205 { 206 207 JarOutputStream jout = info.out; 208 if (src.isDirectory()) 209 { 210 prefix = prefix + src.getName() + "/"; 212 ZipEntry entry = new ZipEntry (prefix); 213 entry.setTime(src.lastModified()); 214 entry.setMethod(JarOutputStream.STORED); 215 entry.setSize(0L); 216 entry.setCrc(0L); 217 jout.putNextEntry(entry); 218 jout.closeEntry(); 219 220 File [] files = src.listFiles(info.filter); 222 for (int i = 0; i < files.length; i++) 223 { 224 jar(files[i], prefix, info); 225 } 226 } 227 else if (src.isFile()) 228 { 229 byte[] buffer = info.buffer; 231 232 ZipEntry entry = new ZipEntry (prefix + src.getName()); 234 entry.setTime(src.lastModified()); 235 jout.putNextEntry(entry); 236 237 FileInputStream in = new FileInputStream (src); 239 int len; 240 while ((len = in.read(buffer, 0, buffer.length)) != -1) 241 { 242 jout.write(buffer, 0, len); 243 } 244 in.close(); 245 jout.closeEntry(); 246 } 247 } 248 249 252 public static void unjar(InputStream in, File dest) throws IOException 253 { 254 if (!dest.exists()) 255 { 256 dest.mkdirs(); 257 } 258 if (!dest.isDirectory()) 259 { 260 throw new IOException ("Destination must be a directory."); 261 } 262 JarInputStream jin = new JarInputStream (in); 263 byte[] buffer = new byte[1024]; 264 265 ZipEntry entry = jin.getNextEntry(); 266 while (entry != null) 267 { 268 String fileName = entry.getName(); 269 if (fileName.charAt(fileName.length() - 1) == '/') 270 { 271 fileName = fileName.substring(0, fileName.length() - 1); 272 } 273 if (fileName.charAt(0) == '/') 274 { 275 fileName = fileName.substring(1); 276 } 277 if (File.separatorChar != '/') 278 { 279 fileName = fileName.replace('/', File.separatorChar); 280 } 281 File file = new File (dest, fileName); 282 if (entry.isDirectory()) 283 { 284 file.mkdirs(); 286 jin.closeEntry(); 287 } 288 else 289 { 290 File parent = file.getParentFile(); 292 if (parent != null && !parent.exists()) 293 { 294 parent.mkdirs(); 295 } 296 297 OutputStream out = new FileOutputStream (file); 299 int len = 0; 300 while ((len = jin.read(buffer, 0, buffer.length)) != -1) 301 { 302 out.write(buffer, 0, len); 303 } 304 out.flush(); 305 out.close(); 306 jin.closeEntry(); 307 file.setLastModified(entry.getTime()); 308 } 309 entry = jin.getNextEntry(); 310 } 311 314 Manifest mf = jin.getManifest(); 315 if (mf != null) 316 { 317 File file = new File (dest, "META-INF/MANIFEST.MF"); 318 File parent = file.getParentFile(); 319 if( parent.exists() == false ) 320 { 321 parent.mkdirs(); 322 } 323 OutputStream out = new FileOutputStream (file); 324 mf.write(out); 325 out.flush(); 326 out.close(); 327 } 328 jin.close(); 329 } 330 331 341 public static URL extractNestedJar(URL jarURL, File dest) 342 throws IOException 343 { 344 if( jarURL.getProtocol().equals("jar") == false ) 346 return jarURL; 347 348 String destPath = dest.getAbsolutePath(); 349 URLConnection urlConn = jarURL.openConnection(); 350 JarURLConnection jarConn = (JarURLConnection ) urlConn; 351 String parentArchiveName = jarConn.getJarFile().getName(); 353 int length = Math.min(destPath.length(), parentArchiveName.length()); 355 int n = 0; 356 while( n < length ) 357 { 358 char a = destPath.charAt(n); 359 char b = parentArchiveName.charAt(n); 360 if( a != b ) 361 break; 362 n ++; 363 } 364 parentArchiveName = parentArchiveName.substring(n); 366 367 File archiveDir = new File (dest, parentArchiveName+"-contents"); 368 if( archiveDir.exists() == false && archiveDir.mkdirs() == false ) 369 throw new IOException ("Failed to create contents directory for archive, path="+archiveDir.getAbsolutePath()); 370 String archiveName = jarConn.getEntryName(); 371 File archiveFile = new File (archiveDir, archiveName); 372 File archiveParentDir = archiveFile.getParentFile(); 373 if( archiveParentDir.exists() == false && archiveParentDir.mkdirs() == false ) 374 throw new IOException ("Failed to create parent directory for archive, path="+archiveParentDir.getAbsolutePath()); 375 InputStream archiveIS = jarConn.getInputStream(); 376 FileOutputStream fos = new FileOutputStream (archiveFile); 377 BufferedOutputStream bos = new BufferedOutputStream (fos); 378 byte[] buffer = new byte[4096]; 379 int read; 380 while( (read = archiveIS.read(buffer)) > 0 ) 381 { 382 bos.write(buffer, 0, read); 383 } 384 archiveIS.close(); 385 bos.close(); 386 387 return archiveFile.toURL(); 389 } 390 391 392 396 public static void main(String [] args) throws Exception 397 { 398 if (args.length == 0) 399 { 400 System.out.println("usage: <x or c> <jar-archive> <files...>"); 401 System.exit(0); 402 } 403 if (args[0].equals("x")) 404 { 405 BufferedInputStream in = new BufferedInputStream (new FileInputStream (args[1])); 406 File dest = new File (args[2]); 407 unjar(in, dest); 408 } 409 else if (args[0].equals("c")) 410 { 411 BufferedOutputStream out = new BufferedOutputStream (new FileOutputStream (args[1])); 412 File [] src = new File [args.length - 2]; 413 for (int i = 0; i < src.length; i++) 414 { 415 src[i] = new File (args[2 + i]); 416 } 417 jar(out, src); 418 } 419 else 420 { 421 System.out.println("Need x or c as first argument"); 422 } 423 } 424 } 425 | Popular Tags |