1 18 23 package org.apache.tools.ant.taskdefs.optional.jlink; 24 25 import java.io.BufferedInputStream ; 26 import java.io.File ; 27 import java.io.FileInputStream ; 28 import java.io.FileOutputStream ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.util.Enumeration ; 32 import java.util.Vector ; 33 import java.util.zip.CRC32 ; 34 import java.util.zip.Deflater ; 35 import java.util.zip.ZipEntry ; 36 import java.util.zip.ZipException ; 37 import java.util.zip.ZipFile ; 38 import java.util.zip.ZipOutputStream ; 39 40 44 public class jlink { 45 46 47 private String outfile = null; 48 49 private Vector mergefiles = new Vector (10); 50 51 private Vector addfiles = new Vector (10); 52 53 private boolean compression = false; 54 55 57 byte[] buffer = new byte[8192]; 58 59 61 64 public void setOutfile(String outfile) { 65 if (outfile == null) { 66 return; 67 } 68 this.outfile = outfile; 69 } 70 71 72 76 public void addMergeFile(String fileToMerge) { 77 if (fileToMerge == null) { 78 return; 79 } 80 mergefiles.addElement(fileToMerge); 81 } 82 83 84 87 public void addAddFile(String fileToAdd) { 88 if (fileToAdd == null) { 89 return; 90 } 91 addfiles.addElement(fileToAdd); 92 } 93 94 95 99 public void addMergeFiles(String [] filesToMerge) { 100 if (filesToMerge == null) { 101 return; 102 } 103 for (int i = 0; i < filesToMerge.length; i++) { 104 addMergeFile(filesToMerge[i]); 105 } 106 } 107 108 109 113 public void addAddFiles(String [] filesToAdd) { 114 if (filesToAdd == null) { 115 return; 116 } 117 for (int i = 0; i < filesToAdd.length; i++) { 118 addAddFile(filesToAdd[i]); 119 } 120 } 121 122 123 127 public void setCompression(boolean compress) { 128 this.compression = compress; 129 } 130 131 132 144 public void link() throws Exception { 145 ZipOutputStream output = new ZipOutputStream (new FileOutputStream (outfile)); 146 147 if (compression) { 148 output.setMethod(ZipOutputStream.DEFLATED); 149 output.setLevel(Deflater.DEFAULT_COMPRESSION); 150 } else { 151 output.setMethod(ZipOutputStream.STORED); 152 } 153 154 Enumeration merges = mergefiles.elements(); 155 156 while (merges.hasMoreElements()) { 157 String path = (String ) merges.nextElement(); 158 File f = new File (path); 159 160 if (f.getName().endsWith(".jar") || f.getName().endsWith(".zip")) { 161 mergeZipJarContents(output, f); 163 } else { 164 addAddFile(path); 167 } 168 } 169 170 Enumeration adds = addfiles.elements(); 171 172 while (adds.hasMoreElements()) { 173 String name = (String ) adds.nextElement(); 174 File f = new File (name); 175 176 if (f.isDirectory()) { 177 addDirContents(output, f, f.getName() + '/', compression); 179 } else { 180 addFile(output, f, "", compression); 181 } 182 } 183 if (output != null) { 184 try { 185 output.close(); 186 } catch (IOException ioe) { 187 } 189 } 190 } 191 192 193 197 public static void main(String [] args) { 198 if (args.length < 2) { 200 System.out.println("usage: jlink output input1 ... inputN"); 201 System.exit(1); 202 } 203 jlink linker = new jlink(); 204 205 linker.setOutfile(args[0]); 206 for (int i = 1; i < args.length; i++) { 209 linker.addMergeFile(args[i]); 210 } 211 try { 212 linker.link(); 213 } catch (Exception ex) { 214 System.err.print(ex.getMessage()); 215 } 216 } 217 218 219 223 private void mergeZipJarContents(ZipOutputStream output, File f) throws IOException { 224 if (!f.exists()) { 226 return; 227 } 228 ZipFile zipf = new ZipFile (f); 229 Enumeration entries = zipf.entries(); 230 231 while (entries.hasMoreElements()) { 232 ZipEntry inputEntry = (ZipEntry ) entries.nextElement(); 233 String inputEntryName = inputEntry.getName(); 237 int index = inputEntryName.indexOf("META-INF"); 238 239 if (index < 0) { 240 try { 242 output.putNextEntry(processEntry(zipf, inputEntry)); 243 } catch (ZipException ex) { 244 String mess = ex.getMessage(); 251 252 if (mess.indexOf("duplicate") >= 0) { 253 continue; 255 } else { 256 throw ex; 259 } 260 } 261 262 InputStream in = zipf.getInputStream(inputEntry); 263 int len = buffer.length; 264 int count = -1; 265 266 while ((count = in.read(buffer, 0, len)) > 0) { 267 output.write(buffer, 0, count); 268 } 269 in.close(); 270 output.closeEntry(); 271 } 272 } 273 zipf.close(); 274 } 275 276 277 280 private void addDirContents(ZipOutputStream output, File dir, String prefix, 281 boolean compress) throws IOException { 282 String [] contents = dir.list(); 283 284 for (int i = 0; i < contents.length; ++i) { 285 String name = contents[i]; 286 File file = new File (dir, name); 287 288 if (file.isDirectory()) { 289 addDirContents(output, file, prefix + name + '/', compress); 290 } else { 291 addFile(output, file, prefix, compress); 292 } 293 } 294 } 295 296 297 302 private String getEntryName(File file, String prefix) { 303 String name = file.getName(); 304 305 if (!name.endsWith(".class")) { 306 InputStream input = null; 308 try { 309 input = new FileInputStream (file); 310 String className = ClassNameReader.getClassName(input); 311 312 if (className != null) { 313 return className.replace('.', '/') + ".class"; 314 } 315 } catch (IOException ioe) { 316 } finally { 318 if (input != null) { 319 try { 320 input.close(); 321 } catch (IOException e) { 322 } 324 } 325 } 326 } 327 System.out.println("From " + file.getPath() + " and prefix " + prefix 328 + ", creating entry " + prefix + name); 329 return (prefix + name); 330 } 331 332 333 336 private void addFile(ZipOutputStream output, File file, String prefix, 337 boolean compress) throws IOException { 338 if (!file.exists()) { 340 return; 341 } 342 ZipEntry entry = new ZipEntry (getEntryName(file, prefix)); 343 344 entry.setTime(file.lastModified()); 345 entry.setSize(file.length()); 346 if (!compress) { 347 entry.setCrc(calcChecksum(file)); 348 } 349 FileInputStream input = new FileInputStream (file); 350 351 addToOutputStream(output, input, entry); 352 } 353 354 355 358 private void addToOutputStream(ZipOutputStream output, InputStream input, 359 ZipEntry ze) throws IOException { 360 try { 361 output.putNextEntry(ze); 362 } catch (ZipException zipEx) { 363 input.close(); 365 return; 366 } 367 368 int numBytes = -1; 369 370 while ((numBytes = input.read(buffer)) > 0) { 371 output.write(buffer, 0, numBytes); 372 } 373 output.closeEntry(); 374 input.close(); 375 } 376 377 378 383 private ZipEntry processEntry(ZipFile zip, ZipEntry inputEntry) { 384 396 String name = inputEntry.getName(); 397 398 if (!(inputEntry.isDirectory() || name.endsWith(".class"))) { 399 try { 400 InputStream input = zip.getInputStream(zip.getEntry(name)); 401 String className = ClassNameReader.getClassName(input); 402 403 input.close(); 404 if (className != null) { 405 name = className.replace('.', '/') + ".class"; 406 } 407 } catch (IOException ioe) { 408 } 410 } 411 ZipEntry outputEntry = new ZipEntry (name); 412 413 outputEntry.setTime(inputEntry.getTime()); 414 outputEntry.setExtra(inputEntry.getExtra()); 415 outputEntry.setComment(inputEntry.getComment()); 416 outputEntry.setTime(inputEntry.getTime()); 417 if (compression) { 418 outputEntry.setMethod(ZipEntry.DEFLATED); 419 } else { 421 outputEntry.setMethod(ZipEntry.STORED); 422 outputEntry.setCrc(inputEntry.getCrc()); 423 outputEntry.setSize(inputEntry.getSize()); 424 } 425 return outputEntry; 426 } 427 428 429 433 private long calcChecksum(File f) throws IOException { 434 BufferedInputStream in = new BufferedInputStream (new FileInputStream (f)); 435 436 return calcChecksum(in); 437 } 438 439 440 444 private long calcChecksum(InputStream in) throws IOException { 445 CRC32 crc = new CRC32 (); 446 int len = buffer.length; 447 int count = -1; 448 int haveRead = 0; 449 450 while ((count = in.read(buffer, 0, len)) > 0) { 451 haveRead += count; 452 crc.update(buffer, 0, count); 453 } 454 in.close(); 455 return crc.getValue(); 456 } 457 458 459 } 460 461 462 | Popular Tags |