modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/BundleParams.java

Print this page




   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.tools.packager.bundlers;
  27 
  28 import com.oracle.bundlers.BundlerParamInfo;
  29 import com.oracle.bundlers.StandardBundlerParam;
  30 import com.sun.javafx.tools.packager.Log;
  31 import com.sun.javafx.tools.packager.PackagerLib;
  32 
  33 import java.io.File;
  34 import java.io.IOException;
  35 import java.util.*;
  36 import java.util.jar.Attributes;
  37 import java.util.jar.JarFile;
  38 import java.util.jar.Manifest;
  39 


  40 public class BundleParams {
  41       
  42     final protected Map<String, ? super Object> params;
  43     
  44     public static final String PARAM_RUNTIME                = "runtime"; // RelativeFileSet //KEY
  45     public static final String PARAM_APP_RESOURCES          = "appResources"; // RelativeFileSet //KEY
  46     public static final String PARAM_TYPE                   = "type"; // BundlerType
  47     public static final String PARAM_BUNDLE_FORMAT          = "bundleFormat"; // String
  48     public static final String PARAM_ICON                   = "icon"; // String //KEY
  49 
  50     /* Name of bundle file and native launcher.
  51        Also used as CFBundleName on Mac */
  52     public static final String PARAM_APP_NAME               = "appName"; // String //KEY
  53     public static final String PARAM_NAME                   = "name"; // String //KEY
  54 
  55     /* application vendor, used by most of the bundlers */
  56     public static final String PARAM_VENDOR                 = "vendor"; // String //KEY
  57 
  58     /* email name and email, only used for debian */
  59     public static final String PARAM_EMAIL                  = "email"; // String  //KEY
  60 
  61     /* Copyright. Used on Mac */
  62     public static final String PARAM_COPYRIGHT              = "copyright"; // String //KEY
  63 
  64     /* GUID on windows for MSI, CFBundleIdentifier on Mac
  65        If not compatible with requirements then bundler either do not bundle
  66        or autogenerate */
  67     public static final String PARAM_IDENTIFIER             = "identifier"; // String  //KEY
  68 
  69     /* shortcut preferences */
  70     public static final String PARAM_SHORTCUT               = "shortcutHint"; // boolean //KEY
  71     public static final String PARAM_MENU                   = "menuHint"; // boolean //KEY
  72 
  73     /* Application version. Format may differ for different bundlers */
  74     public static final String PARAM_VERSION                = "appVersion"; // String //KEY
  75     /* Application category. Used at least on Mac/Linux. Value is platform specific */
  76     public static final String PARAM_CATEGORY               = "applicationCategory"; // String //KEY
  77 
  78     /* Optional short application */
  79     public static final String PARAM_TITLE                  = "title"; // String //KEY
  80 
  81     /* Optional application description. Used by MSI and on Linux */
  82     public static final String PARAM_DESCRIPTION            = "description"; // String //KEY
  83 
  84     /* License type. Needed on Linux (rpm) */
  85     public static final String PARAM_LICENSE_TYPE           = "licenseType"; // String //KEY
  86 
  87     /* File(s) with license. Format is OS/bundler specific */
  88     public static final String PARAM_LICENSE_FILES          = "licenseFiles"; // List<String> //KEY
  89 
  90     /* user or system level install.
  91        null means "default" */
  92     public static final String PARAM_SYSTEM_WIDE            = "systemWide"; // Boolean //KEY
  93 
  94     /* Main application class. Not used directly but used to derive default values */
  95     public static final String PARAM_APPLICATION_CLASS      = "applicationClass"; // String //KEY
  96 
  97     //list of jvm args (in theory string can contain spaces and need to be escaped
  98     private List<String> jvmargs = new LinkedList<>();
  99     //list of jvm args (in theory string can contain spaces and need to be escaped
 100     private Map<String, String> jvmUserArgs = new HashMap<>();
 101 
 102     //list of jvm properties (can also be passed as VM args
 103     private Map<String, String> jvmProperties = new HashMap<>();
 104 
 105     /**
 106      * create a new bundle with all default values
 107      */
 108     public BundleParams() {
 109         params = new HashMap<>();
 110     }
 111 
 112     /**
 113      * Create a bundle params with a copy of the params 
 114      * @param params map of initial parameters to be copied in.
 115      */


 163     public void setJvmProperties(Map<String, String> jvmProperties) {
 164         this.jvmProperties = jvmProperties;
 165     }
 166 
 167     public List<String> getAllJvmOptions() {
 168         List<String> all = new LinkedList<>();
 169         all.addAll(jvmargs);
 170         for(String k: jvmProperties.keySet()) {
 171             all.add("-D"+k+"="+jvmProperties.get(k)); //TODO: We are not escaping values here...
 172         }
 173         return all;
 174     }
 175 
 176     public Map<String, String> getAllJvmUserOptions() {
 177         Map<String, String> all = new HashMap<>();
 178         all.putAll(jvmUserArgs);
 179         return all;
 180     }
 181 
 182     public String getApplicationID() {
 183         return fetchParam(StandardBundlerParam.IDENTIFIER);        
 184     }
 185 
 186     public String getPreferencesID() {
 187         return fetchParam(StandardBundlerParam.PREFERENCES_ID);
 188     }
 189 
 190     public String getTitle() {
 191         return fetchParam(StandardBundlerParam.TITLE); //FIXME title
 192     }
 193 
 194     public void setTitle(String title) {
 195         putUnlessNull(PARAM_TITLE, title);
 196     }
 197 
 198     public String getApplicationClass() {
 199         return fetchParam(StandardBundlerParam.MAIN_CLASS);
 200     }
 201 
 202     public void setApplicationClass(String applicationClass) {
 203         putUnlessNull(PARAM_APPLICATION_CLASS, applicationClass);
 204     }
 205 
 206     public String getAppVersion() {
 207         return fetchParam(StandardBundlerParam.VERSION);
 208     }
 209 
 210     public void setAppVersion(String version) {
 211         putUnlessNull(PARAM_VERSION, version);
 212     }
 213 
 214     public String getDescription() {
 215         return fetchParam(StandardBundlerParam.NAME); //FIXME DESCRIPTION);
 216     }
 217 
 218     public void setDescription(String s) {
 219         putUnlessNull(PARAM_DESCRIPTION, s);
 220     }
 221 
 222     public String getLicenseType() {
 223         return fetchParam(StandardBundlerParam.LICENSE_TYPE); //FIXME
 224     }
 225 
 226     public void setLicenseType(String version) {
 227         putUnlessNull(PARAM_LICENSE_TYPE, version);
 228     }
 229 
 230     //path is relative to the application root
 231     public void addLicenseFile(String path) {
 232         @SuppressWarnings("unchecked") 
 233         List<String> licenseFile = fetchParam(List.class, PARAM_LICENSE_FILES);
 234         if (licenseFile == null) {
 235             licenseFile = new ArrayList<>();
 236             params.put(PARAM_LICENSE_FILES, licenseFile);
 237         }
 238         licenseFile.add(path);
 239     }
 240 
 241     public Boolean getSystemWide() {
 242         return fetchParam(StandardBundlerParam.SYSTEM_WIDE);
 243     }
 244 
 245     public void setSystemWide(Boolean b) {
 246         putUnlessNull(PARAM_SYSTEM_WIDE, b);
 247     }
 248 
 249     public RelativeFileSet getRuntime() {
 250         return fetchParam(StandardBundlerParam.RUNTIME);
 251     }
 252 
 253     public boolean isShortcutHint() {
 254         return fetchParam(StandardBundlerParam.SHORTCUT_HINT);
 255     }
 256 
 257     public void setShortcutHint(boolean v) {
 258         putUnlessNull(PARAM_SHORTCUT, v);
 259     }
 260 
 261     public boolean isMenuHint() {
 262         return fetchParam(StandardBundlerParam.MENU_HINT);
 263     }
 264 
 265     public void setMenuHint(boolean v) {
 266         putUnlessNull(PARAM_MENU, v);
 267     }
 268 
 269     public String getName() {
 270         return fetchParam(StandardBundlerParam.NAME);
 271     }
 272 
 273     public void setName(String name) {
 274         putUnlessNull(PARAM_NAME, name);
 275     }
 276 
 277     public BundleType getType() {
 278         return fetchParam(BundleType.class, PARAM_TYPE); 
 279     }
 280 
 281     public void setType(BundleType type) {
 282         putUnlessNull(PARAM_TYPE, type);
 283     }
 284 
 285     public String getBundleFormat() {
 286         return fetchParam(String.class, PARAM_BUNDLE_FORMAT); 
 287     }
 288     
 289     public void setBundleFormat(String t) {
 290         putUnlessNull(PARAM_BUNDLE_FORMAT, t);
 291     }
 292 
 293     public static boolean shouldExclude(File baseDir, File f, Rule ruleset[]) {
 294         if (ruleset == null) {
 295             return false;
 296         }
 297 
 298         String fname = f.getAbsolutePath().toLowerCase().substring(
 299                 baseDir.getAbsolutePath().length());
 300         //first rule match defines the answer
 301         for (Rule r: ruleset) {
 302             if (r.match(fname)) {
 303                 return !r.treatAsAccept();
 304             }
 305         }
 306         //default is include
 307         return false;
 308     }
 309 
 310     public static void walk(File base, File root, Rule ruleset[], Set<File> files) {
 311         if (!root.isDirectory()) {
 312             if (root.isFile()) {
 313                 files.add(root);
 314             }
 315             return;
 316         }
 317 
 318         File[] lst = root.listFiles();
 319         if (lst != null) {
 320             for (File f : lst) {
 321                 //ignore symbolic links!
 322                 if (IOUtils.isNotSymbolicLink(f) && !shouldExclude(base, f, ruleset)) {
 323                     if (f.isDirectory()) {
 324                         walk(base, f, ruleset, files);
 325                     } else if (f.isFile()) {
 326                         //add to list
 327                         files.add(f);
 328                     }
 329                 }
 330             }
 331         }
 332     }
 333 
 334     
 335     @SuppressWarnings("unchecked")
 336     public List<String> getLicenseFile() {
 337         return fetchParam(List.class, PARAM_LICENSE_FILES);
 338     }
 339 
 340     public List<String> getJvmargs() {
 341         return jvmargs;
 342     }
 343 
 344     public static class Rule {
 345         String regex;
 346         boolean includeRule;
 347         Type type;
 348         enum Type {SUFFIX, PREFIX, SUBSTR, REGEX}
 349 
 350         private Rule(String regex, boolean includeRule, Type type) {
 351             this.regex = regex;
 352             this.type = type;
 353             this.includeRule = includeRule;
 354         }
 355 
 356         boolean match(String str) {
 357             if (type == Type.SUFFIX) {
 358                 return str.endsWith(regex);
 359             }
 360             if (type == Type.PREFIX) {
 361                 return str.startsWith(regex);
 362             }
 363             if (type == Type.SUBSTR) {
 364                 return str.contains(regex);
 365             }
 366             return str.matches(regex);
 367         }
 368 
 369         boolean treatAsAccept() {return includeRule;}
 370 
 371         static Rule suffix(String s) {
 372             return new Rule(s, true, Type.SUFFIX);
 373         }
 374         static Rule suffixNeg(String s) {
 375             return new Rule(s, false, Type.SUFFIX);
 376         }
 377         static Rule prefix(String s) {
 378             return new Rule(s, true, Type.PREFIX);
 379         }
 380         static Rule prefixNeg(String s) {
 381             return new Rule(s, false, Type.PREFIX);
 382         }
 383         static Rule substr(String s) {
 384             return new Rule(s, true, Type.SUBSTR);
 385         }
 386         static Rule substrNeg(String s) {
 387             return new Rule(s, false, Type.SUBSTR);
 388         }
 389     }
 390 
 391     //Subsetting of JRE is restricted.
 392     //JRE README defines what is allowed to strip:
 393     //   http://www.oracle.com/technetwork/java/javase/jre-7-readme-430162.html
 394     //
 395     //In addition to this we may need to keep deploy jars and deploy.dll
 396     // because JavaFX apps might need JNLP services
 397     //Also, embedded launcher uses deploy.jar to access registry
 398     // (although this is not needed)
 399     public static Rule macRules[] = {
 400         Rule.suffixNeg("macos/libjli.dylib"),
 401         Rule.suffixNeg("resources"),
 402         Rule.suffixNeg("home/bin"),
 403         Rule.suffixNeg("home/db"),
 404         Rule.suffixNeg("home/demo"),
 405         Rule.suffixNeg("home/include"),
 406         Rule.suffixNeg("home/lib"),
 407         Rule.suffixNeg("home/man"),
 408         Rule.suffixNeg("home/release"),
 409         Rule.suffixNeg("home/sample"),
 410         Rule.suffixNeg("home/src.zip"),
 411         //"home/rt" is not part of the official builds
 412         // but we may be creating this symlink to make older NB projects
 413         // happy. Make sure to not include it into final artifact
 414         Rule.suffixNeg("home/rt"),
 415         Rule.suffixNeg("jre/bin"),
 416         Rule.suffixNeg("jre/bin/rmiregistry"),
 417         Rule.suffixNeg("jre/bin/tnameserv"),
 418         Rule.suffixNeg("jre/bin/keytool"),
 419         Rule.suffixNeg("jre/bin/klist"),
 420         Rule.suffixNeg("jre/bin/ktab"),
 421         Rule.suffixNeg("jre/bin/policytool"),
 422         Rule.suffixNeg("jre/bin/orbd"),
 423         Rule.suffixNeg("jre/bin/servertool"),
 424         Rule.suffixNeg("jre/bin/javaws"),
 425         Rule.suffixNeg("jre/bin/java"),
 426 //        Rule.suffixNeg("jre/lib/ext"), //need some of jars there for https to work
 427         Rule.suffixNeg("jre/lib/nibs"),
 428 //keep core deploy APIs but strip plugin dll
 429 //        Rule.suffixNeg("jre/lib/deploy"),
 430 //        Rule.suffixNeg("jre/lib/deploy.jar"),
 431 //        Rule.suffixNeg("jre/lib/javaws.jar"),
 432 //        Rule.suffixNeg("jre/lib/libdeploy.dylib"),
 433 //        Rule.suffixNeg("jre/lib/plugin.jar"),
 434         Rule.suffixNeg("jre/lib/libnpjp2.dylib"),
 435         Rule.suffixNeg("jre/lib/security/javaws.policy")
 436     };
 437 
 438     public static Rule[] winRules = {
 439         Rule.prefixNeg("\\bin\\new_plugin"),
 440         Rule.suffix("deploy.jar"), //take deploy.jar
 441         Rule.prefixNeg("\\lib\\deploy"),
 442         Rule.suffixNeg(".pdb"),
 443         Rule.suffixNeg(".map"),
 444         Rule.suffixNeg("axbridge.dll"),
 445         Rule.suffixNeg("eula.dll"),
 446         Rule.substrNeg("javacpl"),
 447         Rule.suffixNeg("wsdetect.dll"),
 448         Rule.substrNeg("eployjava1.dll"), //NP and IE versions
 449         Rule.substrNeg("bin\\jp2"),
 450         Rule.substrNeg("bin\\jpi"),
 451 //        Rule.suffixNeg("lib\\ext"), //need some of jars there for https to work
 452         Rule.suffixNeg("ssv.dll"),
 453         Rule.substrNeg("npjpi"),
 454         Rule.substrNeg("npoji"),
 455         Rule.suffixNeg(".exe"),
 456 //keep core deploy files as JavaFX APIs use them
 457 //        Rule.suffixNeg("deploy.dll"),
 458 //        Rule.suffixNeg("deploy.jar"),
 459 //        Rule.suffixNeg("javaws.jar"),
 460 //        Rule.suffixNeg("plugin.jar"),
 461         Rule.suffix(".jar")
 462     };
 463 
 464     public static Rule[] linuxRules = {
 465         Rule.prefixNeg("/bin"),
 466         Rule.prefixNeg("/plugin"),
 467 //        Rule.prefixNeg("/lib/ext"), //need some of jars there for https to work
 468         Rule.suffix("deploy.jar"), //take deploy.jar
 469         Rule.prefixNeg("/lib/deploy"),
 470         Rule.prefixNeg("/lib/desktop"),
 471         Rule.substrNeg("libnpjp2.so")
 472     };
 473 
 474     //Validation approach:
 475     //  - JRE marker (rt.jar)
 476     //  - FX marker (jfxrt.jar)
 477     //  - JDK marker (tools.jar)
 478     private static boolean checkJDKRoot(File jdkRoot) {
 479         File rtJar = new File(jdkRoot, "jre/lib/rt.jar");
 480         if (!rtJar.exists()) {
 481             Log.verbose("rt.jar is not found at " + rtJar.getAbsolutePath());
 482             return false;
 483         }
 484 
 485         File jfxJar = new File(jdkRoot, "jre/lib/ext/jfxrt.jar");
 486         if (!jfxJar.exists()) {
 487             //Try again with new location
 488             jfxJar = new File(jdkRoot, "jre/lib/jfxrt.jar");
 489             if (!jfxJar.exists()) {
 490                 Log.verbose("jfxrt.jar is not found at " + jfxJar.getAbsolutePath());
 491                 return false;
 492             }
 493         }


 546     //select subset of given runtime using predefined rules
 547     public void setRuntime(File baseDir) {
 548         baseDir = validateRuntimeLocation(baseDir);
 549 
 550         //mistake or explicit intent to use system runtime
 551         if (baseDir == null) {
 552             Log.verbose("No Java runtime to embed. Package will need system Java.");
 553             params.put(PARAM_RUNTIME, null);
 554             return;
 555         }
 556         doSetRuntime(baseDir);
 557     }
 558 
 559     public void setDefaultRuntime() {
 560         File f = new File(System.getProperty("java.home"));
 561         doSetRuntime(f);
 562     }
 563 
 564     //input dir "jdk/jre" (i.e. jre folder in the jdk)
 565     private void doSetRuntime(File baseDir) {
 566         boolean isMac = System.getProperty("os.name").toLowerCase().contains("os x");
 567 
 568         //Normalization: on MacOS we need to point to the top of JDK dir
 569         // (other platforms are fine)
 570         if (isMac) {
 571             //On Mac we need Bundle root, not jdk/Contents/Home
 572             baseDir = baseDir.getParentFile().getParentFile().getParentFile();
 573         }
 574 
 575         Set<File> lst = new HashSet<>();
 576 
 577         Rule ruleset[];
 578         if (System.getProperty("os.name").startsWith("Mac")) {
 579             ruleset = macRules;
 580         } else if (System.getProperty("os.name").startsWith("Win")) {
 581             ruleset = winRules;
 582         } else {
 583             //must be linux
 584             ruleset = linuxRules;
 585         }
 586 
 587         walk(baseDir, baseDir, ruleset, lst);
 588 
 589         params.put(PARAM_RUNTIME, new RelativeFileSet(baseDir, lst));
 590     }
 591 
 592     //Currently unused?
 593     //
 594     //public void setRuntime(RelativeFileSet fs) {
 595     //       runtime = fs;
 596     //}
 597 
 598     public RelativeFileSet getAppResource() {
 599         return fetchParam(StandardBundlerParam.APP_RESOURCES);
 600     }
 601 
 602     public void setAppResource(RelativeFileSet fs) {
 603         putUnlessNull(PARAM_APP_RESOURCES, fs);
 604     }
 605 
 606     public File getIcon() {
 607         return fetchParam(StandardBundlerParam.ICON);
 608     }
 609 
 610     public void setIcon(File icon) {
 611         putUnlessNull(PARAM_ICON, icon);
 612     }
 613 
 614     public String getApplicationCategory() {
 615         return fetchParam(String.class, PARAM_CATEGORY); //FIXME
 616     }
 617 
 618     public void setApplicationCategory(String category) {
 619         putUnlessNull(PARAM_CATEGORY, category);
 620     }
 621 
 622     public String getMainClassName() {
 623         String applicationClass = getApplicationClass();
 624         
 625         if (applicationClass == null) {
 626             return null;
 627         }
 628 
 629         int idx = applicationClass.lastIndexOf(".");
 630         if (idx >= 0) {
 631             return applicationClass.substring(idx+1);
 632         }
 633         return applicationClass;
 634     }
 635 
 636     public String getCopyright() {
 637         return fetchParam(StandardBundlerParam.COPYRIGHT);
 638     }
 639 
 640     public void setCopyright(String c) {
 641         putUnlessNull(PARAM_COPYRIGHT, c);
 642     }
 643 
 644     public String getIdentifier() {
 645         return fetchParam(StandardBundlerParam.IDENTIFIER);
 646     }
 647 
 648     public void setIdentifier(String s) {
 649         putUnlessNull(PARAM_IDENTIFIER, s);
 650     }
 651 
 652     private String mainJar = null;
 653     private String mainJarClassPath = null;
 654     private boolean useFXPackaging = true;
 655 
 656     //are we packaging JavaFX application or regular executable Jar?
 657     public boolean useJavaFXPackaging() {
 658         if (mainJar == null) {
 659             //this will find out answer
 660             getMainApplicationJar();
 661         }
 662         return useFXPackaging;
 663     }
 664 
 665     //For regular executable Jars we need to take care of classpath


 703                 Attributes attrs = (m != null) ? m.getMainAttributes() : null;
 704                 if (attrs != null) {
 705                     boolean javaMain = applicationClass.equals(
 706                                attrs.getValue(Attributes.Name.MAIN_CLASS));
 707                     boolean fxMain = applicationClass.equals(
 708                                attrs.getValue(PackagerLib.MANIFEST_JAVAFX_MAIN));
 709                     if (javaMain || fxMain) {
 710                         useFXPackaging = fxMain;
 711                         mainJar = fname;
 712                         mainJarClassPath = attrs.getValue(Attributes.Name.CLASS_PATH);
 713                         return mainJar;
 714                     }
 715                 }
 716             } catch (IOException ignore) {
 717             }
 718         }
 719         return null;
 720     }
 721 
 722     public String getVendor() {
 723         return fetchParam(StandardBundlerParam.VENDOR);
 724     }
 725 
 726     public void setVendor(String vendor) {
 727        putUnlessNull(PARAM_VENDOR, vendor);
 728     }
 729 
 730     public String getEmail() {
 731         return fetchParam(String.class, PARAM_EMAIL);
 732     }
 733 
 734     public void setEmail(String email) {
 735         putUnlessNull(PARAM_EMAIL, email);
 736     }
 737     
 738     public void putUnlessNull(String param, Object value) {
 739         if (value != null) {
 740             params.put(param, value);
 741         }
 742     }
 743 


   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.tools.packager.bundlers;
  27 
  28 import com.oracle.bundlers.BundlerParamInfo;

  29 import com.sun.javafx.tools.packager.Log;
  30 import com.sun.javafx.tools.packager.PackagerLib;
  31 
  32 import java.io.File;
  33 import java.io.IOException;
  34 import java.util.*;
  35 import java.util.jar.Attributes;
  36 import java.util.jar.JarFile;
  37 import java.util.jar.Manifest;
  38 
  39 import static com.oracle.bundlers.StandardBundlerParam.*;
  40 
  41 public class BundleParams {
  42       
  43     final protected Map<String, ? super Object> params;
  44     
  45     public static final String PARAM_RUNTIME                = "runtime"; // RelativeFileSet
  46     public static final String PARAM_APP_RESOURCES          = "appResources"; // RelativeFileSet
  47     public static final String PARAM_TYPE                   = "type"; // BundlerType
  48     public static final String PARAM_BUNDLE_FORMAT          = "bundleFormat"; // String
  49     public static final String PARAM_ICON                   = "icon"; // String
  50 
  51     /* Name of bundle file and native launcher */
  52     public static final String PARAM_NAME                   = "name"; // String


  53 
  54     /* application vendor, used by most of the bundlers */
  55     public static final String PARAM_VENDOR                 = "vendor"; // String
  56 
  57     /* email name and email, only used for debian */
  58     public static final String PARAM_EMAIL                  = "email"; // String
  59 
  60     /* Copyright. Used on Mac */
  61     public static final String PARAM_COPYRIGHT              = "copyright"; // String
  62 
  63     /* GUID on windows for MSI, CFBundleIdentifier on Mac
  64        If not compatible with requirements then bundler either do not bundle
  65        or autogenerate */
  66     public static final String PARAM_IDENTIFIER             = "identifier"; // String
  67 
  68     /* shortcut preferences */
  69     public static final String PARAM_SHORTCUT               = "shortcutHint"; // boolean
  70     public static final String PARAM_MENU                   = "menuHint"; // boolean
  71 
  72     /* Application version. Format may differ for different bundlers */
  73     public static final String PARAM_VERSION                = "appVersion"; // String
  74     /* Application category. Used at least on Mac/Linux. Value is platform specific */
  75     public static final String PARAM_CATEGORY               = "applicationCategory"; // String
  76 
  77     /* Optional short application */
  78     public static final String PARAM_TITLE                  = "title"; // String
  79 
  80     /* Optional application description. Used by MSI and on Linux */
  81     public static final String PARAM_DESCRIPTION            = "description"; // String
  82 
  83     /* License type. Needed on Linux (rpm) */
  84     public static final String PARAM_LICENSE_TYPE           = "licenseType"; // String
  85 
  86     /* File(s) with license. Format is OS/bundler specific */
  87     public static final String PARAM_LICENSE_FILES          = "licenseFiles"; // List<String>
  88 
  89     /* user or system level install.
  90        null means "default" */
  91     public static final String PARAM_SYSTEM_WIDE            = "systemWide"; // Boolean
  92 
  93     /* Main application class. Not used directly but used to derive default values */
  94     public static final String PARAM_APPLICATION_CLASS      = "applicationClass"; // String
  95 
  96     //list of jvm args (in theory string can contain spaces and need to be escaped
  97     private List<String> jvmargs = new LinkedList<>();
  98     //list of jvm args (in theory string can contain spaces and need to be escaped
  99     private Map<String, String> jvmUserArgs = new HashMap<>();
 100 
 101     //list of jvm properties (can also be passed as VM args
 102     private Map<String, String> jvmProperties = new HashMap<>();
 103 
 104     /**
 105      * create a new bundle with all default values
 106      */
 107     public BundleParams() {
 108         params = new HashMap<>();
 109     }
 110 
 111     /**
 112      * Create a bundle params with a copy of the params 
 113      * @param params map of initial parameters to be copied in.
 114      */


 162     public void setJvmProperties(Map<String, String> jvmProperties) {
 163         this.jvmProperties = jvmProperties;
 164     }
 165 
 166     public List<String> getAllJvmOptions() {
 167         List<String> all = new LinkedList<>();
 168         all.addAll(jvmargs);
 169         for(String k: jvmProperties.keySet()) {
 170             all.add("-D"+k+"="+jvmProperties.get(k)); //TODO: We are not escaping values here...
 171         }
 172         return all;
 173     }
 174 
 175     public Map<String, String> getAllJvmUserOptions() {
 176         Map<String, String> all = new HashMap<>();
 177         all.putAll(jvmUserArgs);
 178         return all;
 179     }
 180 
 181     public String getApplicationID() {
 182         return fetchParam(IDENTIFIER);
 183     }
 184 
 185     public String getPreferencesID() {
 186         return fetchParam(PREFERENCES_ID);
 187     }
 188 
 189     public String getTitle() {
 190         return fetchParam(TITLE);
 191     }
 192 
 193     public void setTitle(String title) {
 194         putUnlessNull(PARAM_TITLE, title);
 195     }
 196 
 197     public String getApplicationClass() {
 198         return fetchParam(MAIN_CLASS);
 199     }
 200 
 201     public void setApplicationClass(String applicationClass) {
 202         putUnlessNull(PARAM_APPLICATION_CLASS, applicationClass);
 203     }
 204 
 205     public String getAppVersion() {
 206         return fetchParam(VERSION);
 207     }
 208 
 209     public void setAppVersion(String version) {
 210         putUnlessNull(PARAM_VERSION, version);
 211     }
 212 
 213     public String getDescription() {
 214         return fetchParam(DESCRIPTION);
 215     }
 216 
 217     public void setDescription(String s) {
 218         putUnlessNull(PARAM_DESCRIPTION, s);
 219     }
 220 
 221     public String getLicenseType() {
 222         return fetchParam(LICENSE_TYPE);
 223     }
 224 
 225     public void setLicenseType(String version) {
 226         putUnlessNull(PARAM_LICENSE_TYPE, version);
 227     }
 228 
 229     //path is relative to the application root
 230     public void addLicenseFile(String path) {
 231         List<String> licenseFile = fetchParam(LICENSE_FILES);

 232         if (licenseFile == null) {
 233             licenseFile = new ArrayList<>();
 234             params.put(PARAM_LICENSE_FILES, licenseFile);
 235         }
 236         licenseFile.add(path);
 237     }
 238 
 239     public Boolean getSystemWide() {
 240         return fetchParam(SYSTEM_WIDE);
 241     }
 242 
 243     public void setSystemWide(Boolean b) {
 244         putUnlessNull(PARAM_SYSTEM_WIDE, b);
 245     }
 246 
 247     public RelativeFileSet getRuntime() {
 248         return fetchParam(RUNTIME);
 249     }
 250 
 251     public boolean isShortcutHint() {
 252         return fetchParam(SHORTCUT_HINT);
 253     }
 254 
 255     public void setShortcutHint(boolean v) {
 256         putUnlessNull(PARAM_SHORTCUT, v);
 257     }
 258 
 259     public boolean isMenuHint() {
 260         return fetchParam(MENU_HINT);
 261     }
 262 
 263     public void setMenuHint(boolean v) {
 264         putUnlessNull(PARAM_MENU, v);
 265     }
 266 
 267     public String getName() {
 268         return fetchParam(APP_NAME);
 269     }
 270 
 271     public void setName(String name) {
 272         putUnlessNull(PARAM_NAME, name);
 273     }
 274 
 275     public BundleType getType() {
 276         return fetchParam(BundleType.class, PARAM_TYPE); 
 277     }
 278 
 279     public void setType(BundleType type) {
 280         putUnlessNull(PARAM_TYPE, type);
 281     }
 282 
 283     public String getBundleFormat() {
 284         return fetchParam(String.class, PARAM_BUNDLE_FORMAT); 
 285     }
 286     
 287     public void setBundleFormat(String t) {
 288         putUnlessNull(PARAM_BUNDLE_FORMAT, t);
 289     }
 290 
























 291 


















 292     public List<String> getLicenseFile() {
 293         return fetchParam(LICENSE_FILES);
 294     }
 295 
 296     public List<String> getJvmargs() {
 297         return jvmargs;
 298     }
 299 


































































































































 300     //Validation approach:
 301     //  - JRE marker (rt.jar)
 302     //  - FX marker (jfxrt.jar)
 303     //  - JDK marker (tools.jar)
 304     private static boolean checkJDKRoot(File jdkRoot) {
 305         File rtJar = new File(jdkRoot, "jre/lib/rt.jar");
 306         if (!rtJar.exists()) {
 307             Log.verbose("rt.jar is not found at " + rtJar.getAbsolutePath());
 308             return false;
 309         }
 310 
 311         File jfxJar = new File(jdkRoot, "jre/lib/ext/jfxrt.jar");
 312         if (!jfxJar.exists()) {
 313             //Try again with new location
 314             jfxJar = new File(jdkRoot, "jre/lib/jfxrt.jar");
 315             if (!jfxJar.exists()) {
 316                 Log.verbose("jfxrt.jar is not found at " + jfxJar.getAbsolutePath());
 317                 return false;
 318             }
 319         }


 372     //select subset of given runtime using predefined rules
 373     public void setRuntime(File baseDir) {
 374         baseDir = validateRuntimeLocation(baseDir);
 375 
 376         //mistake or explicit intent to use system runtime
 377         if (baseDir == null) {
 378             Log.verbose("No Java runtime to embed. Package will need system Java.");
 379             params.put(PARAM_RUNTIME, null);
 380             return;
 381         }
 382         doSetRuntime(baseDir);
 383     }
 384 
 385     public void setDefaultRuntime() {
 386         File f = new File(System.getProperty("java.home"));
 387         doSetRuntime(f);
 388     }
 389 
 390     //input dir "jdk/jre" (i.e. jre folder in the jdk)
 391     private void doSetRuntime(File baseDir) {
 392         params.put(PARAM_RUNTIME, baseDir.toString());























 393     }
 394 
 395     //Currently unused?
 396     //
 397     //public void setRuntime(RelativeFileSet fs) {
 398     //       runtime = fs;
 399     //}
 400 
 401     public RelativeFileSet getAppResource() {
 402         return fetchParam(APP_RESOURCES);
 403     }
 404 
 405     public void setAppResource(RelativeFileSet fs) {
 406         putUnlessNull(PARAM_APP_RESOURCES, fs);
 407     }
 408 
 409     public File getIcon() {
 410         return fetchParam(ICON);
 411     }
 412 
 413     public void setIcon(File icon) {
 414         putUnlessNull(PARAM_ICON, icon);
 415     }
 416 
 417     public String getApplicationCategory() {
 418         return fetchParam(CATEGORY);
 419     }
 420 
 421     public void setApplicationCategory(String category) {
 422         putUnlessNull(PARAM_CATEGORY, category);
 423     }
 424 
 425     public String getMainClassName() {
 426         String applicationClass = getApplicationClass();
 427         
 428         if (applicationClass == null) {
 429             return null;
 430         }
 431 
 432         int idx = applicationClass.lastIndexOf(".");
 433         if (idx >= 0) {
 434             return applicationClass.substring(idx+1);
 435         }
 436         return applicationClass;
 437     }
 438 
 439     public String getCopyright() {
 440         return fetchParam(COPYRIGHT);
 441     }
 442 
 443     public void setCopyright(String c) {
 444         putUnlessNull(PARAM_COPYRIGHT, c);
 445     }
 446 
 447     public String getIdentifier() {
 448         return fetchParam(IDENTIFIER);
 449     }
 450 
 451     public void setIdentifier(String s) {
 452         putUnlessNull(PARAM_IDENTIFIER, s);
 453     }
 454 
 455     private String mainJar = null;
 456     private String mainJarClassPath = null;
 457     private boolean useFXPackaging = true;
 458 
 459     //are we packaging JavaFX application or regular executable Jar?
 460     public boolean useJavaFXPackaging() {
 461         if (mainJar == null) {
 462             //this will find out answer
 463             getMainApplicationJar();
 464         }
 465         return useFXPackaging;
 466     }
 467 
 468     //For regular executable Jars we need to take care of classpath


 506                 Attributes attrs = (m != null) ? m.getMainAttributes() : null;
 507                 if (attrs != null) {
 508                     boolean javaMain = applicationClass.equals(
 509                                attrs.getValue(Attributes.Name.MAIN_CLASS));
 510                     boolean fxMain = applicationClass.equals(
 511                                attrs.getValue(PackagerLib.MANIFEST_JAVAFX_MAIN));
 512                     if (javaMain || fxMain) {
 513                         useFXPackaging = fxMain;
 514                         mainJar = fname;
 515                         mainJarClassPath = attrs.getValue(Attributes.Name.CLASS_PATH);
 516                         return mainJar;
 517                     }
 518                 }
 519             } catch (IOException ignore) {
 520             }
 521         }
 522         return null;
 523     }
 524 
 525     public String getVendor() {
 526         return fetchParam(VENDOR);
 527     }
 528 
 529     public void setVendor(String vendor) {
 530        putUnlessNull(PARAM_VENDOR, vendor);
 531     }
 532 
 533     public String getEmail() {
 534         return fetchParam(String.class, PARAM_EMAIL);
 535     }
 536 
 537     public void setEmail(String email) {
 538         putUnlessNull(PARAM_EMAIL, email);
 539     }
 540     
 541     public void putUnlessNull(String param, Object value) {
 542         if (value != null) {
 543             params.put(param, value);
 544         }
 545     }
 546