< 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                     "mac.configure-launcher-in-plist",
  92                     Boolean.class,
  93                     params -> Boolean.FALSE,
  94                     (s, p) -> Boolean.valueOf(s));
  95 
  96     public static final EnumeratedBundlerParam<String> MAC_CATEGORY =
  97             new EnumeratedBundlerParam<>(
  98                     Arguments.CLIOptions.MAC_APP_STORE_CATEGORY.getId(),


  99                     String.class,
 100                     params -> "Unknown",
 101                     (s, p) -> s,
 102                     MacAppBundler.getMacCategories(),
 103                     false //strict - for MacStoreBundler this should be strict
 104             );
 105 
 106     public static final BundlerParamInfo<String> MAC_CF_BUNDLE_NAME =
 107             new StandardBundlerParam<>(


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


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


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


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


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


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


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


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


< prev index next >