1 20 21 package com.izforge.izpack.compiler; 22 23 import java.io.File ; 24 import java.io.FileInputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.ObjectOutputStream ; 28 import java.io.OutputStream ; 29 import java.net.URL ; 30 import java.util.ArrayList ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.Properties ; 37 import java.util.Set ; 38 import java.util.zip.Deflater ; 39 import java.util.zip.ZipException ; 40 import java.util.zip.ZipInputStream ; 41 42 import net.n3.nanoxml.XMLElement; 43 44 51 import com.izforge.izpack.CustomData; 52 import com.izforge.izpack.GUIPrefs; 53 import com.izforge.izpack.Info; 54 import com.izforge.izpack.Pack; 55 import com.izforge.izpack.PackFile; 56 import com.izforge.izpack.Panel; 57 import com.izforge.izpack.compressor.PackCompressor; 58 import com.izforge.izpack.compressor.PackCompressorFactory; 59 61 68 public class Packager implements IPackager 69 { 70 71 72 public static final String SKELETON_SUBPATH = "lib/installer.jar"; 73 74 75 private File baseFile = null; 76 77 79 private com.izforge.izpack.util.JarOutputStream primaryJarStream; 80 81 82 private Info info = null; 83 84 85 private GUIPrefs guiPrefs = null; 86 87 88 private Properties variables = new Properties (); 89 90 91 private List panelList = new ArrayList (); 92 93 94 private List packsList = new ArrayList (); 95 96 97 private List langpackNameList = new ArrayList (); 98 99 100 private List customDataList = new ArrayList (); 101 102 103 private Map installerResourceURLMap = new HashMap (); 104 105 106 private Set includedJarURLs = new HashSet (); 107 108 109 private boolean packJarsSeparate = false; 110 111 112 private PackagerListener listener; 113 114 115 private PackCompressor compressor; 116 117 118 private HashMap alreadyWrittenFiles = new HashMap (); 119 121 public Packager() throws CompilerException 122 { 123 this("default"); 124 } 125 126 132 public Packager(String compr_format) throws CompilerException 133 { 134 this( compr_format, -1); 135 } 136 137 144 public Packager(String compr_format, int compr_level) throws CompilerException 145 { 146 compressor = PackCompressorFactory.get( compr_format); 147 compressor.setCompressionLevel(compr_level); 148 } 149 150 151 152 155 public void createInstaller(File primaryFile) throws Exception 156 { 157 String baseName = primaryFile.getName(); 159 if (baseName.endsWith(".jar")) 160 { 161 baseName = baseName.substring(0, baseName.length() - 4); 162 baseFile = new File (primaryFile.getParentFile(), baseName); 163 } 164 else 165 baseFile = primaryFile; 166 167 info.setInstallerBase(baseFile.getName()); 168 packJarsSeparate = (info.getWebDirURL() != null); 169 170 primaryJarStream = getJarOutputStream(baseFile.getName() + ".jar"); 172 173 sendStart(); 174 175 writeSkeletonInstaller(); 179 180 writeInstallerObject("info", info); 181 writeInstallerObject("vars", variables); 182 writeInstallerObject("GUIPrefs", guiPrefs); 183 writeInstallerObject("panelsOrder", panelList); 184 writeInstallerObject("customData", customDataList); 185 writeInstallerObject("langpacks.info", langpackNameList); 186 writeInstallerResources(); 187 writeIncludedJars(); 188 189 writePacks(); 191 192 primaryJarStream.closeAlways(); 198 199 sendStop(); 200 } 201 202 205 206 209 public PackagerListener getPackagerListener() 210 { 211 return listener; 212 } 213 216 public void setPackagerListener(PackagerListener listener) 217 { 218 this.listener = listener; 219 } 220 221 226 private void sendMsg(String job) 227 { 228 sendMsg(job, PackagerListener.MSG_INFO); 229 } 230 231 237 private void sendMsg(String job, int priority) 238 { 239 if (listener != null) listener.packagerMsg(job, priority); 240 } 241 242 243 private void sendStart() 244 { 245 if (listener != null) listener.packagerStart(); 246 } 247 248 249 private void sendStop() 250 { 251 if (listener != null) listener.packagerStop(); 252 } 253 254 257 258 261 public void setInfo(Info info) throws Exception 262 { 263 sendMsg("Setting the installer information", PackagerListener.MSG_VERBOSE); 264 this.info = info; 265 if( ! getCompressor().useStandardCompression() && 266 getCompressor().getDecoderMapperName() != null ) 267 { 268 this.info.setPackDecoderClassName(getCompressor().getDecoderMapperName()); 269 } 270 } 271 272 275 public void setGUIPrefs(GUIPrefs prefs) 276 { 277 sendMsg("Setting the GUI preferences", PackagerListener.MSG_VERBOSE); 278 guiPrefs = prefs; 279 } 280 281 284 public Properties getVariables() 285 { 286 return variables; 287 } 288 289 292 public void addPanelJar(Panel panel, URL jarURL) 293 { 294 panelList.add(panel); addJarContent(jarURL); } 298 299 302 public void addCustomJar(CustomData ca, URL url) 303 { 304 customDataList.add(ca); addJarContent(url); } 308 309 312 public void addPack(PackInfo pack) 313 { 314 packsList.add(pack); 315 } 316 317 320 public List getPacksList() 321 { 322 return packsList; 323 } 324 325 328 public void addLangPack(String iso3, URL xmlURL, URL flagURL) 329 { 330 sendMsg("Adding langpack: " + iso3, PackagerListener.MSG_VERBOSE); 331 langpackNameList.add(iso3); 334 addResource("flag." + iso3, flagURL); 335 installerResourceURLMap.put("langpacks/" + iso3 + ".xml", xmlURL); 336 } 337 338 341 public void addResource(String resId, URL url) 342 { 343 sendMsg("Adding resource: " + resId, PackagerListener.MSG_VERBOSE); 344 installerResourceURLMap.put("res/" + resId, url); 345 } 346 347 350 public void addNativeLibrary(String name, URL url) throws Exception 351 { 352 sendMsg("Adding native library: " + name, PackagerListener.MSG_VERBOSE); 353 installerResourceURLMap.put("native/" + name, url); 354 } 355 356 357 360 public void addJarContent(URL jarURL) 361 { 362 addJarContent(jarURL, null); 363 } 364 367 public void addJarContent(URL jarURL, List files) 368 { 369 Object [] cont = { jarURL, files }; 370 sendMsg("Adding content of jar: " + jarURL.getFile(), PackagerListener.MSG_VERBOSE); 371 includedJarURLs.add(cont); 372 } 373 374 377 public void addNativeUninstallerLibrary(CustomData data) 378 { 379 customDataList.add(data); 382 } 383 384 387 388 392 private void writeSkeletonInstaller() throws IOException 393 { 394 sendMsg("Copying the skeleton installer", PackagerListener.MSG_VERBOSE); 395 396 InputStream is = Packager.class.getResourceAsStream("/" + SKELETON_SUBPATH); 397 if (is == null) 398 { 399 File skeleton = new File (Compiler.IZPACK_HOME, SKELETON_SUBPATH); 400 is = new FileInputStream (skeleton); 401 } 402 ZipInputStream inJarStream = new ZipInputStream (is); 403 copyZip(inJarStream, primaryJarStream); 404 } 405 406 409 private void writeInstallerObject(String entryName, Object object) throws IOException 410 { 411 primaryJarStream.putNextEntry(new org.apache.tools.zip.ZipEntry(entryName)); 412 ObjectOutputStream out = new ObjectOutputStream (primaryJarStream); 413 out.writeObject(object); 414 out.flush(); 415 primaryJarStream.closeEntry(); 416 } 417 418 419 private void writeInstallerResources() throws IOException 420 { 421 sendMsg("Copying " + installerResourceURLMap.size() + " files into installer"); 422 423 Iterator i = installerResourceURLMap.keySet().iterator(); 424 while (i.hasNext()) 425 { 426 String name = (String ) i.next(); 427 InputStream in = ((URL ) installerResourceURLMap.get(name)).openStream(); 428 primaryJarStream.putNextEntry(new org.apache.tools.zip.ZipEntry(name)); 429 PackagerHelper.copyStream(in, primaryJarStream); 430 primaryJarStream.closeEntry(); 431 in.close(); 432 } 433 } 434 435 436 private void writeIncludedJars() throws IOException 437 { 438 sendMsg("Merging " + includedJarURLs.size() + " jars into installer"); 439 440 Iterator i = includedJarURLs.iterator(); 441 while (i.hasNext()) 442 { 443 Object [] current = (Object []) i.next(); 444 InputStream is = ((URL ) current[0]).openStream(); 445 ZipInputStream inJarStream = new ZipInputStream (is); 446 copyZip(inJarStream, primaryJarStream, (List ) current[1]); 447 } 448 } 449 450 453 private void writePacks() throws Exception 454 { 455 final int num = packsList.size(); 456 sendMsg("Writing " + num + " Pack" + (num > 1 ? "s" : "") + " into installer"); 457 458 Map storedFiles = new HashMap (); 460 461 464 int packNumber = 0; 465 Iterator packIter = packsList.iterator(); 466 while (packIter.hasNext()) 467 { 468 PackInfo packInfo = (PackInfo) packIter.next(); 469 Pack pack = packInfo.getPack(); 470 pack.nbytes = 0; 471 472 com.izforge.izpack.util.JarOutputStream packStream = primaryJarStream; 474 if (packJarsSeparate) 475 { 476 String name = baseFile.getName() + ".pack" + packNumber + ".jar"; 478 packStream = getJarOutputStream(name); 479 } 480 OutputStream comprStream = packStream; 481 482 sendMsg("Writing Pack " + packNumber + ": " + pack.name, PackagerListener.MSG_VERBOSE); 483 484 org.apache.tools.zip.ZipEntry entry = 486 new org.apache.tools.zip.ZipEntry("packs/pack" + packNumber); 487 if( ! compressor.useStandardCompression()) 488 { 489 entry.setMethod(org.apache.tools.zip.ZipEntry.STORED); 490 entry.setComment(compressor.getCompressionFormatSymbols()[0]); 491 packStream.putNextEntry(entry); 494 packStream.flush(); comprStream = compressor.getOutputStream(packStream); 496 } 497 else 498 { 499 int level = compressor.getCompressionLevel(); 500 if( level >= 0 && level < 10 ) 501 packStream.setLevel(level); 502 packStream.putNextEntry(entry); 503 packStream.flush(); } 505 506 ByteCountingOutputStream dos = new ByteCountingOutputStream(comprStream); 507 ObjectOutputStream objOut = new ObjectOutputStream (dos); 508 509 objOut.writeInt(packInfo.getPackFiles().size()); 511 512 Iterator iter = packInfo.getPackFiles().iterator(); 513 while (iter.hasNext()) 514 { 515 boolean addFile = !pack.loose; 516 PackFile pf = (PackFile) iter.next(); 517 File file = packInfo.getFile(pf); 518 519 long[] info = (long[]) storedFiles.get(file); 522 if (info != null && !packJarsSeparate) 523 { 524 pf.setPreviousPackFileRef((int) info[0], info[1]); 525 addFile = false; 526 } 527 528 objOut.writeObject(pf); objOut.flush(); 531 if (addFile && !pf.isDirectory()) 532 { 533 long pos = dos.getByteCount(); 535 FileInputStream inStream = new FileInputStream (file); 536 long bytesWritten = PackagerHelper.copyStream(inStream, objOut); 537 538 if (bytesWritten != pf.length()) 539 throw new IOException ("File size mismatch when reading " + file); 540 541 inStream.close(); 542 storedFiles.put(file, new long[] { packNumber, pos}); 543 } 544 545 pack.nbytes += pf.length(); 547 } 548 549 objOut.writeInt(packInfo.getParsables().size()); 551 iter = packInfo.getParsables().iterator(); 552 while (iter.hasNext()) 553 objOut.writeObject(iter.next()); 554 555 objOut.writeInt(packInfo.getExecutables().size()); 557 iter = packInfo.getExecutables().iterator(); 558 while (iter.hasNext()) 559 objOut.writeObject(iter.next()); 560 561 objOut.writeInt(packInfo.getUpdateChecks().size()); 563 iter = packInfo.getUpdateChecks().iterator(); 564 while (iter.hasNext()) 565 objOut.writeObject(iter.next()); 566 567 objOut.flush(); 569 if( ! compressor.useStandardCompression()) 570 { 571 comprStream.close(); 572 } 573 574 packStream.closeEntry(); 575 576 if (packJarsSeparate) packStream.closeAlways(); 578 579 packNumber++; 580 } 581 582 primaryJarStream.putNextEntry(new org.apache.tools.zip.ZipEntry("packs.info")); 584 ObjectOutputStream out = new ObjectOutputStream (primaryJarStream); 585 out.writeInt(packsList.size()); 586 587 Iterator i = packsList.iterator(); 588 while (i.hasNext()) 589 { 590 PackInfo pack = (PackInfo) i.next(); 591 out.writeObject(pack.getPack()); 592 } 593 out.flush(); 594 primaryJarStream.closeEntry(); 595 } 596 597 600 601 602 private com.izforge.izpack.util.JarOutputStream getJarOutputStream(String name) throws IOException 603 { 604 File file = new File (baseFile.getParentFile(), name); 605 sendMsg("Building installer jar: " + file.getAbsolutePath()); 606 607 com.izforge.izpack.util.JarOutputStream jar = 608 new com.izforge.izpack.util.JarOutputStream(file); 609 jar.setLevel(Deflater.BEST_COMPRESSION); 610 jar.setPreventClose(true); 613 return jar; 614 } 615 616 625 private void copyZip(ZipInputStream zin, org.apache.tools.zip.ZipOutputStream out) throws IOException 626 { 627 copyZip( zin, out, null ); 628 } 629 630 639 private void copyZip(ZipInputStream zin, org.apache.tools.zip.ZipOutputStream out, 640 List files) 641 throws IOException 642 { 643 java.util.zip.ZipEntry zentry; 644 if( ! alreadyWrittenFiles.containsKey( out )) 645 alreadyWrittenFiles.put(out, new HashSet ()); 646 HashSet currentSet = (HashSet ) alreadyWrittenFiles.get(out); 647 while ((zentry = zin.getNextEntry()) != null) 648 { 649 String currentName = zentry.getName(); 650 String testName = currentName.replace('/', '.'); 651 testName = testName.replace('\\', '.'); 652 if( files != null ) 653 { 654 Iterator i = files.iterator(); 655 boolean founded = false; 656 while( i.hasNext()) 657 { String doInclude = (String ) i.next(); 659 if( testName.matches( doInclude ) ) 660 { 661 founded = true; 662 break; 663 } 664 } 665 if( ! founded ) 666 continue; 667 } 668 if( currentSet.contains(currentName)) 669 continue; 670 try 671 { 672 out.putNextEntry(new org.apache.tools.zip.ZipEntry(currentName)); 673 PackagerHelper.copyStream(zin, out); 674 out.closeEntry(); 675 zin.closeEntry(); 676 currentSet.add(currentName); 677 } 678 catch (ZipException x) 679 { 680 } 684 } 685 } 686 687 690 public PackCompressor getCompressor() 691 { 692 return compressor; 693 } 694 695 public void initPackCompressor(String compr_format, int compr_level) throws CompilerException 696 { 697 compressor = PackCompressorFactory.get( compr_format); 698 compressor.setCompressionLevel(compr_level); 699 } 700 701 public void addConfigurationInformation(XMLElement data) 702 { 703 705 } 706 } 707 | Popular Tags |