< prev index next >

src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java

Print this page




  71             "Info-lite.plist.template";
  72     private static final String TEMPLATE_RUNTIME_INFO_PLIST =
  73             "Runtime-Info.plist.template";
  74 
  75     private final Path root;
  76     private final Path contentsDir;
  77     private final Path javaDir;
  78     private final Path javaModsDir;
  79     private final Path resourcesDir;
  80     private final Path macOSDir;
  81     private final Path runtimeDir;
  82     private final Path runtimeRoot;
  83     private final Path mdir;
  84 
  85     private final Map<String, ? super Object> params;
  86 
  87     private static List<String> keyChains;
  88 
  89     public static final BundlerParamInfo<Boolean>
  90             MAC_CONFIGURE_LAUNCHER_IN_PLIST = new StandardBundlerParam<>(
  91                     I18N.getString("param.configure-launcher-in-plist"),
  92                     I18N.getString(
  93                             "param.configure-launcher-in-plist.description"),
  94                     "mac.configure-launcher-in-plist",
  95                     Boolean.class,
  96                     params -> Boolean.FALSE,
  97                     (s, p) -> Boolean.valueOf(s));
  98 
  99     public static final BundlerParamInfo<String> MAC_CATEGORY =
 100             new StandardBundlerParam<>(
 101                     I18N.getString("param.category-name"),
 102                     I18N.getString("param.category-name.description"),
 103                     "mac.category",
 104                     String.class,
 105                     CATEGORY::fetchFrom,
 106                     (s, p) -> s
 107             );
 108 
 109     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_NAME =
 110             new StandardBundlerParam<>(
 111                     I18N.getString("param.cfbundle-name.name"),
 112                     I18N.getString("param.cfbundle-name.description"),
 113                     "mac.CFBundleName",
 114                     String.class,
 115                     params -> null,
 116                     (s, p) -> s);
 117 
 118     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_IDENTIFIER =
 119             new StandardBundlerParam<>(
 120                     I18N.getString("param.cfbundle-identifier.name"),
 121                     I18N.getString("param.cfbundle-identifier.description"),
 122                     Arguments.CLIOptions.MAC_BUNDLE_IDENTIFIER.getId(),
 123                     String.class,
 124                     IDENTIFIER::fetchFrom,
 125                     (s, p) -> s);
 126 
 127     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_VERSION =
 128             new StandardBundlerParam<>(
 129                     I18N.getString("param.cfbundle-version.name"),
 130                     I18N.getString("param.cfbundle-version.description"),
 131                     "mac.CFBundleVersion",
 132                     String.class,
 133                     p -> {
 134                         String s = VERSION.fetchFrom(p);
 135                         if (validCFBundleVersion(s)) {
 136                             return s;
 137                         } else {
 138                             return "100";
 139                         }
 140                     },
 141                     (s, p) -> s);
 142 
 143     public static final BundlerParamInfo<String> DEFAULT_ICNS_ICON =
 144             new StandardBundlerParam<>(
 145             I18N.getString("param.default-icon-icns"),
 146             I18N.getString("param.default-icon-icns.description"),
 147             ".mac.default.icns",
 148             String.class,
 149             params -> TEMPLATE_BUNDLE_ICON,
 150             (s, p) -> s);
 151 
 152     public static final BundlerParamInfo<File> ICON_ICNS =
 153             new StandardBundlerParam<>(
 154             I18N.getString("param.icon-icns.name"),
 155             I18N.getString("param.icon-icns.description"),
 156             "icon.icns",
 157             File.class,
 158             params -> {
 159                 File f = ICON.fetchFrom(params);
 160                 if (f != null && !f.getName().toLowerCase().endsWith(".icns")) {
 161                     Log.error(MessageFormat.format(
 162                             I18N.getString("message.icon-not-icns"), f));
 163                     return null;
 164                 }
 165                 return f;
 166             },
 167             (s, p) -> new File(s));
 168 
 169     public static final StandardBundlerParam<Boolean> SIGN_BUNDLE  =
 170             new StandardBundlerParam<>(
 171             I18N.getString("param.sign-bundle.name"),
 172             I18N.getString("param.sign-bundle.description"),
 173             Arguments.CLIOptions.MAC_SIGN.getId(),
 174             Boolean.class,
 175             params -> false,
 176             // valueOf(null) is false, we actually do want null in some cases
 177             (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ?
 178                     null : Boolean.valueOf(s)
 179         );
 180 
 181     public MacAppImageBuilder(Map<String, Object> config, Path imageOutDir)
 182             throws IOException {
 183         super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config)
 184                 + ".app/Contents/PlugIns/Java.runtime/Contents/Home"));
 185 
 186         Objects.requireNonNull(imageOutDir);
 187 
 188         this.params = config;
 189         this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params) + ".app");
 190         this.contentsDir = root.resolve("Contents");
 191         this.javaDir = contentsDir.resolve("Java");
 192         this.javaModsDir = javaDir.resolve("mods");


 317         // Generate PkgInfo
 318         File pkgInfoFile = new File(contentsDir.toFile(), "PkgInfo");
 319         pkgInfoFile.createNewFile();
 320         writePkgInfo(pkgInfoFile);
 321 
 322         Path executable = macOSDir.resolve(getLauncherName(params));
 323 
 324         // create the main app launcher
 325         try (InputStream is_launcher =
 326                 getResourceAsStream("jpackageapplauncher");
 327             InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
 328             // Copy executable and library to MacOS folder
 329             writeEntry(is_launcher, executable);
 330             writeEntry(is_lib, macOSDir.resolve(LIBRARY_NAME));
 331         }
 332         executable.toFile().setExecutable(true, false);
 333         // generate main app launcher config file
 334         File cfg = new File(root.toFile(), getLauncherCfgName(params));
 335         writeCfgFile(params, cfg, "$APPDIR/PlugIns/Java.runtime");
 336 
 337         // create secondary app launcher(s) and config file(s)
 338         List<Map<String, ? super Object>> entryPoints =
 339                 StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params);
 340         for (Map<String, ? super Object> entryPoint : entryPoints) {
 341             Map<String, ? super Object> tmp = new HashMap<>(originalParams);
 342             tmp.putAll(entryPoint);
 343 
 344             // add executable for secondary launcher
 345             Path secondaryExecutable = macOSDir.resolve(getLauncherName(tmp));
 346             try (InputStream is = getResourceAsStream("jpackageapplauncher");) {
 347                 writeEntry(is, secondaryExecutable);
 348             }
 349             secondaryExecutable.toFile().setExecutable(true, false);
 350 
 351             // add config file for secondary launcher
 352             cfg = new File(root.toFile(), getLauncherCfgName(tmp));
 353             writeCfgFile(tmp, cfg, "$APPDIR/PlugIns/Java.runtime");
 354         }
 355 
 356         // Copy class path entries to Java folder
 357         copyClassPathEntries(javaDir);
 358 
 359         /*********** Take care of "config" files *******/
 360         File icon = ICON_ICNS.fetchFrom(params);
 361 
 362         InputStream in = locateResource(
 363                 APP_NAME.fetchFrom(params) + ".icns",
 364                 "icon",
 365                 DEFAULT_ICNS_ICON.fetchFrom(params),
 366                 icon,
 367                 VERBOSE.fetchFrom(params),
 368                 RESOURCE_DIR.fetchFrom(params));
 369         Files.copy(in,
 370                 resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns"),
 371                 StandardCopyOption.REPLACE_EXISTING);


 464             String bn = MAC_CF_BUNDLE_NAME.fetchFrom(params);
 465             if (bn.length() > 16) {
 466                 Log.error(MessageFormat.format(I18N.getString(
 467                         "message.bundle-name-too-long-warning"),
 468                         MAC_CF_BUNDLE_NAME.getID(), bn));
 469             }
 470             return MAC_CF_BUNDLE_NAME.fetchFrom(params);
 471         } else if (APP_NAME.fetchFrom(params) != null) {
 472             return APP_NAME.fetchFrom(params);
 473         } else {
 474             String nm = MAIN_CLASS.fetchFrom(params);
 475             if (nm.length() > 16) {
 476                 nm = nm.substring(0, 16);
 477             }
 478             return nm;
 479         }
 480     }
 481 
 482     private void writeRuntimeInfoPlist(File file) throws IOException {
 483         Map<String, String> data = new HashMap<>();
 484         String identifier = RUNTIME_INSTALLER.fetchFrom(params) ?
 485                 MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) :
 486                 "com.oracle.java." + MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params);
 487         data.put("CF_BUNDLE_IDENTIFIER", identifier);
 488         String name = RUNTIME_INSTALLER.fetchFrom(params) ?
 489                 getBundleName(params): "Java Runtime Image";
 490         data.put("CF_BUNDLE_NAME", name);
 491         data.put("CF_BUNDLE_VERSION", VERSION.fetchFrom(params));
 492         data.put("CF_BUNDLE_SHORT_VERSION_STRING", VERSION.fetchFrom(params));
 493 
 494         Writer w = new BufferedWriter(new FileWriter(file));
 495         w.write(preprocessTextResource("Runtime-Info.plist",
 496                 I18N.getString("resource.runtime-info-plist"),
 497                 TEMPLATE_RUNTIME_INFO_PLIST,
 498                 data,
 499                 VERBOSE.fetchFrom(params),
 500                 RESOURCE_DIR.fetchFrom(params)));
 501         w.close();
 502     }
 503 
 504     private void writeInfoPlist(File file) throws IOException {
 505         Log.verbose(MessageFormat.format(I18N.getString(
 506                 "message.preparing-info-plist"), file.getAbsolutePath()));
 507 
 508         //prepare config for exe




  71             "Info-lite.plist.template";
  72     private static final String TEMPLATE_RUNTIME_INFO_PLIST =
  73             "Runtime-Info.plist.template";
  74 
  75     private final Path root;
  76     private final Path contentsDir;
  77     private final Path javaDir;
  78     private final Path javaModsDir;
  79     private final Path resourcesDir;
  80     private final Path macOSDir;
  81     private final Path runtimeDir;
  82     private final Path runtimeRoot;
  83     private final Path mdir;
  84 
  85     private final Map<String, ? super Object> params;
  86 
  87     private static List<String> keyChains;
  88 
  89     public static final BundlerParamInfo<Boolean>
  90             MAC_CONFIGURE_LAUNCHER_IN_PLIST = new StandardBundlerParam<>(


  91                             "param.configure-launcher-in-plist.description"),
  92                     "mac.configure-launcher-in-plist",
  93                     Boolean.class,
  94                     params -> Boolean.FALSE,
  95                     (s, p) -> Boolean.valueOf(s));
  96 
  97     public static final BundlerParamInfo<String> MAC_CATEGORY =
  98             new StandardBundlerParam<>(


  99                     "mac.category",
 100                     String.class,
 101                     CATEGORY::fetchFrom,
 102                     (s, p) -> s
 103             );
 104 
 105     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_NAME =
 106             new StandardBundlerParam<>(


 107                     "mac.CFBundleName",
 108                     String.class,
 109                     params -> null,
 110                     (s, p) -> s);
 111 
 112     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_IDENTIFIER =
 113             new StandardBundlerParam<>(


 114                     Arguments.CLIOptions.MAC_BUNDLE_IDENTIFIER.getId(),
 115                     String.class,
 116                     IDENTIFIER::fetchFrom,
 117                     (s, p) -> s);
 118 
 119     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_VERSION =
 120             new StandardBundlerParam<>(


 121                     "mac.CFBundleVersion",
 122                     String.class,
 123                     p -> {
 124                         String s = VERSION.fetchFrom(p);
 125                         if (validCFBundleVersion(s)) {
 126                             return s;
 127                         } else {
 128                             return "100";
 129                         }
 130                     },
 131                     (s, p) -> s);
 132 
 133     public static final BundlerParamInfo<String> DEFAULT_ICNS_ICON =
 134             new StandardBundlerParam<>(


 135             ".mac.default.icns",
 136             String.class,
 137             params -> TEMPLATE_BUNDLE_ICON,
 138             (s, p) -> s);
 139 
 140     public static final BundlerParamInfo<File> ICON_ICNS =
 141             new StandardBundlerParam<>(


 142             "icon.icns",
 143             File.class,
 144             params -> {
 145                 File f = ICON.fetchFrom(params);
 146                 if (f != null && !f.getName().toLowerCase().endsWith(".icns")) {
 147                     Log.error(MessageFormat.format(
 148                             I18N.getString("message.icon-not-icns"), f));
 149                     return null;
 150                 }
 151                 return f;
 152             },
 153             (s, p) -> new File(s));
 154 
 155     public static final StandardBundlerParam<Boolean> SIGN_BUNDLE  =
 156             new StandardBundlerParam<>(


 157             Arguments.CLIOptions.MAC_SIGN.getId(),
 158             Boolean.class,
 159             params -> false,
 160             // valueOf(null) is false, we actually do want null in some cases
 161             (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ?
 162                     null : Boolean.valueOf(s)
 163         );
 164 
 165     public MacAppImageBuilder(Map<String, Object> config, Path imageOutDir)
 166             throws IOException {
 167         super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config)
 168                 + ".app/Contents/PlugIns/Java.runtime/Contents/Home"));
 169 
 170         Objects.requireNonNull(imageOutDir);
 171 
 172         this.params = config;
 173         this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params) + ".app");
 174         this.contentsDir = root.resolve("Contents");
 175         this.javaDir = contentsDir.resolve("Java");
 176         this.javaModsDir = javaDir.resolve("mods");


 301         // Generate PkgInfo
 302         File pkgInfoFile = new File(contentsDir.toFile(), "PkgInfo");
 303         pkgInfoFile.createNewFile();
 304         writePkgInfo(pkgInfoFile);
 305 
 306         Path executable = macOSDir.resolve(getLauncherName(params));
 307 
 308         // create the main app launcher
 309         try (InputStream is_launcher =
 310                 getResourceAsStream("jpackageapplauncher");
 311             InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) {
 312             // Copy executable and library to MacOS folder
 313             writeEntry(is_launcher, executable);
 314             writeEntry(is_lib, macOSDir.resolve(LIBRARY_NAME));
 315         }
 316         executable.toFile().setExecutable(true, false);
 317         // generate main app launcher config file
 318         File cfg = new File(root.toFile(), getLauncherCfgName(params));
 319         writeCfgFile(params, cfg, "$APPDIR/PlugIns/Java.runtime");
 320 
 321         // create additional app launcher(s) and config file(s)
 322         List<Map<String, ? super Object>> entryPoints =
 323                 StandardBundlerParam.ADD_LAUNCHERS.fetchFrom(params);
 324         for (Map<String, ? super Object> entryPoint : entryPoints) {
 325             Map<String, ? super Object> tmp = new HashMap<>(originalParams);
 326             tmp.putAll(entryPoint);
 327 
 328             // add executable for add launcher
 329             Path addExecutable = macOSDir.resolve(getLauncherName(tmp));
 330             try (InputStream is = getResourceAsStream("jpackageapplauncher");) {
 331                 writeEntry(is, addExecutable);
 332             }
 333             addExecutable.toFile().setExecutable(true, false);
 334 
 335             // add config file for add launcher
 336             cfg = new File(root.toFile(), getLauncherCfgName(tmp));
 337             writeCfgFile(tmp, cfg, "$APPDIR/PlugIns/Java.runtime");
 338         }
 339 
 340         // Copy class path entries to Java folder
 341         copyClassPathEntries(javaDir);
 342 
 343         /*********** Take care of "config" files *******/
 344         File icon = ICON_ICNS.fetchFrom(params);
 345 
 346         InputStream in = locateResource(
 347                 APP_NAME.fetchFrom(params) + ".icns",
 348                 "icon",
 349                 DEFAULT_ICNS_ICON.fetchFrom(params),
 350                 icon,
 351                 VERBOSE.fetchFrom(params),
 352                 RESOURCE_DIR.fetchFrom(params));
 353         Files.copy(in,
 354                 resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns"),
 355                 StandardCopyOption.REPLACE_EXISTING);


 448             String bn = MAC_CF_BUNDLE_NAME.fetchFrom(params);
 449             if (bn.length() > 16) {
 450                 Log.error(MessageFormat.format(I18N.getString(
 451                         "message.bundle-name-too-long-warning"),
 452                         MAC_CF_BUNDLE_NAME.getID(), bn));
 453             }
 454             return MAC_CF_BUNDLE_NAME.fetchFrom(params);
 455         } else if (APP_NAME.fetchFrom(params) != null) {
 456             return APP_NAME.fetchFrom(params);
 457         } else {
 458             String nm = MAIN_CLASS.fetchFrom(params);
 459             if (nm.length() > 16) {
 460                 nm = nm.substring(0, 16);
 461             }
 462             return nm;
 463         }
 464     }
 465 
 466     private void writeRuntimeInfoPlist(File file) throws IOException {
 467         Map<String, String> data = new HashMap<>();
 468         String identifier = StandardBundlerParam.isRuntimeInstaller(params) ?
 469                 MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) :
 470                 "com.oracle.java." + MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params);
 471         data.put("CF_BUNDLE_IDENTIFIER", identifier);
 472         String name = StandardBundlerParam.isRuntimeInstaller(params) ?
 473                 getBundleName(params): "Java Runtime Image";
 474         data.put("CF_BUNDLE_NAME", name);
 475         data.put("CF_BUNDLE_VERSION", VERSION.fetchFrom(params));
 476         data.put("CF_BUNDLE_SHORT_VERSION_STRING", VERSION.fetchFrom(params));
 477 
 478         Writer w = new BufferedWriter(new FileWriter(file));
 479         w.write(preprocessTextResource("Runtime-Info.plist",
 480                 I18N.getString("resource.runtime-info-plist"),
 481                 TEMPLATE_RUNTIME_INFO_PLIST,
 482                 data,
 483                 VERBOSE.fetchFrom(params),
 484                 RESOURCE_DIR.fetchFrom(params)));
 485         w.close();
 486     }
 487 
 488     private void writeInfoPlist(File file) throws IOException {
 489         Log.verbose(MessageFormat.format(I18N.getString(
 490                 "message.preparing-info-plist"), file.getAbsolutePath()));
 491 
 492         //prepare config for exe


< prev index next >