1 25 26 package com.izforge.izpack.compiler; 27 28 import java.io.BufferedInputStream ; 29 import java.io.BufferedOutputStream ; 30 import java.io.File ; 31 import java.io.FileNotFoundException ; 32 import java.io.FileInputStream ; 33 import java.io.FileOutputStream ; 34 import java.io.IOException ; 35 import java.io.InputStream ; 36 import java.net.MalformedURLException ; 37 import java.net.URI ; 38 import java.net.URL ; 39 import java.net.URLClassLoader ; 40 import java.util.ArrayList ; 41 import java.util.Date ; 42 import java.util.Enumeration ; 43 import java.util.HashMap ; 44 import java.util.Iterator ; 45 import java.util.List ; 46 import java.util.Map ; 47 import java.util.Properties ; 48 import java.util.Set ; 49 import java.util.StringTokenizer ; 50 import java.util.TreeMap ; 51 import java.util.Vector ; 52 import java.util.jar.JarInputStream ; 53 import java.util.zip.ZipEntry ; 54 import java.util.zip.ZipInputStream ; 55 56 import org.apache.tools.ant.DirectoryScanner; 57 58 import com.izforge.izpack.CustomData; 59 import com.izforge.izpack.ExecutableFile; 60 import com.izforge.izpack.GUIPrefs; 61 import com.izforge.izpack.Info; 62 import com.izforge.izpack.PackFile; 63 import com.izforge.izpack.Panel; 64 import com.izforge.izpack.ParsableFile; 65 import com.izforge.izpack.UpdateCheck; 66 import com.izforge.izpack.compiler.Compiler.CmdlinePackagerListener; 67 import com.izforge.izpack.event.CompilerListener; 68 import com.izforge.izpack.util.Debug; 69 import com.izforge.izpack.util.OsConstraint; 70 import com.izforge.izpack.util.VariableSubstitutor; 71 72 import net.n3.nanoxml.IXMLReader; 73 import net.n3.nanoxml.NonValidator; 74 import net.n3.nanoxml.StdXMLBuilder; 75 import net.n3.nanoxml.StdXMLParser; 76 import net.n3.nanoxml.StdXMLReader; 77 import net.n3.nanoxml.XMLElement; 78 79 87 public class CompilerConfig extends Thread 88 { 89 90 public final static String VERSION = "1.0"; 91 92 93 public final static String STANDARD = "standard"; 94 95 96 public final static String WEB = "web"; 97 98 99 private static boolean YES = true; 100 101 102 private static boolean NO = false; 103 104 private final static String IZ_TEST_FILE = "ShellLink.dll"; 105 106 private final static String IZ_TEST_SUBDIR = "bin" + File.separator + "native" + File.separator 107 + "izpack"; 108 109 110 private String filename; 111 112 private String installText; 113 114 protected String basedir; 115 116 117 private Compiler compiler; 118 119 122 protected List compilerListeners = new ArrayList (); 123 124 128 public static void setIzpackHome(String izHome) 129 { 130 Compiler.setIzpackHome(izHome); 131 } 132 133 142 public CompilerConfig(String filename, String basedir, String kind, String output) throws CompilerException 143 { 144 this(filename, basedir, kind, output, (PackagerListener) null); 145 } 146 156 public CompilerConfig(String filename, String basedir, String kind, String output, PackagerListener listener) 157 throws CompilerException 158 { 159 this(filename,basedir,kind,output, "default", listener); 160 } 161 162 170 public CompilerConfig(String filename, String base, String kind, String output, String compr_format, 171 PackagerListener listener) throws CompilerException 172 { 173 this(filename,base,kind,output, compr_format,listener, (String ) null); 174 } 175 176 185 public CompilerConfig(String basedir, String kind, String output, PackagerListener listener, 186 String installText) throws CompilerException 187 { 188 this((String ) null, basedir, kind, output, "default", listener, installText); 189 } 190 201 public CompilerConfig(String filename, String basedir, String kind, String output, String compr_format, 202 PackagerListener listener, String installText) throws CompilerException 203 { 204 this( filename, basedir, kind, output, compr_format, -1, listener, installText); 205 } 206 207 218 public CompilerConfig(String filename, String basedir, String kind, String output, String compr_format, 219 int compr_level, PackagerListener listener, String installText) throws CompilerException 220 { 221 this.filename = filename; 222 this.installText = installText; 223 this.basedir = basedir; 224 this.compiler = new Compiler (basedir, kind, output, compr_format, compr_level); 225 compiler.setPackagerListener(listener); 226 } 227 228 229 230 238 public boolean addProperty(String name, String value) 239 { 240 return compiler.addProperty(name, value); 241 } 242 243 247 public Compiler getCompiler() 248 { 249 return compiler; 250 } 251 252 255 public PackagerListener getPackagerListener() 256 { 257 return compiler.getPackagerListener(); 258 } 259 260 261 public void compile() 262 { 263 start(); 264 } 265 266 267 public void run() 268 { 269 try 270 { 271 executeCompiler(); 272 } 273 catch (CompilerException ce) 274 { 275 System.out.println(ce.getMessage() + "\n"); 276 } 277 catch (Exception e) 278 { 279 if (Debug.stackTracing()) 280 { 281 e.printStackTrace(); 282 } 283 else 284 { 285 System.out.println("ERROR: " + e.getMessage()); 286 } 287 } 288 } 289 290 295 public void executeCompiler() throws Exception 296 { 297 File base = new File (basedir).getAbsoluteFile(); 300 if (!base.canRead() || !base.isDirectory()) 301 throw new CompilerException("Invalid base directory: " + base); 302 303 compiler.setProperty("basedir", base.toString()); 305 306 XMLElement data = getXMLTree(); 308 loadPackagingInformation(data); 310 311 addCustomListeners(data); 313 314 substituteProperties(data); 316 317 addVariables(data); 319 addInfo(data); 320 addGUIPrefs(data); 321 addLangpacks(data); 322 addResources(data); 323 addNativeLibraries(data); 324 addJars(data); 325 addPanels(data); 326 addPacks(data); 327 328 compiler.createInstaller(); 330 } 331 332 private void loadPackagingInformation(XMLElement data) throws CompilerException 333 { 334 notifyCompilerListener("loadPackager", CompilerListener.BEGIN, data); 335 XMLElement root = data.getFirstChildNamed("packaging"); 337 String packagerclassname = "com.izforge.izpack.compiler.Packager"; 338 String unpackerclassname = "com.izforge.izpack.installer.Unpacker"; 339 XMLElement packager = null; 340 if (root != null){ 341 packager = root.getFirstChildNamed("packager"); 342 343 if (packager != null){ 344 packagerclassname = requireAttribute(packager, "class"); 345 } 346 347 XMLElement unpacker = root.getFirstChildNamed("unpacker"); 348 349 if (unpacker != null){ 350 unpackerclassname = requireAttribute(unpacker, "class"); 351 } 352 } 353 compiler.initPackager(packagerclassname); 354 if (packager != null){ 355 XMLElement options = packager.getFirstChildNamed("options"); 356 if (options != null){ 357 compiler.getPackager().addConfigurationInformation(options); 358 } 359 } 360 compiler.addProperty("UNPACKER_CLASS", unpackerclassname); 361 notifyCompilerListener("loadPackager", CompilerListener.END, data); 362 } 363 364 public boolean wasSuccessful() 365 { 366 return compiler.wasSuccessful(); 367 } 368 369 375 protected void addGUIPrefs(XMLElement data) throws CompilerException 376 { 377 notifyCompilerListener("addGUIPrefs", CompilerListener.BEGIN, data); 378 XMLElement gp = data.getFirstChildNamed("guiprefs"); 380 GUIPrefs prefs = new GUIPrefs(); 381 if (gp != null) 382 { 383 prefs.resizable = requireYesNoAttribute(gp, "resizable"); 384 prefs.width = requireIntAttribute(gp, "width"); 385 prefs.height = requireIntAttribute(gp, "height"); 386 387 Iterator it = gp.getChildrenNamed("laf").iterator(); 389 while (it.hasNext()) 390 { 391 XMLElement laf = (XMLElement) it.next(); 392 String lafName = requireAttribute(laf, "name"); 393 requireChildNamed(laf, "os"); 394 395 Iterator oit = laf.getChildrenNamed("os").iterator(); 396 while (oit.hasNext()) 397 { 398 XMLElement os = (XMLElement) oit.next(); 399 String osName = requireAttribute(os, "family"); 400 prefs.lookAndFeelMapping.put(osName, lafName); 401 } 402 403 Iterator pit = laf.getChildrenNamed("param").iterator(); 404 Map params = new TreeMap (); 405 while (pit.hasNext()) 406 { 407 XMLElement param = (XMLElement) pit.next(); 408 String name = requireAttribute(param, "name"); 409 String value = requireAttribute(param, "value"); 410 params.put(name, value); 411 } 412 prefs.lookAndFeelParams.put(lafName, params); 413 } 414 it = gp.getChildrenNamed("modifier").iterator(); 416 while (it.hasNext()) 417 { 418 XMLElement curentModifier = (XMLElement) it.next(); 419 String key = requireAttribute(curentModifier, "key"); 420 String value = requireAttribute(curentModifier, "value"); 421 prefs.modifier.put(key, value); 422 423 } 424 HashMap lafMap = new HashMap (); 427 lafMap.put("liquid", "liquidlnf.jar"); 428 lafMap.put("kunststoff", "kunststoff.jar"); 429 lafMap.put("metouia", "metouia.jar"); 430 lafMap.put("looks", "looks.jar"); 431 432 Iterator kit = prefs.lookAndFeelMapping.keySet().iterator(); 438 while (kit.hasNext()) 439 { 440 String lafName = (String ) prefs.lookAndFeelMapping.get(kit.next()); 441 String lafJarName = (String ) lafMap.get(lafName); 442 if (lafJarName == null) parseError(gp, "Unrecognized Look and Feel: " + lafName); 443 444 URL lafJarURL = findIzPackResource("lib/" + lafJarName, "Look and Feel Jar file", 445 gp); 446 compiler.addJarContent(lafJarURL); 447 } 448 } 449 compiler.setGUIPrefs(prefs); 450 notifyCompilerListener("addGUIPrefs", CompilerListener.END, data); 451 } 452 453 458 protected void addJars(XMLElement data) throws Exception 459 { 460 notifyCompilerListener("addJars", CompilerListener.BEGIN, data); 461 Iterator iter = data.getChildrenNamed("jar").iterator(); 462 while (iter.hasNext()) 463 { 464 XMLElement el = (XMLElement) iter.next(); 465 String src = requireAttribute(el, "src"); 466 URL url = findProjectResource(src, "Jar file", el); 467 compiler.addJarContent(url); 468 String stage = el.getAttribute("stage"); 477 if (stage != null 478 && ("both".equalsIgnoreCase(stage) || "uninstall".equalsIgnoreCase(stage))) 479 { 480 CustomData ca = new CustomData(null, getContainedFilePaths(url), null, 481 CustomData.UNINSTALLER_JAR); 482 compiler.addCustomJar(ca, url); 483 } 484 } 485 notifyCompilerListener("addJars", CompilerListener.END, data); 486 } 487 488 493 protected void addNativeLibraries(XMLElement data) throws Exception 494 { 495 boolean needAddOns = false; 496 notifyCompilerListener("addNativeLibraries", CompilerListener.BEGIN, data); 497 Iterator iter = data.getChildrenNamed("native").iterator(); 498 while (iter.hasNext()) 499 { 500 XMLElement el = (XMLElement) iter.next(); 501 String type = requireAttribute(el, "type"); 502 String name = requireAttribute(el, "name"); 503 String path = "bin/native/" + type + "/" + name; 504 URL url = findIzPackResource(path, "Native Library", el); 505 compiler.addNativeLibrary(name, url); 506 String stage = el.getAttribute("stage"); 515 List constraints = OsConstraint.getOsList(el); 516 if (stage != null 517 && ("both".equalsIgnoreCase(stage) || "uninstall".equalsIgnoreCase(stage))) 518 { 519 ArrayList al = new ArrayList (); 520 al.add(name); 521 CustomData cad = new CustomData(null, al, constraints, CustomData.UNINSTALLER_LIB); 522 compiler.addNativeUninstallerLibrary(cad); 523 needAddOns = true; 524 } 525 526 } 527 if (needAddOns) 528 { 529 XMLElement root = requireChildNamed(data, "info"); 531 XMLElement uninstallInfo = root.getFirstChildNamed("uninstaller"); 532 if (validateYesNoAttribute(uninstallInfo, "write", YES)) 533 { 534 URL url = findIzPackResource("lib/uninstaller-ext.jar", "Uninstaller extensions", 535 root); 536 compiler.addResource("IzPack.uninstaller-ext", url); 537 } 538 539 } 540 notifyCompilerListener("addNativeLibraries", CompilerListener.END, data); 541 } 542 543 548 protected void addPacks(XMLElement data) throws CompilerException 549 { 550 notifyCompilerListener("addPacks", CompilerListener.BEGIN, data); 551 XMLElement root = requireChildNamed(data, "packs"); 553 554 Vector packElements = root.getChildrenNamed("pack"); 556 if (packElements.isEmpty()) parseError(root, "<packs> requires a <pack>"); 557 558 File baseDir = new File (basedir); 559 560 Iterator packIter = packElements.iterator(); 561 while (packIter.hasNext()) 562 { 563 XMLElement el = (XMLElement) packIter.next(); 564 565 String name = requireAttribute(el, "name"); 567 String id = el.getAttribute("id"); 568 569 boolean loose = "true".equalsIgnoreCase(el.getAttribute("loose", "false")); 570 String description = requireChildNamed(el, "description").getContent(); 571 boolean required = requireYesNoAttribute(el, "required"); 572 String group = el.getAttribute("group"); 573 String installGroups = el.getAttribute("installGroups"); 574 String excludeGroup = el.getAttribute("excludeGroup"); 575 576 if(required && excludeGroup != null) 577 { 578 parseError(el, "Pack, which has excludeGroup can not be required.", 579 new Exception ("Pack, which has excludeGroup can not be required.")); 580 } 581 582 PackInfo pack = new PackInfo(name, id, description, required, loose, excludeGroup); 583 pack.setOsConstraints(OsConstraint.getOsList(el)); 585 if(excludeGroup == null) 588 pack.setPreselected(validateYesNoAttribute(el, "preselected", YES)); 589 else 590 pack.setPreselected(validateYesNoAttribute(el, "preselected", NO)); 591 592 if (group != null) 594 pack.setGroup(group); 595 if (installGroups != null) 597 { 598 StringTokenizer st = new StringTokenizer (installGroups, ","); 599 while (st.hasMoreTokens()) 600 { 601 String igroup = st.nextToken(); 602 pack.addInstallGroup(igroup); 603 } 604 } 605 606 Iterator iter = el.getChildrenNamed("parsable").iterator(); 608 while (iter.hasNext()) 609 { 610 XMLElement p = (XMLElement) iter.next(); 611 String target = requireAttribute(p, "targetfile"); 612 String type = p.getAttribute("type", "plain"); 613 String encoding = p.getAttribute("encoding", null); 614 List osList = OsConstraint.getOsList(p); 616 pack.addParsable(new ParsableFile(target, type, encoding, osList)); 617 } 618 619 iter = el.getChildrenNamed("executable").iterator(); 621 while (iter.hasNext()) 622 { 623 XMLElement e = (XMLElement) iter.next(); 624 ExecutableFile executable = new ExecutableFile(); 625 String val; 627 executable.path = requireAttribute(e, "targetfile"); 628 629 val = e.getAttribute("stage", "never"); 631 if ("postinstall".equalsIgnoreCase(val)) 632 executable.executionStage = ExecutableFile.POSTINSTALL; 633 else if ("uninstall".equalsIgnoreCase(val)) 634 executable.executionStage = ExecutableFile.UNINSTALL; 635 636 val = e.getAttribute("type", "bin"); 638 if ("jar".equalsIgnoreCase(val)) 639 { 640 executable.type = ExecutableFile.JAR; 641 executable.mainClass = e.getAttribute("class"); } 644 645 val = e.getAttribute("failure", "ask"); 647 if ("abort".equalsIgnoreCase(val)) 648 executable.onFailure = ExecutableFile.ABORT; 649 else if ("warn".equalsIgnoreCase(val)) executable.onFailure = ExecutableFile.WARN; 650 651 val = e.getAttribute("keep"); 653 executable.keepFile = "true".equalsIgnoreCase(val); 654 655 XMLElement args = e.getFirstChildNamed("args"); 657 if (null != args) 658 { 659 Iterator argIterator = args.getChildrenNamed("arg").iterator(); 660 while (argIterator.hasNext()) 661 { 662 XMLElement arg = (XMLElement) argIterator.next(); 663 executable.argList.add(requireAttribute(arg, "value")); 664 } 665 } 666 667 executable.osList = OsConstraint.getOsList(e); 670 pack.addExecutable(executable); 671 } 672 673 iter = el.getChildrenNamed("file").iterator(); 675 while (iter.hasNext()) 676 { 677 XMLElement f = (XMLElement) iter.next(); 678 String src = requireAttribute(f, "src"); 679 String targetdir = requireAttribute(f, "targetdir"); 680 List osList = OsConstraint.getOsList(f); int override = getOverrideValue(f); 682 Map additionals = getAdditionals(f); 683 boolean unpack = src.endsWith(".zip") && "true".equalsIgnoreCase(f.getAttribute("unpack")); 684 685 File file = new File (src); 686 if (!file.isAbsolute()) file = new File (basedir, src); 687 688 try 689 { 690 if (unpack) 691 addArchiveContent(baseDir, file, targetdir, osList, override, pack, additionals); 692 else 693 addRecursively(baseDir, file, targetdir, osList, override, pack, additionals); 694 } 695 catch (Exception x) 696 { 697 parseError(f, x.getMessage(), x); 698 } 699 } 700 701 iter = el.getChildrenNamed("singlefile").iterator(); 703 while (iter.hasNext()) 704 { 705 XMLElement f = (XMLElement) iter.next(); 706 String src = requireAttribute(f, "src"); 707 String target = requireAttribute(f, "target"); 708 List osList = OsConstraint.getOsList(f); int override = getOverrideValue(f); 710 Map additionals = getAdditionals(f); 711 712 File file = new File (src); 713 if (!file.isAbsolute()) file = new File (basedir, src); 714 715 try 716 { 717 pack.addFile(baseDir, file, target, osList, override, additionals); 718 } 719 catch (FileNotFoundException x) 720 { 721 parseError(f, x.getMessage(), x); 722 } 723 } 724 725 iter = el.getChildrenNamed("fileset").iterator(); 727 while (iter.hasNext()) 728 { 729 XMLElement f = (XMLElement) iter.next(); 730 String dir_attr = requireAttribute(f, "dir"); 731 732 File dir = new File (dir_attr); 733 if (!dir.isAbsolute()) dir = new File (basedir, dir_attr); 734 if (!dir.isDirectory()) parseError(f, "Invalid directory 'dir': " + dir_attr); 736 737 boolean casesensitive = validateYesNoAttribute(f, "casesensitive", YES); 738 boolean defexcludes = validateYesNoAttribute(f, "defaultexcludes", YES); 739 String targetdir = requireAttribute(f, "targetdir"); 740 List osList = OsConstraint.getOsList(f); int override = getOverrideValue(f); 742 Map additionals = getAdditionals(f); 743 744 Vector xcludesList = null; 746 String [] includes = null; 747 xcludesList = f.getChildrenNamed("include"); 748 if (!xcludesList.isEmpty()) 749 { 750 includes = new String [xcludesList.size()]; 751 for (int j = 0; j < xcludesList.size(); j++) 752 { 753 XMLElement xclude = (XMLElement) xcludesList.get(j); 754 includes[j] = requireAttribute(xclude, "name"); 755 } 756 } 757 String [] excludes = null; 758 xcludesList = f.getChildrenNamed("exclude"); 759 if (!xcludesList.isEmpty()) 760 { 761 excludes = new String [xcludesList.size()]; 762 for (int j = 0; j < xcludesList.size(); j++) 763 { 764 XMLElement xclude = (XMLElement) xcludesList.get(j); 765 excludes[j] = requireAttribute(xclude, "name"); 766 } 767 } 768 769 String [] toDo = new String [] { "includes", "excludes"}; 771 String [][] containers = new String [][] { includes, excludes}; 774 for (int j = 0; j < toDo.length; ++j) 775 { 776 String inex = f.getAttribute(toDo[j]); 777 if (inex != null && inex.length() > 0) 778 { StringTokenizer tok = new StringTokenizer (inex, ", ", false); 780 int newSize = tok.countTokens(); 781 int k = 0; 782 String [] nCont = null; 783 if (containers[j] != null && containers[j].length > 0) 784 { newSize += containers[j].length; 788 nCont = new String [newSize]; 789 for (; k < containers[j].length; ++k) 790 nCont[k] = containers[j][k]; 791 } 792 if (nCont == null) nCont = new String [newSize]; 796 for (; k < newSize; ++k) 797 nCont[k] = tok.nextToken(); 799 containers[j] = nCont; 800 } 801 } 802 includes = containers[0]; excludes = containers[1]; 807 DirectoryScanner ds = new DirectoryScanner(); 809 ds.setIncludes(includes); 810 ds.setExcludes(excludes); 811 if (defexcludes) ds.addDefaultExcludes(); 812 ds.setBasedir(dir); 813 ds.setCaseSensitive(casesensitive); 814 ds.scan(); 815 816 String [] files = ds.getIncludedFiles(); 817 String [] dirs = ds.getIncludedDirectories(); 818 819 for (int i = 0; i < files.length; ++i) 822 { 823 try 824 { 825 String target = new File (targetdir, files[i]).getPath(); 826 pack 827 .addFile(baseDir, new File (dir, files[i]), target, osList, override, 828 additionals); 829 } 830 catch (FileNotFoundException x) 831 { 832 parseError(f, x.getMessage(), x); 833 } 834 } 835 for (int i = 0; i < dirs.length; ++i) 836 { 837 try 838 { 839 String target = new File (targetdir, dirs[i]).getPath(); 840 pack.addFile(baseDir, new File (dir, dirs[i]), target, osList, override, additionals); 841 } 842 catch (FileNotFoundException x) 843 { 844 parseError(f, x.getMessage(), x); 845 } 846 } 847 } 848 849 iter = el.getChildrenNamed("updatecheck").iterator(); 851 while (iter.hasNext()) 852 { 853 XMLElement f = (XMLElement) iter.next(); 854 855 String casesensitive = f.getAttribute("casesensitive"); 856 857 ArrayList includesList = new ArrayList (); 859 ArrayList excludesList = new ArrayList (); 860 861 Iterator include_it = f.getChildrenNamed("include").iterator(); 863 while (include_it.hasNext()) 864 { 865 XMLElement inc_el = (XMLElement) include_it.next(); 866 includesList.add(requireAttribute(inc_el, "name")); 867 } 868 869 Iterator exclude_it = f.getChildrenNamed("exclude").iterator(); 870 while (exclude_it.hasNext()) 871 { 872 XMLElement excl_el = (XMLElement) exclude_it.next(); 873 excludesList.add(requireAttribute(excl_el, "name")); 874 } 875 876 pack.addUpdateCheck(new UpdateCheck(includesList, excludesList, casesensitive)); 877 } 878 iter = el.getChildrenNamed("depends").iterator(); 880 while (iter.hasNext()) 881 { 882 XMLElement dep = (XMLElement) iter.next(); 883 String depName = requireAttribute(dep, "packname"); 884 pack.addDependency(depName); 885 886 } 887 compiler.addPack(pack); 889 } 890 891 compiler.checkDependencies(); 892 compiler.checkExcludes(); 893 894 notifyCompilerListener("addPacks", CompilerListener.END, data); 895 } 896 897 902 public void checkDependencies(List packs) throws CompilerException 903 { 904 Map names = new HashMap (); 907 for (int i = 0; i < packs.size(); i++) 908 { 909 PackInfo pack = (PackInfo) packs.get(i); 910 names.put(pack.getPack().name, pack); 911 } 912 int result = dfs(packs, names); 913 if (result == -2) 915 parseError("Circular dependency detected"); 916 else if (result == -1) parseError("A dependency doesn't exist"); 917 } 918 919 927 private int dfs(List packs, Map names) 928 { 929 Map edges = new HashMap (); 930 for (int i = 0; i < packs.size(); i++) 931 { 932 PackInfo pack = (PackInfo) packs.get(i); 933 if (pack.colour == PackInfo.WHITE) 934 { 935 if (dfsVisit(pack, names, edges) != 0) return -1; 936 } 937 938 } 939 return checkBackEdges(edges); 940 } 941 942 945 private int checkBackEdges(Map edges) 946 { 947 Set keys = edges.keySet(); 948 for (Iterator iterator = keys.iterator(); iterator.hasNext();) 949 { 950 final Object key = iterator.next(); 951 int color = ((Integer ) edges.get(key)).intValue(); 952 if (color == PackInfo.GREY) { return -2; } 953 } 954 return 0; 955 956 } 957 958 961 private class Edge 962 { 963 964 PackInfo u; 965 966 PackInfo v; 967 968 Edge(PackInfo u, PackInfo v) 969 { 970 this.u = u; 971 this.v = v; 972 } 973 } 974 975 private int dfsVisit(PackInfo u, Map names, Map edges) 976 { 977 u.colour = PackInfo.GREY; 978 List deps = u.getDependencies(); 979 if (deps != null) 980 { 981 for (int i = 0; i < deps.size(); i++) 982 { 983 String name = (String ) deps.get(i); 984 PackInfo v = (PackInfo) names.get(name); 985 if (v == null) 986 { 987 System.out.println("Failed to find dependency: "+name); 988 return -1; 989 } 990 Edge edge = new Edge(u, v); 991 if (edges.get(edge) == null) edges.put(edge, new Integer (v.colour)); 992 993 if (v.colour == PackInfo.WHITE) 994 { 995 996 final int result = dfsVisit(v, names, edges); 997 if (result != 0) return result; 998 } 999 } 1000 } 1001 u.colour = PackInfo.BLACK; 1002 return 0; 1003 } 1004 1005 1014 protected void addArchiveContent(File baseDir, File archive, String targetdir, List osList, int override, PackInfo pack, Map additionals) throws IOException { 1015 1016 FileInputStream fin = new FileInputStream (archive); 1017 ZipInputStream zin = new ZipInputStream (fin); 1018 while (true) { 1019 ZipEntry zentry = zin.getNextEntry(); 1020 if (zentry==null) break; 1021 if (zentry.isDirectory()) continue; 1022 1023 try { 1024 File temp = File.createTempFile("izpack", null); 1025 temp.deleteOnExit(); 1026 1027 FileOutputStream out = new FileOutputStream (temp); 1028 PackagerHelper.copyStream(zin, out); 1029 out.close(); 1030 1031 pack.addFile(baseDir, temp, targetdir + "/" + zentry.getName(), osList, override, additionals); 1032 } catch (IOException e) { 1033 throw new IOException ("Couldn't create temporary file for "+zentry.getName()+" in archive "+archive+" ("+e.getMessage()+")"); 1034 } 1035 1036 } 1037 fin.close(); 1038 } 1039 1040 1051 protected void addRecursively(File baseDir, File file, String targetdir, List osList, int override, 1052 PackInfo pack, Map additionals) throws IOException 1053 { 1054 String targetfile = targetdir + "/" + file.getName(); 1055 if (!file.isDirectory()) 1056 pack.addFile(baseDir, file, targetfile, osList, override, additionals); 1057 else 1058 { 1059 File [] files = file.listFiles(); 1060 if (files.length == 0) pack.addFile(baseDir, file, targetfile, osList, override, additionals); 1062 else 1063 { 1064 for (int i = 0; i < files.length; i++) 1066 addRecursively(baseDir, files[i], targetfile, osList, override, pack, additionals); 1067 } 1068 } 1069 } 1070 1071 1077 protected void addPanels(XMLElement data) throws CompilerException 1078 { 1079 notifyCompilerListener("addPanels", CompilerListener.BEGIN, data); 1080 XMLElement root = requireChildNamed(data, "panels"); 1081 1082 Vector panels = root.getChildrenNamed("panel"); 1084 if (panels.isEmpty()) parseError(root, "<panels> requires a <panel>"); 1085 1086 Iterator iter = panels.iterator(); 1088 while (iter.hasNext()) 1089 { 1090 XMLElement xmlPanel = (XMLElement) iter.next(); 1091 1092 Panel panel = new Panel(); 1094 panel.osConstraints = OsConstraint.getOsList(xmlPanel); 1095 String className = xmlPanel.getAttribute("classname"); 1096 String panelid = xmlPanel.getAttribute("id"); 1098 panel.setPanelid(panelid); 1099 String jarPath = "bin/panels/" + className + ".jar"; 1101 URL url = findIzPackResource(jarPath, "Panel jar file", xmlPanel); 1102 String fullClassName = null; 1103 try 1104 { 1105 fullClassName = getFullClassName(url, className); 1106 } 1107 catch (IOException e) 1108 { 1109 } 1110 if (fullClassName != null) 1111 panel.className = fullClassName; 1112 else 1113 panel.className = className; 1114 compiler.addPanelJar(panel, url); 1116 } 1117 notifyCompilerListener("addPanels", CompilerListener.END, data); 1118 } 1119 1120 1126 protected void addResources(XMLElement data) throws CompilerException 1127 { 1128 notifyCompilerListener("addResources", CompilerListener.BEGIN, data); 1129 XMLElement root = data.getFirstChildNamed("resources"); 1130 if (root == null) return; 1131 1132 Iterator iter = root.getChildrenNamed("res").iterator(); 1134 while (iter.hasNext()) 1135 { 1136 XMLElement res = (XMLElement) iter.next(); 1137 String id = requireAttribute(res, "id"); 1138 String src = requireAttribute(res, "src"); 1139 boolean parse = validateYesNoAttribute(res, "parse", NO); 1140 1141 URL url = findProjectResource(src, "Resource", res); 1143 1144 if (parse) 1146 { 1147 if (compiler.getVariables().isEmpty()) 1148 { 1149 parseWarn(res, "No variables defined. " + url.getPath() + " not parsed."); 1150 } 1151 else 1152 { 1153 String type = res.getAttribute("type"); 1154 String encoding = res.getAttribute("encoding"); 1155 File parsedFile = null; 1156 1157 try 1158 { 1159 InputStream bin = new BufferedInputStream (url.openStream()); 1161 1162 parsedFile = File.createTempFile("izpp", null); 1163 parsedFile.deleteOnExit(); 1164 FileOutputStream outFile = new FileOutputStream (parsedFile); 1165 BufferedOutputStream bout = new BufferedOutputStream (outFile); 1166 1167 VariableSubstitutor vs = new VariableSubstitutor(compiler.getVariables()); 1168 vs.substitute(bin, bout, type, encoding); 1169 bin.close(); 1170 bout.close(); 1171 1172 url = parsedFile.toURL(); 1175 } 1176 catch (IOException x) 1177 { 1178 parseError(res, x.getMessage(), x); 1179 } 1180 } 1181 } 1182 1183 compiler.addResource(id, url); 1184 } 1185 notifyCompilerListener("addResources", CompilerListener.END, data); 1186 } 1187 1188 1194 protected void addLangpacks(XMLElement data) throws CompilerException 1195 { 1196 notifyCompilerListener("addLangpacks", CompilerListener.BEGIN, data); 1197 XMLElement root = requireChildNamed(data, "locale"); 1198 1199 Vector locals = root.getChildrenNamed("langpack"); 1201 if (locals.isEmpty()) parseError(root, "<locale> requires a <langpack>"); 1202 1203 Iterator iter = locals.iterator(); 1205 while (iter.hasNext()) 1206 { 1207 XMLElement el = (XMLElement) iter.next(); 1208 String iso3 = requireAttribute(el, "iso3"); 1209 String path; 1210 1211 path = "bin/langpacks/installer/" + iso3 + ".xml"; 1212 URL iso3xmlURL = findIzPackResource(path, "ISO3 file", el); 1213 1214 path = "bin/langpacks/flags/" + iso3 + ".gif"; 1215 URL iso3FlagURL = findIzPackResource(path, "ISO3 flag image", el); 1216 1217 compiler.addLangPack(iso3, iso3xmlURL, iso3FlagURL); 1218 } 1219 notifyCompilerListener("addLangpacks", CompilerListener.END, data); 1220 } 1221 1222 1228 protected void addInfo(XMLElement data) throws Exception 1229 { 1230 notifyCompilerListener("addInfo", CompilerListener.BEGIN, data); 1231 XMLElement root = requireChildNamed(data, "info"); 1233 1234 Info info = new Info(); 1235 info.setAppName(requireContent(requireChildNamed(root, "appname"))); 1236 info.setAppVersion(requireContent(requireChildNamed(root, "appversion"))); 1237 XMLElement subpath = root.getFirstChildNamed("appsubpath"); 1239 if (subpath != null) 1240 { 1241 info.setInstallationSubPath(requireContent(subpath)); 1242 } 1243 1244 final XMLElement URLElem = root.getFirstChildNamed("url"); 1246 if (URLElem != null) 1247 { 1248 URL appURL = requireURLContent(URLElem); 1249 info.setAppURL(appURL.toString()); 1250 } 1251 1252 XMLElement authors = root.getFirstChildNamed("authors"); 1254 if (authors != null) 1255 { 1256 Iterator iter = authors.getChildrenNamed("author").iterator(); 1257 while (iter.hasNext()) 1258 { 1259 XMLElement author = (XMLElement) iter.next(); 1260 String name = requireAttribute(author, "name"); 1261 String email = requireAttribute(author, "email"); 1262 info.addAuthor(new Info.Author(name, email)); 1263 } 1264 } 1265 1266 XMLElement javaVersion = root.getFirstChildNamed("javaversion"); 1268 if (javaVersion != null) info.setJavaVersion(requireContent(javaVersion)); 1269 1270 XMLElement webDirURL = root.getFirstChildNamed("webdir"); 1272 if (webDirURL != null) info.setWebDirURL(requireURLContent(webDirURL).toString()); 1273 String kind = compiler.getKind(); 1274 if (kind != null) 1275 { 1276 if (kind.equalsIgnoreCase(WEB) && webDirURL == null) 1277 { 1278 parseError(root, "<webdir> required when \"WEB\" installer requested"); 1279 } 1280 else if (kind.equalsIgnoreCase(STANDARD) && webDirURL != null) 1281 { 1282 info.setWebDirURL(null); 1285 } 1286 } 1287 1288 XMLElement uninstallInfo = root.getFirstChildNamed("uninstaller"); 1290 if (validateYesNoAttribute(uninstallInfo, "write", YES)) 1291 { 1292 URL url = findIzPackResource("lib/uninstaller.jar", "Uninstaller", root); 1293 compiler.addResource("IzPack.uninstaller", url); 1294 1295 if (uninstallInfo != null) 1296 { 1297 String uninstallerName = uninstallInfo.getAttribute("name"); 1298 if (uninstallerName != null && uninstallerName.endsWith(".jar") 1299 && uninstallerName.length() > ".jar".length()) 1300 info.setUninstallerName(uninstallerName); 1301 } 1302 } 1303 XMLElement slfPath = root.getFirstChildNamed("summarylogfilepath"); 1305 if (slfPath != null) info.setSummaryLogFilePath(requireContent(slfPath)); 1306 1307 String unpackerclass = compiler.getProperty("UNPACKER_CLASS"); 1309 info.setUnpackerClassName(unpackerclass); 1310 compiler.setInfo(info); 1311 notifyCompilerListener("addInfo", CompilerListener.END, data); 1312 } 1313 1314 1337 protected void addVariables(XMLElement data) throws CompilerException 1338 { 1339 notifyCompilerListener("addVariables", CompilerListener.BEGIN, data); 1340 XMLElement root = data.getFirstChildNamed("variables"); 1342 if (root == null) return; 1343 1344 Properties variables = compiler.getVariables(); 1345 1346 Iterator iter = root.getChildrenNamed("variable").iterator(); 1347 while (iter.hasNext()) 1348 { 1349 XMLElement var = (XMLElement) iter.next(); 1350 String name = requireAttribute(var, "name"); 1351 String value = requireAttribute(var, "value"); 1352 if (variables.contains(name)) 1353 parseWarn(var, "Variable '" + name + "' being overwritten"); 1354 variables.setProperty(name, value); 1355 } 1356 notifyCompilerListener("addVariables", CompilerListener.END, data); 1357 } 1358 1359 1386 protected void substituteProperties(XMLElement data) throws CompilerException 1387 { 1388 notifyCompilerListener("substituteProperties", CompilerListener.BEGIN, data); 1389 1390 XMLElement root = data.getFirstChildNamed("properties"); 1391 if (root != null) 1392 { 1393 Iterator iter = root.getChildrenNamed("property").iterator(); 1395 while (iter.hasNext()) 1396 { 1397 XMLElement prop = (XMLElement) iter.next(); 1398 Property property = new Property(prop, this); 1399 property.execute(); 1400 } 1401 } 1402 1403 if (root != null) data.removeChild(root); 1408 1409 substituteAllProperties(data); 1410 if (root != null) data.addChild(root); 1411 1412 notifyCompilerListener("substituteProperties", CompilerListener.END, data); 1413 } 1414 1415 1418 protected void substituteAllProperties(XMLElement element) throws CompilerException 1419 { 1420 Enumeration attributes = element.enumerateAttributeNames(); 1421 while (attributes.hasMoreElements()) 1422 { 1423 String name = (String ) attributes.nextElement(); 1424 String value = compiler.replaceProperties(element.getAttribute(name)); 1425 element.setAttribute(name, value); 1426 } 1427 1428 String content = element.getContent(); 1429 if (content != null) 1430 { 1431 element.setContent(compiler.replaceProperties(content)); 1432 } 1433 1434 Enumeration children = element.enumerateChildren(); 1435 while (children.hasMoreElements()) 1436 { 1437 XMLElement child = (XMLElement) children.nextElement(); 1438 substituteAllProperties(child); 1439 } 1440 } 1441 1442 1449 protected XMLElement getXMLTree() throws CompilerException, IOException 1450 { 1451 IXMLReader reader = null; 1453 if( filename != null ) 1454 { 1455 File file = new File (filename).getAbsoluteFile(); 1456 if (!file.canRead()) throw new CompilerException("Invalid file: " + file); 1457 reader = new StdXMLReader(new FileInputStream (filename)); 1458 compiler.setProperty("izpack.file", file.toString()); 1460 } 1461 else if( installText != null ) 1462 { 1463 reader = StdXMLReader.stringReader(installText); 1464 } 1465 else 1466 { 1467 throw new CompilerException("Neither install file or text specified"); 1468 } 1469 1470 StdXMLParser parser = new StdXMLParser(); 1471 parser.setBuilder(new StdXMLBuilder()); 1472 parser.setReader(reader); 1473 parser.setValidator(new NonValidator()); 1474 1475 XMLElement data = null; 1477 try 1478 { 1479 data = (XMLElement) parser.parse(); 1480 } 1481 catch (Exception x) 1482 { 1483 throw new CompilerException("Error parsing installation file", x); 1484 } 1485 1486 if (!"installation".equalsIgnoreCase(data.getName())) 1488 parseError(data, "this is not an IzPack XML installation file"); 1489 if (!requireAttribute(data, "version").equalsIgnoreCase(VERSION)) 1490 parseError(data, "the file version is different from the compiler version"); 1491 1492 return data; 1494 } 1495 1496 protected int getOverrideValue(XMLElement f) throws CompilerException 1497 { 1498 int override = PackFile.OVERRIDE_UPDATE; 1499 1500 String override_val = f.getAttribute("override"); 1501 if (override_val != null) 1502 { 1503 if ("true".equalsIgnoreCase(override_val)) 1504 { 1505 override = PackFile.OVERRIDE_TRUE; 1506 } 1507 else if ("false".equalsIgnoreCase(override_val)) 1508 { 1509 override = PackFile.OVERRIDE_FALSE; 1510 } 1511 else if ("asktrue".equalsIgnoreCase(override_val)) 1512 { 1513 override = PackFile.OVERRIDE_ASK_TRUE; 1514 } 1515 else if ("askfalse".equalsIgnoreCase(override_val)) 1516 { 1517 override = PackFile.OVERRIDE_ASK_FALSE; 1518 } 1519 else if ("update".equalsIgnoreCase(override_val)) 1520 { 1521 override = PackFile.OVERRIDE_UPDATE; 1522 } 1523 else 1524 parseError(f, "invalid value for attribute \"override\""); 1525 } 1526 1527 return override; 1528 } 1529 1530 1540 private URL findProjectResource(String path, String desc, XMLElement parent) 1541 throws CompilerException 1542 { 1543 URL url = null; 1544 File resource = new File (path); 1545 if (!resource.isAbsolute()) resource = new File (basedir, path); 1546 1547 if (!resource.exists()) parseError(parent, desc + " not found: " + resource); 1549 1550 try 1551 { 1552 url = resource.toURL(); 1553 } 1554 catch (MalformedURLException how) 1555 { 1556 parseError(parent, desc + "(" + resource + ")", how); 1557 } 1558 1559 return url; 1560 } 1561 1562 1573 private URL findIzPackResource(String path, String desc, XMLElement parent) 1574 throws CompilerException 1575 { 1576 URL url = getClass().getResource("/" + path); 1577 if (url == null) 1578 { 1579 File resource = new File (path); 1580 1581 if (!resource.isAbsolute()) resource = new File (Compiler.IZPACK_HOME, path); 1582 1583 if (!resource.exists()) parseError(parent, desc + " not found: " + resource); 1585 1586 try 1587 { 1588 url = resource.toURL(); 1589 } 1590 catch (MalformedURLException how) 1591 { 1592 parseError(parent, desc + "(" + resource + ")", how); 1593 } 1594 } 1595 1596 return url; 1597 } 1598 1599 1605 protected void parseError(String message) throws CompilerException 1606 { 1607 throw new CompilerException(filename + ":" + message); 1608 } 1609 1610 1617 protected void parseError(XMLElement parent, String message) throws CompilerException 1618 { 1619 throw new CompilerException(filename + ":" + parent.getLineNr() + ": " + message); 1620 } 1621 1622 1629 protected void parseError(XMLElement parent, String message, Throwable cause) 1630 throws CompilerException 1631 { 1632 throw new CompilerException(filename + ":" + parent.getLineNr() + ": " + message, cause); 1633 } 1634 1635 1642 protected void parseWarn(XMLElement parent, String message) 1643 { 1644 System.out.println(filename + ":" + parent.getLineNr() + ": " + message); 1645 } 1646 1647 1654 protected XMLElement requireChildNamed(XMLElement parent, String name) throws CompilerException 1655 { 1656 XMLElement child = parent.getFirstChildNamed(name); 1657 if (child == null) 1658 parseError(parent, "<" + parent.getName() + "> requires child <" + name + ">"); 1659 return child; 1660 } 1661 1662 1668 protected URL requireURLContent(XMLElement element) throws CompilerException 1669 { 1670 URL url = null; 1671 try 1672 { 1673 url = new URL (requireContent(element)); 1674 } 1675 catch (MalformedURLException x) 1676 { 1677 parseError(element, "<" + element.getName() + "> requires valid URL", x); 1678 } 1679 return url; 1680 } 1681 1682 1688 protected String requireContent(XMLElement element) throws CompilerException 1689 { 1690 String content = element.getContent(); 1691 if (content == null || content.length() == 0) 1692 parseError(element, "<" + element.getName() + "> requires content"); 1693 return content; 1694 } 1695 1696 1703 protected String requireAttribute(XMLElement element, String attribute) 1704 throws CompilerException 1705 { 1706 String value = element.getAttribute(attribute); 1707 if (value == null) 1708 parseError(element, "<" + element.getName() + "> requires attribute '" + attribute 1709 + "'"); 1710 return value; 1711 } 1712 1713 1721 protected int requireIntAttribute(XMLElement element, String attribute) 1722 throws CompilerException 1723 { 1724 String value = element.getAttribute(attribute); 1725 if (value == null || value.length() == 0) 1726 parseError(element, "<" + element.getName() + "> requires attribute '" + attribute 1727 + "'"); 1728 try 1729 { 1730 return Integer.parseInt(value); 1731 } 1732 catch (NumberFormatException x) 1733 { 1734 parseError(element, "'" + attribute + "' must be an integer"); 1735 } 1736 return 0; } 1738 1739 1746 protected boolean requireYesNoAttribute(XMLElement element, String attribute) 1747 throws CompilerException 1748 { 1749 String value = requireAttribute(element, attribute); 1750 if ("yes".equalsIgnoreCase(value)) return true; 1751 if ("no".equalsIgnoreCase(value)) return false; 1752 1753 parseError(element, "<" + element.getName() + "> invalid attribute '" + attribute 1754 + "': Expected (yes|no)"); 1755 1756 return false; } 1758 1759 1767 protected boolean validateYesNoAttribute(XMLElement element, String attribute, 1768 boolean defaultValue) 1769 { 1770 if (element == null) return defaultValue; 1771 1772 String value = element.getAttribute(attribute, (defaultValue ? "yes" : "no")); 1773 if ("yes".equalsIgnoreCase(value)) return true; 1774 if ("no".equalsIgnoreCase(value)) return false; 1775 1776 parseWarn(element, "<" + element.getName() + "> invalid attribute '" + attribute 1779 + "': Expected (yes|no) if present"); 1780 1781 return defaultValue; 1782 } 1783 1784 1789 public static void main(String [] args) 1790 { 1791 System.out.println(""); 1793 System.out.println(".:: IzPack - Version " + Compiler.IZPACK_VERSION + " ::."); 1794 System.out.println(""); 1795 System.out.println("< compiler specifications version: " + VERSION + " >"); 1796 System.out.println(""); 1797 System.out.println("- Copyright (C) 2001-2007 Julien Ponge"); 1798 System.out.println("- Visit http://www.izforge.com/izpack/ for the latest releases"); 1799 System.out.println("- Released under the terms of the Apache Software License version 2.0."); 1800 System.out.println(""); 1801 1802 int exitCode = 1; 1804 String home = "."; 1805 String izHome = System.getProperty("IZPACK_HOME"); 1807 if (izHome != null) home = izHome; 1808 1809 try 1811 { 1812 String filename; 1814 String base = "."; 1815 String kind = "standard"; 1816 String output; 1817 String compr_format = "default"; 1818 int compr_level = -1; 1819 1820 int nArgs = args.length; 1822 if (nArgs < 1) throw new Exception ("no arguments given"); 1823 1824 if ("-?".equalsIgnoreCase(args[0])) 1826 { 1827 System.out.println("-> Command line parameters are : (xml file) [args]"); 1828 System.out.println(" (xml file): the xml file describing the installation"); 1829 System.out.println(" -h (IzPack home) : the root path of IzPack. This will be needed"); 1830 System.out.println(" if the compiler is not called in the root directory of IzPack."); 1831 System.out.println(" Do not forget quotations if there are blanks in the path."); 1832 System.out 1833 .println(" -b (base) : indicates the base path that the compiler will use for filenames"); 1834 System.out.println(" of sources. Default is the current path. Attend to -h."); 1835 System.out.println(" -k (kind) : indicates the kind of installer to generate"); 1836 System.out.println(" default is standard"); 1837 System.out.println(" -o (out) : indicates the output file name"); 1838 System.out.println(" default is the xml file name\n"); 1839 System.out 1840 .println(" -c (compression) : indicates the compression format to be used for packs"); 1841 System.out.println(" default is the internal deflate compression\n"); 1842 System.out 1843 .println(" -l (compression-level) : indicates the level for the used compression format"); 1844 System.out.println(" if supported. Only integer are valid\n"); 1845 1846 System.out 1847 .println(" When using vm option -DSTACKTRACE=true there is all kind of debug info "); 1848 System.out.println(""); 1849 exitCode = 0; 1850 } 1851 else 1852 { 1853 1856 filename = args[0]; 1859 output = filename.substring(0, filename.length() - 3) + "jar"; 1861 1862 int pos = 1; 1864 while (pos < nArgs) 1865 if ((args[pos].startsWith("-")) && (args[pos].length() == 2)) 1866 { 1867 switch (args[pos].toLowerCase().charAt(1)) 1868 { 1869 case 'b': 1870 if ((pos + 1) < nArgs) 1871 { 1872 pos++; 1873 base = args[pos]; 1874 } 1875 else 1876 throw new Exception ("base argument missing"); 1877 break; 1878 case 'k': 1879 if ((pos + 1) < nArgs) 1880 { 1881 pos++; 1882 kind = args[pos]; 1883 } 1884 else 1885 throw new Exception ("kind argument missing"); 1886 break; 1887 case 'o': 1888 if ((pos + 1) < nArgs) 1889 { 1890 pos++; 1891 output = args[pos]; 1892 } 1893 else 1894 throw new Exception ("output argument missing"); 1895 break; 1896 case 'c': 1897 if ((pos + 1) < nArgs) 1898 { 1899 pos++; 1900 compr_format = args[pos]; 1901 } 1902 else 1903 throw new Exception ("compression format argument missing"); 1904 break; 1905 case 'l': 1906 if ((pos + 1) < nArgs) 1907 { 1908 pos++; 1909 compr_level = Integer.parseInt(args[pos]); 1910 } 1911 else 1912 throw new Exception ("compression level argument missing"); 1913 break; 1914 case 'h': 1915 if ((pos + 1) < nArgs) 1916 { 1917 pos++; 1918 home = args[pos]; 1919 } 1920 else 1921 throw new Exception ("IzPack home path argument missing"); 1922 break; 1923 default: 1924 throw new Exception ("unknown argument"); 1925 } 1926 pos++; 1927 } 1928 else 1929 throw new Exception ("bad argument"); 1930 1931 home = resolveIzPackHome(home); 1932 System.out.println("-> Processing : " + filename); 1934 System.out.println("-> Output : " + output); 1935 System.out.println("-> Base path : " + base); 1936 System.out.println("-> Kind : " + kind); 1937 System.out.println("-> Compression : " + compr_format); 1938 System.out.println("-> Compr. level: " + compr_level); 1939 System.out.println("-> IzPack home : " + home); 1940 System.out.println(""); 1941 1942 1943 Compiler.setIzpackHome(home); 1944 1945 1946 CmdlinePackagerListener listener = new CmdlinePackagerListener(); 1948 CompilerConfig compiler = new CompilerConfig(filename, base, kind, output, 1949 compr_format, compr_level, listener, (String ) null); 1950 compiler.executeCompiler(); 1951 1952 while (compiler.isAlive()) 1954 Thread.sleep(100); 1955 1956 if (compiler.wasSuccessful()) exitCode = 0; 1957 1958 System.out.println("Build time: " + new Date ()); 1959 } 1960 } 1961 catch (Exception err) 1962 { 1963 System.err.println("-> Fatal error :"); 1965 System.err.println(" " + err.getMessage()); 1966 err.printStackTrace(); 1967 System.err.println(""); 1968 System.err.println("(tip : use -? to get the commmand line parameters)"); 1969 } 1970 1971 System.exit(exitCode); 1973 } 1974 1975 private static String resolveIzPackHome(String home) 1976 { 1977 File test = new File (home, IZ_TEST_SUBDIR + File.separator + IZ_TEST_FILE); 1978 if( test != null && test.exists()) 1979 return( home); 1980 String self = Compiler .class.getName(); 1983 self = self.replace('.', '/'); 1984 self = "/" + self + ".class"; 1985 URL url = Compiler .class.getResource(self); 1986 String np = url.getFile(); 1987 int start = np.indexOf(self); 1988 np = np.substring(0, start); 1989 if( np.endsWith("!")) 1990 { if(np.endsWith("standalone-compiler.jar!")) 1993 return("."); 1994 np = np.substring(0, np.length() - 1); 1995 } 1996 File root = null; 1997 if( URI.create(np).isAbsolute()) 1998 root = new File (URI.create(np)); 1999 else 2000 root = new File (np); 2001 while(true) 2002 { 2003 if( root == null ) 2004 throw new IllegalArgumentException ("No valid IzPack home directory found"); 2005 test = new File (root, IZ_TEST_SUBDIR + File.separator + IZ_TEST_FILE); 2006 if( test.exists()) 2007 return(root.getAbsolutePath()); 2008 root = root.getParentFile(); 2009 } 2010 } 2011 2012 2015 2024 private void addCustomListeners(XMLElement data) throws Exception 2025 { 2026 XMLElement root = data.getFirstChildNamed("listeners"); 2028 if (root == null) return; 2029 Iterator iter = root.getChildrenNamed("listener").iterator(); 2030 while (iter.hasNext()) 2031 { 2032 XMLElement xmlAction = (XMLElement) iter.next(); 2033 Object [] listener = getCompilerListenerInstance(xmlAction); 2034 if (listener != null) 2035 addCompilerListener((CompilerListener) listener[0]); 2036 String [] typeNames = new String [] { "installer", "uninstaller"}; 2037 int[] types = new int[] { CustomData.INSTALLER_LISTENER, 2038 CustomData.UNINSTALLER_LISTENER}; 2039 for (int i = 0; i < typeNames.length; ++i) 2040 { 2041 String className = xmlAction.getAttribute(typeNames[i]); 2042 if (className != null) 2043 { 2044 String jarPath = xmlAction.getAttribute("jar"); 2046 jarPath = compiler.replaceProperties(jarPath); 2047 if( jarPath == null ) 2048 jarPath = "bin/customActions/" + className + ".jar"; 2049 List constraints = OsConstraint.getOsList(xmlAction); 2050 compiler.addCustomListener(types[i], className, jarPath, constraints); 2051 } 2052 } 2053 } 2054 2055 } 2056 2057 2065 private List getContainedFilePaths(URL url) throws Exception 2066 { 2067 JarInputStream jis = new JarInputStream (url.openStream()); 2068 ZipEntry zentry = null; 2069 ArrayList fullNames = new ArrayList (); 2070 while ((zentry = jis.getNextEntry()) != null) 2071 { 2072 String name = zentry.getName(); 2073 if (!zentry.isDirectory()) fullNames.add(name); 2075 } 2076 jis.close(); 2077 return (fullNames); 2078 } 2079 2080 2089 private String getFullClassName(URL url, String className) throws IOException { 2091 JarInputStream jis = new JarInputStream (url.openStream()); 2092 ZipEntry zentry = null; 2093 while ((zentry = jis.getNextEntry()) != null) 2094 { 2095 String name = zentry.getName(); 2096 int lastPos = name.lastIndexOf(".class"); 2097 if (lastPos < 0) 2098 { 2099 continue; } 2101 name = name.replace('/', '.'); 2102 int pos = -1; 2103 int nonCasePos = -1; 2104 if (className != null) 2105 { 2106 pos = name.indexOf(className); 2107 nonCasePos = name.toLowerCase().indexOf(className.toLowerCase()); 2108 } 2109 if (pos != -1 && name.length() == pos + className.length() + 6) { 2111 jis.close(); 2112 return (name.substring(0, lastPos)); 2113 } 2114 2115 if (nonCasePos != -1 && name.length() == nonCasePos + className.length() + 6) 2116 throw new IllegalArgumentException ("Fatal error! The declared panel name in the xml file (" 2118 + className + ") differs in case to the founded class file (" + name + ")."); 2119 } 2120 jis.close(); 2121 return (null); 2122 } 2123 2124 2136 private Object [] getCompilerListenerInstance(XMLElement var) throws Exception 2137 { 2138 String className = var.getAttribute("compiler"); 2139 Class listener = null; 2140 Object instance = null; 2141 if (className == null) return (null); 2142 2143 String jarPath = var.getAttribute("jar"); 2146 jarPath = compiler.replaceProperties(jarPath); 2147 if( jarPath == null ) 2148 jarPath = "bin/customActions/" + className + ".jar"; 2149 URL url = findIzPackResource(jarPath, "CustomAction jar file", var); 2150 String fullName = getFullClassName(url, className); 2151 if (fullName == null){ 2152 return null; 2154 } 2155 if (url != null) 2156 { 2157 if (getClass().getResource("/" + jarPath) != null) 2158 { InputStream in = null; 2161 FileOutputStream outFile = null; 2162 byte[] buffer = new byte[5120]; 2163 File tf = null; 2164 try 2165 { 2166 tf = File.createTempFile("izpj", ".jar"); 2167 tf.deleteOnExit(); 2168 outFile = new FileOutputStream (tf); 2169 in = getClass().getResourceAsStream("/" + jarPath); 2170 long bytesCopied = 0; 2171 int bytesInBuffer; 2172 while ((bytesInBuffer = in.read(buffer)) != -1) 2173 { 2174 outFile.write(buffer, 0, bytesInBuffer); 2175 bytesCopied += bytesInBuffer; 2176 } 2177 } 2178 finally 2179 { 2180 if (in != null) in.close(); 2181 if (outFile != null) outFile.close(); 2182 } 2183 url = tf.toURL(); 2184 2185 } 2186 URLClassLoader ucl = new URLClassLoader (new URL [] { url}, CompilerListener.class 2189 .getClassLoader()); 2190 listener = ucl.loadClass(fullName); 2191 } 2192 if (listener != null) 2193 instance = listener.newInstance(); 2194 else 2195 parseError(var, "Cannot find defined compiler listener " + className); 2196 if (!CompilerListener.class.isInstance(instance)) 2197 parseError(var, "'" + className + "' must be implemented " 2198 + CompilerListener.class.toString()); 2199 List constraints = OsConstraint.getOsList(var); 2200 return (new Object [] { instance, className, constraints}); 2201 } 2202 2203 2209 private void addCompilerListener(CompilerListener pe) 2210 { 2211 compilerListeners.add(pe); 2212 } 2213 2214 2222 private void notifyCompilerListener(String callerName, int state, XMLElement data) 2223 throws CompilerException 2224 { 2225 Iterator i = compilerListeners.iterator(); 2226 IPackager packager = compiler.getPackager(); 2227 while (i != null && i.hasNext()) 2228 { 2229 CompilerListener listener = (CompilerListener) i.next(); 2230 listener.notify(callerName, state, data, packager); 2231 } 2232 2233 } 2234 2235 2241 private Map getAdditionals(XMLElement f) throws CompilerException 2242 { 2243 Iterator i = compilerListeners.iterator(); 2244 Map retval = null; 2245 try 2246 { 2247 while (i != null && i.hasNext()) 2248 { 2249 retval = ((CompilerListener) i.next()).reviseAdditionalDataMap(retval, f); 2250 } 2251 } 2252 catch (CompilerException ce) 2253 { 2254 parseError(f, ce.getMessage()); 2255 } 2256 return (retval); 2257 } 2258} 2259 | Popular Tags |