1 18 package com.izforge.izpack.installer; 19 20 import java.io.BufferedOutputStream ; 21 import java.io.EOFException ; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.ObjectInputStream ; 28 import java.io.PrintWriter ; 29 import java.util.ArrayList ; 30 import java.util.Enumeration ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Properties ; 36 import java.util.Stack ; 37 import java.util.TreeSet ; 38 import java.util.zip.ZipEntry ; 39 import java.util.zip.ZipInputStream ; 40 import java.util.zip.ZipOutputStream ; 41 42 import org.apache.regexp.RE; 43 import org.apache.regexp.RECompiler; 44 import org.apache.regexp.RESyntaxException; 45 46 import com.izforge.izpack.ExecutableFile; 47 import com.izforge.izpack.LocaleDatabase; 48 import com.izforge.izpack.Pack; 49 import com.izforge.izpack.PackFile; 50 import com.izforge.izpack.ParsableFile; 51 import com.izforge.izpack.UpdateCheck; 52 import com.izforge.izpack.XPackFile; 53 import com.izforge.izpack.event.InstallerListener; 54 import com.izforge.izpack.installer.AutomatedInstallData; 55 import com.izforge.izpack.installer.InstallerFrame; 56 import com.izforge.izpack.installer.IzPanel; 57 import com.izforge.izpack.installer.ResourceManager; 58 import com.izforge.izpack.installer.ScriptParser; 59 import com.izforge.izpack.installer.UninstallData; 60 import com.izforge.izpack.io.FileSpanningInputStream; 61 import com.izforge.izpack.io.FileSpanningOutputStream; 62 import com.izforge.izpack.io.VolumeNotFoundException; 63 import com.izforge.izpack.panels.NextMediaDialog; 64 import com.izforge.izpack.util.AbstractUIHandler; 65 import com.izforge.izpack.util.AbstractUIProgressHandler; 66 import com.izforge.izpack.util.Debug; 67 import com.izforge.izpack.util.FileExecutor; 68 import com.izforge.izpack.util.IoHelper; 69 import com.izforge.izpack.util.OsConstraint; 70 import com.izforge.izpack.util.VariableSubstitutor; 71 72 77 public class MultiVolumeUnpacker implements IUnpacker 78 { 79 80 81 private AutomatedInstallData idata; 82 83 84 private AbstractUIProgressHandler handler; 85 86 87 private UninstallData udata; 88 89 90 private VariableSubstitutor vs; 91 92 93 private static HashMap instances = new HashMap (); 94 95 96 private File absolute_installpath; 97 98 99 private LocaleDatabase langpack = null; 100 101 102 private static boolean interruptDesired = false; 103 104 105 private static boolean discardInterrupt = false; 106 107 108 private static final String LANG_FILE_NAME = "packsLang.xml"; 109 110 public static final String ALIVE = "alive"; 111 112 public static final String INTERRUPT = "doInterrupt"; 113 114 public static final String INTERRUPTED = "interruppted"; 115 116 117 private boolean result = true; 118 119 125 public MultiVolumeUnpacker(AutomatedInstallData idata, AbstractUIProgressHandler handler) 126 { 127 try 128 { 129 String resource = LANG_FILE_NAME + "_" + idata.localeISO3; 130 this.langpack = new LocaleDatabase(ResourceManager.getInstance().getInputStream( 131 resource)); 132 } 133 catch (Throwable exception) 134 {} 135 136 this.idata = idata; 137 this.handler = handler; 138 139 vs = new VariableSubstitutor(idata.getVariables()); 141 } 142 143 148 public static HashMap getRunningInstances() 149 { 150 synchronized (instances) 151 { return (HashMap ) (instances.clone()); 154 } 155 } 156 157 160 private void addToInstances() 161 { 162 synchronized (instances) 163 { 164 instances.put(this, ALIVE); 165 } 166 } 167 168 171 private void removeFromInstances() 172 { 173 synchronized (instances) 174 { 175 instances.remove(this); 176 } 177 } 178 179 184 private static void setInterruptAll() 185 { 186 synchronized (instances) 187 { 188 Iterator iter = instances.keySet().iterator(); 189 while (iter.hasNext()) 190 { 191 Object key = iter.next(); 192 if (instances.get(key).equals(ALIVE)) 193 { 194 instances.put(key, INTERRUPT); 195 } 196 } 197 setInterruptDesired(true); 200 } 201 } 202 203 211 public static boolean interruptAll(long waitTime) 212 { 213 long t0 = System.currentTimeMillis(); 214 if (isDiscardInterrupt()) return (false); 215 setInterruptAll(); 216 while (!isInterruptReady()) 217 { 218 if (System.currentTimeMillis() - t0 > waitTime) return (true); 219 try 220 { 221 Thread.sleep(100); 222 } 223 catch (InterruptedException e) 224 {} 225 } 226 return (true); 227 } 228 229 private static boolean isInterruptReady() 230 { 231 synchronized (instances) 232 { 233 Iterator iter = instances.keySet().iterator(); 234 while (iter.hasNext()) 235 { 236 Object key = iter.next(); 237 if (!instances.get(key).equals(INTERRUPTED)) return (false); 238 } 239 return (true); 240 } 241 242 } 243 244 250 private boolean performInterrupted() 251 { 252 synchronized (instances) 253 { 254 Object doIt = instances.get(this); 255 if (doIt != null && (doIt.equals(INTERRUPT) || doIt.equals(INTERRUPTED))) 256 { 257 instances.put(this, INTERRUPTED); 258 this.result = false; 259 return (true); 260 } 261 return (false); 262 } 263 } 264 265 270 private boolean shouldInterrupt() 271 { 272 synchronized (instances) 273 { 274 Object doIt = instances.get(this); 275 if (doIt != null && (doIt.equals(INTERRUPT) || doIt.equals(INTERRUPTED))) { return (true); } 276 return (false); 277 } 278 279 } 280 281 protected File enterNextMediaMessage(String volumename) 282 { 283 Debug.trace("Enter next media: " + volumename); 284 StackTraceElement [] el = (new Exception ()).getStackTrace(); 285 for (int i = 0; i < el.length; i++) 286 { 287 StackTraceElement element = el[i]; 288 Debug.trace(element.toString()); 289 } 290 291 File nextvolume = new File (volumename); 292 NextMediaDialog nmd = null; 293 while (!nextvolume.exists()) 294 { 295 if ((this.handler != null) && (this.handler instanceof IzPanel)) 296 { 297 InstallerFrame installframe = ((IzPanel) this.handler).getInstallerFrame(); 298 nmd = new NextMediaDialog(installframe, idata, volumename); 299 } 300 else 301 { 302 nmd = new NextMediaDialog(null, idata, volumename); 303 } 304 nmd.setVisible(true); 305 String nextmediainput = nmd.getNextMedia(); 306 if (nextmediainput != null) 307 { 308 nextvolume = new File (nextmediainput); 309 } 310 else 311 { 312 Debug.trace("Input from NextMediaDialog was null"); 313 nextvolume = new File (volumename); 314 } 315 } 316 return nextvolume; 317 } 318 319 320 public void run() 321 { 322 addToInstances(); 323 try 324 { 325 FileOutputStream out = null; 328 ArrayList parsables = new ArrayList (); 329 ArrayList executables = new ArrayList (); 330 ArrayList updatechecks = new ArrayList (); 331 List packs = idata.selectedPacks; 332 int npacks = packs.size(); 333 Debug.trace("Unpacker starting"); 334 handler.startAction("Unpacking", npacks); 335 udata = UninstallData.getInstance(); 336 List [] customActions = getCustomActions(); 338 informListeners(customActions, InstallerListener.BEFORE_PACKS, idata, new Integer ( 340 npacks), handler); 341 packs = idata.selectedPacks; 343 npacks = packs.size(); 344 if (npacks == 0) 345 { 346 if (performInterrupted()) 347 { return; 349 } 350 351 informListeners(customActions, InstallerListener.AFTER_PACKS, idata, handler, null); 353 if (performInterrupted()) 354 { return; 356 } 357 358 handler.stopAction(); 360 return; 361 } 362 InputStream in = MultiVolumeUnpacker.class 363 .getResourceAsStream(FileSpanningOutputStream.VOLUMES_INFO); 364 ObjectInputStream metadataobj = new ObjectInputStream (in); 366 int volumes = metadataobj.readInt(); 368 String volumename = metadataobj.readUTF(); 369 Debug.trace("Reading from " + volumes + " volumes with basename " + volumename + " "); 370 metadataobj.close(); 371 String mediadirectory = MultiVolumeInstaller.getMediadirectory(); 372 if ((mediadirectory == null) || (mediadirectory.length() <= 0)) 373 { 374 Debug.trace("Mediadirectory wasn't set."); 375 mediadirectory = System.getProperty("java.io.tmpdir"); } 378 Debug.trace("Using mediadirectory = " + mediadirectory); 379 File volume = new File (mediadirectory + File.separator + volumename); 380 if (!volume.exists()) 381 { 382 volume = enterNextMediaMessage(volume.getAbsolutePath()); 383 } 384 FileSpanningInputStream fin = new FileSpanningInputStream(volume, volumes); 385 386 for (int i = 0; i < npacks; i++) 388 { 389 int n = idata.allPacks.indexOf(packs.get(i)); 391 392 in = MultiVolumeUnpacker.class.getResourceAsStream("/packs/pack" + n); 393 394 informListeners(customActions, InstallerListener.BEFORE_PACK, packs.get(i), 396 new Integer (npacks), handler); 397 ObjectInputStream objIn = new ObjectInputStream (in); 399 int nfiles = objIn.readInt(); 401 402 final Pack pack = ((Pack) packs.get(i)); 404 String stepname = pack.name; if (langpack != null && !(pack.id == null || "".equals(pack.id))) 407 { 408 409 final String name = langpack.getString(pack.id); 410 if (name != null && !"".equals(name)) 411 { 412 stepname = name; 413 } 414 } 415 handler.nextStep(stepname, i + 1, nfiles); 416 for (int j = 0; j < nfiles; j++) 417 { 418 XPackFile pf = (XPackFile) objIn.readObject(); 420 421 if (OsConstraint.oneMatchesCurrentSystem(pf.osConstraints())) 422 { 423 String path = IoHelper.translatePath(pf.getTargetPath(), vs); 425 File pathFile = new File (path); 426 File dest = pathFile; 427 if (!pf.isDirectory()) dest = pathFile.getParentFile(); 428 429 if (!dest.exists()) 430 { 431 List fileListeners = customActions[customActions.length - 1]; 435 if (fileListeners != null && fileListeners.size() > 0) 436 mkDirsWithEnhancement(dest, pf, customActions); 437 else 438 { 440 if (!dest.mkdirs()) 441 { 442 handler.emitError("Error creating directories", 443 "Could not create directory\n" + dest.getPath()); 444 handler.stopAction(); 445 this.result = false; 446 return; 447 } 448 } 449 } 450 451 if (pf.isDirectory()) continue; 452 453 informListeners(customActions, InstallerListener.BEFORE_FILE, pathFile, pf, 455 null); 456 udata.addFile(path); 458 459 handler.progress(j, path); 460 461 if ((pathFile.exists()) && (pf.override() != PackFile.OVERRIDE_TRUE)) 465 { 466 boolean overwritefile = false; 467 468 if (pf.override() != PackFile.OVERRIDE_FALSE) 470 { 471 if (pf.override() == PackFile.OVERRIDE_TRUE) 472 { 473 overwritefile = true; 474 } 475 else if (pf.override() == PackFile.OVERRIDE_UPDATE) 476 { 477 overwritefile = (pathFile.lastModified() < pf.lastModified()); 486 } 487 else 488 { 489 int def_choice = -1; 490 491 if (pf.override() == PackFile.OVERRIDE_ASK_FALSE) 492 def_choice = AbstractUIHandler.ANSWER_NO; 493 if (pf.override() == PackFile.OVERRIDE_ASK_TRUE) 494 def_choice = AbstractUIHandler.ANSWER_YES; 495 496 int answer = handler.askQuestion(idata.langpack 497 .getString("InstallPanel.overwrite.title") 498 + " - " + pathFile.getName(), idata.langpack 499 .getString("InstallPanel.overwrite.question") 500 + pathFile.getAbsolutePath(), 501 AbstractUIHandler.CHOICES_YES_NO, def_choice); 502 503 overwritefile = (answer == AbstractUIHandler.ANSWER_YES); 504 } 505 506 } 507 508 if (!overwritefile) 509 { 510 if (!pf.isBackReference() && !((Pack) packs.get(i)).loose) 511 { 512 } 514 continue; 515 } 516 517 } 518 519 out = new FileOutputStream (pathFile); 521 byte[] buffer = new byte[5120]; 522 long bytesCopied = 0; 523 InputStream pis = fin; 525 526 if (((Pack) packs.get(i)).loose) 527 { 528 pis = new FileInputStream (pf.sourcePath); 529 } 530 531 long fileposition = pf.getArchivefileposition(); 534 535 while (fin.getFilepointer() < fileposition) 536 { 537 Debug.trace("Skipping bytes to get to file " + pathFile.getName() 539 + " (" + fin.getFilepointer() + "<" + fileposition 540 + ") target is: " + (fileposition - fin.getFilepointer())); 541 try 542 { 543 fin.skip(fileposition - fin.getFilepointer()); 544 break; 545 } 546 catch (VolumeNotFoundException vnfe) 547 { 548 File nextmedia = enterNextMediaMessage(vnfe.getVolumename()); 549 fin.setVolumename(nextmedia.getAbsolutePath()); 550 } 551 } 552 553 if (fin.getFilepointer() > fileposition) 554 { 555 Debug.trace("Error, can't access file in pack."); 556 } 557 558 while (bytesCopied < pf.length()) 559 { 560 try 561 { 562 if (performInterrupted()) 563 { out.close(); 565 if (pis != objIn) pis.close(); 566 return; 567 } 568 int maxBytes = (int) Math.min(pf.length() - bytesCopied, 569 buffer.length); 570 571 int bytesInBuffer = pis.read(buffer, 0, maxBytes); 572 if (bytesInBuffer == -1) 573 { 574 Debug.trace("Unexpected end of stream (installer corrupted?)"); 575 throw new IOException ( 576 "Unexpected end of stream (installer corrupted?)"); 577 } 578 579 out.write(buffer, 0, bytesInBuffer); 580 581 bytesCopied += bytesInBuffer; 582 } 583 catch (VolumeNotFoundException vnfe) 584 { 585 File nextmedia = enterNextMediaMessage(vnfe.getVolumename()); 586 fin.setVolumename(nextmedia.getAbsolutePath()); 587 } 588 } 589 out.close(); 591 593 if (pf.lastModified() >= 0) pathFile.setLastModified(pf.lastModified()); 595 informListeners(customActions, InstallerListener.AFTER_FILE, pathFile, pf, 597 null); 598 } 599 else 600 { 601 if (!pf.isBackReference()) 602 { 603 } 605 } 606 } 607 int numParsables = objIn.readInt(); 609 Debug.trace("Looking for parsables"); 610 for (int k = 0; k < numParsables; k++) 611 { 612 ParsableFile pf = null; 613 while (true) 614 { 615 try 616 { 617 pf = (ParsableFile) objIn.readObject(); 618 break; 619 } 620 catch (VolumeNotFoundException vnfe) 621 { 622 File nextmedia = enterNextMediaMessage(vnfe.getVolumename()); 623 fin.setVolumename(nextmedia.getAbsolutePath()); 624 } 625 catch (EOFException eofe) 626 { 627 File nextmedia = enterNextMediaMessage(""); 628 fin.setVolumename(nextmedia.getAbsolutePath()); 629 } 630 } 631 pf.path = IoHelper.translatePath(pf.path, vs); 632 Debug.trace("Found parsable: " + pf.path); 633 parsables.add(pf); 634 } 635 636 int numExecutables = objIn.readInt(); 638 Debug.trace("Looking for executables..."); 639 for (int k = 0; k < numExecutables; k++) 640 { 641 ExecutableFile ef = (ExecutableFile) objIn.readObject(); 642 643 ef.path = IoHelper.translatePath(ef.path, vs); 644 if (null != ef.argList && !ef.argList.isEmpty()) 645 { 646 String arg = null; 647 for (int j = 0; j < ef.argList.size(); j++) 648 { 649 arg = (String ) ef.argList.get(j); 650 arg = IoHelper.translatePath(arg, vs); 651 ef.argList.set(j, arg); 652 } 653 } 654 Debug.trace("Found executable: " + ef.path); 655 executables.add(ef); 656 if (ef.executionStage == ExecutableFile.UNINSTALL) 657 { 658 udata.addExecutable(ef); 659 } 660 } 661 handleAdditionalUninstallData(udata, customActions); 663 664 int numUpdateChecks = objIn.readInt(); 666 Debug.trace("Looking for updatechecks"); 667 for (int k = 0; k < numUpdateChecks; k++) 668 { 669 UpdateCheck uc = (UpdateCheck) objIn.readObject(); 670 Debug.trace("found updatecheck"); 671 updatechecks.add(uc); 672 } 673 674 676 if (performInterrupted()) 677 { return; 679 } 680 681 informListeners(customActions, InstallerListener.AFTER_PACK, packs.get(i), 683 new Integer (i), handler); 684 } 685 Debug.trace("Trying to parse files"); 686 ScriptParser parser = new ScriptParser(parsables, vs); 688 parser.parseFiles(); 689 Debug.trace("parsed files"); 690 if (performInterrupted()) 691 { return; 693 } 694 Debug.trace("Trying to execute files"); 695 FileExecutor executor = new FileExecutor(executables); 697 if (executor.executeFiles(ExecutableFile.POSTINSTALL, handler) != 0) 698 { 699 handler.emitError("File execution failed", "The installation was not completed"); 700 this.result = false; 701 Debug.trace("File execution failed"); 702 } 703 704 if (performInterrupted()) 705 { return; 707 } 708 Debug.trace("Create uninstaller"); 709 putUninstaller(); 711 Debug.trace("Uninstaller created"); 712 Debug.trace("Perform updateChecks"); 714 performUpdateChecks(updatechecks); 715 Debug.trace("updatechecks performed."); 716 if (performInterrupted()) 717 { return; 719 } 720 721 informListeners(customActions, InstallerListener.AFTER_PACKS, idata, handler, null); 723 if (performInterrupted()) 724 { return; 726 } 727 this.writeConfigInformation(); 728 handler.stopAction(); 730 Debug.trace("Installation complete"); 731 } 732 catch (Exception err) 733 { 734 handler.stopAction(); 736 handler.emitError("An error occured", err.toString()); 737 err.printStackTrace(); 738 Debug.trace("Error while installing: " + err.toString()); 739 this.result = false; 740 } 741 finally 742 { 743 removeFromInstances(); 744 } 745 } 746 747 protected void writeConfigInformation() 748 { 749 Properties installerproperties = idata.getVariables(); 751 Enumeration installerpropertieskeys = installerproperties.keys(); 752 try 753 { 754 String installpath = idata.getVariable("INSTALL_PATH"); 755 PrintWriter pw = new PrintWriter (new FileOutputStream (installpath + File.separator 756 + "installer.properties")); 757 pw.println("# Installer properties, written by MultiVolumeUnpacker."); 758 while (installerpropertieskeys.hasMoreElements()) 759 { 760 String key = (String ) installerpropertieskeys.nextElement(); 761 if (key.startsWith("SYSTEM_")) 762 { 763 continue; 765 } 766 else if (key.startsWith("password_")) 767 { 768 continue; 770 } 771 pw.println(key + "=" + installerproperties.getProperty(key)); 772 } 773 pw.flush(); 774 pw.close(); 775 } 776 catch (Exception e) 777 { 778 Debug.trace("Error while writing config information in MultiVolumeUnpacker: " 779 + e.getMessage()); 780 } 781 } 782 783 788 public boolean getResult() 789 { 790 return this.result; 791 } 792 793 796 private void performUpdateChecks(ArrayList updatechecks) 797 { 798 ArrayList include_patterns = new ArrayList (); 799 ArrayList exclude_patterns = new ArrayList (); 800 801 RECompiler recompiler = new RECompiler(); 802 803 this.absolute_installpath = new File (idata.getInstallPath()).getAbsoluteFile(); 804 805 for (Iterator iter = updatechecks.iterator(); iter.hasNext();) 807 { 808 UpdateCheck uc = (UpdateCheck) iter.next(); 809 810 if (uc.includesList != null) 811 include_patterns.addAll(preparePatterns(uc.includesList, recompiler)); 812 813 if (uc.excludesList != null) 814 exclude_patterns.addAll(preparePatterns(uc.excludesList, recompiler)); 815 } 816 817 if (include_patterns.size() == 0) return; 819 820 823 TreeSet installed_files = new TreeSet (); 825 826 for (Iterator if_it = this.udata.getFilesList().iterator(); if_it.hasNext();) 827 { 828 String fname = (String ) if_it.next(); 829 830 File f = new File (fname); 831 832 if (!f.isAbsolute()) 833 { 834 f = new File (this.absolute_installpath, fname); 835 } 836 837 installed_files.add(f.getAbsolutePath()); 838 } 839 840 Stack scanstack = new Stack (); 845 846 ArrayList files_to_delete = new ArrayList (); 848 849 try 850 { 851 scanstack.add(absolute_installpath); 852 853 while (!scanstack.empty()) 854 { 855 File f = (File ) scanstack.pop(); 856 857 File [] files = f.listFiles(); 858 859 if (files == null) { throw new IOException (f.getPath() + "is not a directory!"); } 860 861 for (int i = 0; i < files.length; i++) 862 { 863 File newf = files[i]; 864 865 String newfname = newf.getPath(); 866 867 if (installed_files.contains(newfname)) continue; 869 870 if (fileMatchesOnePattern(newfname, include_patterns) 871 && (!fileMatchesOnePattern(newfname, exclude_patterns))) 872 { 873 files_to_delete.add(newf); 874 } 875 876 if (newf.isDirectory()) 877 { 878 scanstack.push(newf); 879 } 880 881 } 882 } 883 } 884 catch (IOException e) 885 { 886 this.handler.emitError("error while performing update checks", e.toString()); 887 } 888 889 for (Iterator f_it = files_to_delete.iterator(); f_it.hasNext();) 890 { 891 File f = (File ) f_it.next(); 892 893 if (!f.isDirectory()) 894 { 896 this.handler.emitNotification("deleting " + f.getPath()); 897 f.delete(); 898 } 899 900 } 901 902 } 903 904 910 private boolean fileMatchesOnePattern(String filename, ArrayList patterns) 911 { 912 for (Iterator inc_it = patterns.iterator(); inc_it.hasNext();) 914 { 915 RE pattern = (RE) inc_it.next(); 916 917 if (pattern.match(filename)) { return true; } 918 } 919 920 return false; 921 } 922 923 929 private List preparePatterns(ArrayList list, RECompiler recompiler) 930 { 931 ArrayList result = new ArrayList (); 932 933 for (Iterator iter = list.iterator(); iter.hasNext();) 934 { 935 String element = (String ) iter.next(); 936 937 if ((element != null) && (element.length() > 0)) 938 { 939 element = this.vs.substitute(element, "plain"); 941 942 File f = new File (element); 944 945 if (!f.isAbsolute()) 949 { 950 element = new File (this.absolute_installpath, element).toString(); 951 } 952 953 StringBuffer element_re = new StringBuffer (); 961 962 int lookahead = -1; 963 964 int pos = 0; 965 966 while (pos < element.length()) 967 { 968 char c; 969 970 if (lookahead != -1) 971 { 972 c = (char) lookahead; 973 lookahead = -1; 974 } 975 else 976 c = element.charAt(pos++); 977 978 switch (c) 979 { 980 case '/': { 981 element_re.append(File.separator); 982 break; 983 } 984 case '\\': 986 case '.': { 987 element_re.append("\\"); 988 element_re.append(c); 989 break; 990 } 991 case '*': { 992 if (pos == element.length()) 993 { 994 element_re.append("[^").append(File.separator).append("]*"); 995 break; 996 } 997 998 lookahead = element.charAt(pos++); 999 1000 if (lookahead == '*') 1002 { 1003 element_re.append(".*"); 1004 lookahead = -1; 1006 } 1007 else 1008 { 1009 element_re.append("[^").append(File.separator).append("]*"); 1010 } 1012 break; 1013 } 1014 default: { 1015 element_re.append(c); 1016 break; 1017 } 1018 } 1020 } 1021 1022 element_re.append('$'); 1024 1025 try 1027 { 1028 result.add(new RE(recompiler.compile(element_re.toString()))); 1029 } 1030 catch (RESyntaxException e) 1031 { 1032 this.handler.emitNotification("internal error: pattern \"" + element 1033 + "\" produced invalid RE \"" + f.getPath() + "\""); 1034 } 1035 1036 } 1037 } 1038 1039 return result; 1040 } 1041 1042 1047 private void putUninstaller() throws Exception 1048 { 1049 InputStream [] in = new InputStream [2]; 1052 in[0] = MultiVolumeUnpacker.class.getResourceAsStream("/res/IzPack.uninstaller"); 1053 if (in[0] == null) return; 1054 in[1] = MultiVolumeUnpacker.class.getResourceAsStream("/res/IzPack.uninstaller-ext"); 1057 1058 String dest = IoHelper.translatePath("$INSTALL_PATH", vs) + File.separator + "Uninstaller"; 1060 String jar = dest + File.separator + idata.info.getUninstallerName(); 1061 File pathMaker = new File (dest); 1062 pathMaker.mkdirs(); 1063 1064 udata.setUninstallerJarFilename(jar); 1066 udata.setUninstallerPath(dest); 1067 1068 FileOutputStream out = new FileOutputStream (jar); 1070 BufferedOutputStream bos = new BufferedOutputStream (out); 1072 ZipOutputStream outJar = new ZipOutputStream (bos); 1073 idata.uninstallOutJar = outJar; 1074 outJar.setLevel(9); 1075 udata.addFile(jar); 1076 1077 HashSet doubles = new HashSet (); 1079 1080 for (int i = 0; i < in.length; ++i) 1081 { 1082 if (in[i] == null) continue; 1083 ZipInputStream inRes = new ZipInputStream (in[i]); 1084 ZipEntry zentry = inRes.getNextEntry(); 1085 while (zentry != null) 1086 { 1087 if (!doubles.contains(zentry.getName())) 1089 { 1090 doubles.add(zentry.getName()); 1091 outJar.putNextEntry(new ZipEntry (zentry.getName())); 1092 1093 int unc = inRes.read(); 1095 while (unc != -1) 1096 { 1097 outJar.write(unc); 1098 unc = inRes.read(); 1099 } 1100 1101 inRes.closeEntry(); 1103 outJar.closeEntry(); 1104 } 1105 zentry = inRes.getNextEntry(); 1106 } 1107 inRes.close(); 1108 } 1109 1110 InputStream in2 = MultiVolumeUnpacker.class.getResourceAsStream("/langpacks/" 1112 + idata.localeISO3 + ".xml"); 1113 outJar.putNextEntry(new ZipEntry ("langpack.xml")); 1114 int read = in2.read(); 1115 while (read != -1) 1116 { 1117 outJar.write(read); 1118 read = in2.read(); 1119 } 1120 outJar.closeEntry(); 1121 } 1122 1123 1125 1134 private void informListeners(List [] customActions, int action, Object firstParam, 1135 Object secondParam, Object thirdParam) throws Exception 1136 { 1137 List listener = null; 1138 switch (action) 1140 { 1141 case InstallerListener.BEFORE_FILE: 1142 case InstallerListener.AFTER_FILE: 1143 case InstallerListener.BEFORE_DIR: 1144 case InstallerListener.AFTER_DIR: 1145 listener = customActions[customActions.length - 1]; 1146 break; 1147 default: 1148 listener = customActions[0]; 1149 break; 1150 } 1151 if (listener == null) return; 1152 Iterator iter = listener.iterator(); 1154 while (iter.hasNext()) 1155 { 1156 if (shouldInterrupt()) return; 1157 InstallerListener il = (InstallerListener) iter.next(); 1158 switch (action) 1159 { 1160 case InstallerListener.BEFORE_FILE: 1161 il.beforeFile((File ) firstParam, (PackFile) secondParam); 1162 break; 1163 case InstallerListener.AFTER_FILE: 1164 il.afterFile((File ) firstParam, (PackFile) secondParam); 1165 break; 1166 case InstallerListener.BEFORE_DIR: 1167 il.beforeDir((File ) firstParam, (PackFile) secondParam); 1168 break; 1169 case InstallerListener.AFTER_DIR: 1170 il.afterDir((File ) firstParam, (PackFile) secondParam); 1171 break; 1172 case InstallerListener.BEFORE_PACK: 1173 il.beforePack((Pack) firstParam, (Integer ) secondParam, 1174 (AbstractUIProgressHandler) thirdParam); 1175 break; 1176 case InstallerListener.AFTER_PACK: 1177 il.afterPack((Pack) firstParam, (Integer ) secondParam, 1178 (AbstractUIProgressHandler) thirdParam); 1179 break; 1180 case InstallerListener.BEFORE_PACKS: 1181 il.beforePacks((AutomatedInstallData) firstParam, (Integer ) secondParam, 1182 (AbstractUIProgressHandler) thirdParam); 1183 break; 1184 case InstallerListener.AFTER_PACKS: 1185 il.afterPacks((AutomatedInstallData) firstParam, 1186 (AbstractUIProgressHandler) secondParam); 1187 break; 1188 1189 } 1190 } 1191 } 1192 1193 1199 private List [] getCustomActions() 1200 { 1201 String [] listenerNames = AutomatedInstallData.CUSTOM_ACTION_TYPES; 1202 List [] retval = new List [listenerNames.length + 1]; 1203 int i; 1204 for (i = 0; i < listenerNames.length; ++i) 1205 { 1206 retval[i] = (List ) idata.customData.get(listenerNames[i]); 1207 if (retval[i] == null) 1208 retval[i] = new ArrayList (); 1210 } 1211 if (retval[AutomatedInstallData.INSTALLER_LISTENER_INDEX].size() > 0) 1212 { i = retval.length - 1; retval[i] = new ArrayList (); 1217 Iterator iter = ((List ) retval[AutomatedInstallData.INSTALLER_LISTENER_INDEX]) 1218 .iterator(); 1219 while (iter.hasNext()) 1220 { 1221 InstallerListener li = (InstallerListener) iter.next(); 1224 if (li.isFileListener()) retval[i].add(li); 1225 } 1226 1227 } 1228 return (retval); 1229 } 1230 1231 1237 private void handleAdditionalUninstallData(UninstallData udata, List [] customData) 1238 { 1239 udata.addAdditionalData("__uninstallLibs__", 1241 customData[AutomatedInstallData.UNINSTALLER_LIBS_INDEX]); 1242 udata.addAdditionalData("uninstallerListeners", 1244 customData[AutomatedInstallData.UNINSTALLER_LISTENER_INDEX]); 1245 udata.addAdditionalData("uninstallerJars", 1247 customData[AutomatedInstallData.UNINSTALLER_JARS_INDEX]); 1248 } 1249 1250 1261 1262 private boolean mkDirsWithEnhancement(File dest, PackFile pf, List [] customActions) 1263 throws Exception 1264 { 1265 String path = "unknown"; 1266 if (dest != null) path = dest.getAbsolutePath(); 1267 if (dest != null && !dest.exists() && dest.getParentFile() != null) 1268 { 1269 if (dest.getParentFile().exists()) 1270 informListeners(customActions, InstallerListener.BEFORE_DIR, dest, pf, null); 1271 if (!dest.mkdir()) 1272 { 1273 mkDirsWithEnhancement(dest.getParentFile(), pf, customActions); 1274 if (!dest.mkdir()) dest = null; 1275 } 1276 informListeners(customActions, InstallerListener.AFTER_DIR, dest, pf, null); 1277 } 1278 if (dest == null) 1279 { 1280 handler.emitError("Error creating directories", "Could not create directory\n" + path); 1281 handler.stopAction(); 1282 return (false); 1283 } 1284 return (true); 1285 } 1286 1287 1289 1294 public static synchronized boolean isDiscardInterrupt() 1295 { 1296 return discardInterrupt; 1297 } 1298 1299 1304 public static synchronized void setDiscardInterrupt(boolean di) 1305 { 1306 discardInterrupt = di; 1307 setInterruptDesired(false); 1308 } 1309 1310 1315 public static boolean isInterruptDesired() 1316 { 1317 return interruptDesired; 1318 } 1319 1320 1323 private static void setInterruptDesired(boolean interruptDesired) 1324 { 1325 MultiVolumeUnpacker.interruptDesired = interruptDesired; 1326 } 1327} | Popular Tags |