src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java
branchJDK-8200758-branch
changeset 57396 3944e4c2f779
parent 57391 970f28090a06
child 57397 89549ecec1c7
equal deleted inserted replaced
57395:521c02b9eed0 57396:3944e4c2f779
   242             return null;
   242             return null;
   243         }
   243         }
   244     }
   244     }
   245 
   245 
   246     @Override
   246     @Override
   247     public boolean validate(Map<String, ? super Object> p)
   247     public boolean validate(Map<String, ? super Object> params)
   248             throws UnsupportedPlatformException, ConfigException {
   248             throws UnsupportedPlatformException, ConfigException {
   249         try {
   249         try {
   250             if (p == null) throw new ConfigException(
   250             if (params == null) throw new ConfigException(
   251                     I18N.getString("error.parameters-null"),
   251                     I18N.getString("error.parameters-null"),
   252                     I18N.getString("error.parameters-null.advice"));
   252                     I18N.getString("error.parameters-null.advice"));
   253 
   253 
   254             // run basic validation to ensure requirements are met
   254             // run basic validation to ensure requirements are met
   255             // we are not interested in return code, only possible exception
   255             // we are not interested in return code, only possible exception
   256             APP_BUNDLER.fetchFrom(p).validate(p);
   256             APP_BUNDLER.fetchFrom(params).validate(params);
   257 
   257 
   258             String candleVersion =
   258             String candleVersion =
   259                     findToolVersion(TOOL_CANDLE_EXECUTABLE.fetchFrom(p));
   259                     findToolVersion(TOOL_CANDLE_EXECUTABLE.fetchFrom(params));
   260             String lightVersion =
   260             String lightVersion =
   261                     findToolVersion(TOOL_LIGHT_EXECUTABLE.fetchFrom(p));
   261                     findToolVersion(TOOL_LIGHT_EXECUTABLE.fetchFrom(params));
   262 
   262 
   263             // WiX 3.0+ is required
   263             // WiX 3.0+ is required
   264             String minVersion = "3.0";
   264             String minVersion = "3.0";
   265             boolean bad = false;
   265             boolean bad = false;
   266 
   266 
   283                         I18N.getString("error.no-wix-tools.advice"));
   283                         I18N.getString("error.no-wix-tools.advice"));
   284             }
   284             }
   285 
   285 
   286             if (!VersionExtractor.isLessThan(lightVersion, "3.6")) {
   286             if (!VersionExtractor.isLessThan(lightVersion, "3.6")) {
   287                 Log.verbose(I18N.getString("message.use-wix36-features"));
   287                 Log.verbose(I18N.getString("message.use-wix36-features"));
   288                 p.put(CAN_USE_WIX36.getID(), Boolean.TRUE);
   288                 params.put(CAN_USE_WIX36.getID(), Boolean.TRUE);
   289             }
   289             }
   290 
   290 
   291             /********* validate bundle parameters *************/
   291             /********* validate bundle parameters *************/
   292 
   292 
   293             String version = PRODUCT_VERSION.fetchFrom(p);
   293             String version = PRODUCT_VERSION.fetchFrom(params);
   294             if (!isVersionStringValid(version)) {
   294             if (!isVersionStringValid(version)) {
   295                 throw new ConfigException(
   295                 throw new ConfigException(
   296                         MessageFormat.format(I18N.getString(
   296                         MessageFormat.format(I18N.getString(
   297                                 "error.version-string-wrong-format"), version),
   297                                 "error.version-string-wrong-format"), version),
   298                         MessageFormat.format(I18N.getString(
   298                         MessageFormat.format(I18N.getString(
   300                                 PRODUCT_VERSION.getID()));
   300                                 PRODUCT_VERSION.getID()));
   301             }
   301             }
   302 
   302 
   303             // only one mime type per association, at least one file extension
   303             // only one mime type per association, at least one file extension
   304             List<Map<String, ? super Object>> associations =
   304             List<Map<String, ? super Object>> associations =
   305                     FILE_ASSOCIATIONS.fetchFrom(p);
   305                     FILE_ASSOCIATIONS.fetchFrom(params);
   306             if (associations != null) {
   306             if (associations != null) {
   307                 for (int i = 0; i < associations.size(); i++) {
   307                 for (int i = 0; i < associations.size(); i++) {
   308                     Map<String, ? super Object> assoc = associations.get(i);
   308                     Map<String, ? super Object> assoc = associations.get(i);
   309                     List<String> mimes = FA_CONTENT_TYPE.fetchFrom(assoc);
   309                     List<String> mimes = FA_CONTENT_TYPE.fetchFrom(assoc);
   310                     if (mimes.size() > 1) {
   310                     if (mimes.size() > 1) {
   376         }
   376         }
   377 
   377 
   378         return true;
   378         return true;
   379     }
   379     }
   380 
   380 
   381     private boolean prepareProto(Map<String, ? super Object> p)
   381     private boolean prepareProto(Map<String, ? super Object> params)
   382                 throws PackagerException, IOException {
   382                 throws PackagerException, IOException {
   383         File appImage = StandardBundlerParam.getPredefinedAppImage(p);
   383         File appImage = StandardBundlerParam.getPredefinedAppImage(params);
   384         File appDir = null;
   384         File appDir = null;
   385 
   385 
   386         // we either have an application image or need to build one
   386         // we either have an application image or need to build one
   387         if (appImage != null) {
   387         if (appImage != null) {
   388             appDir = new File(
   388             appDir = new File(MSI_IMAGE_DIR.fetchFrom(params),
   389                     MSI_IMAGE_DIR.fetchFrom(p), APP_NAME.fetchFrom(p));
   389                     APP_NAME.fetchFrom(params));
   390             // copy everything from appImage dir into appDir/name
   390             // copy everything from appImage dir into appDir/name
   391             IOUtils.copyRecursive(appImage.toPath(), appDir.toPath());
   391             IOUtils.copyRecursive(appImage.toPath(), appDir.toPath());
   392         } else {
   392         } else {
   393             appDir = APP_BUNDLER.fetchFrom(p).doBundle(p,
   393             appDir = APP_BUNDLER.fetchFrom(params).doBundle(params,
   394                     MSI_IMAGE_DIR.fetchFrom(p), true);
   394                     MSI_IMAGE_DIR.fetchFrom(params), true);
   395         }
   395         }
   396 
   396 
   397         p.put(WIN_APP_IMAGE.getID(), appDir);
   397         params.put(WIN_APP_IMAGE.getID(), appDir);
   398 
   398 
   399         String licenseFile = LICENSE_FILE.fetchFrom(p);
   399         String licenseFile = LICENSE_FILE.fetchFrom(params);
   400         if (licenseFile != null) {
   400         if (licenseFile != null) {
   401             // need to copy license file to the working directory and convert to rtf if needed
   401             // need to copy license file to the working directory and convert to rtf if needed
   402             File lfile = new File(licenseFile);
   402             File lfile = new File(licenseFile);
   403             File destFile = new File(CONFIG_ROOT.fetchFrom(p), lfile.getName());
   403             File destFile = new File(CONFIG_ROOT.fetchFrom(params),
       
   404                     lfile.getName());
   404             IOUtils.copyFile(lfile, destFile);
   405             IOUtils.copyFile(lfile, destFile);
   405             ensureByMutationFileIsRTF(destFile);
   406             ensureByMutationFileIsRTF(destFile);
   406         }
   407         }
   407 
   408 
   408         // copy file association icons
   409         // copy file association icons
   409         List<Map<String, ? super Object>> fileAssociations =
   410         List<Map<String, ? super Object>> fileAssociations =
   410                 FILE_ASSOCIATIONS.fetchFrom(p);
   411                 FILE_ASSOCIATIONS.fetchFrom(params);
   411         for (Map<String, ? super Object> fa : fileAssociations) {
   412         for (Map<String, ? super Object> fa : fileAssociations) {
   412             File icon = FA_ICON.fetchFrom(fa); // TODO FA_ICON_ICO
   413             File icon = FA_ICON.fetchFrom(fa); // TODO FA_ICON_ICO
   413             if (icon == null) {
   414             if (icon == null) {
   414                 continue;
   415                 continue;
   415             }
   416             }
   426         }
   427         }
   427 
   428 
   428         return appDir != null;
   429         return appDir != null;
   429     }
   430     }
   430 
   431 
   431     public File bundle(Map<String, ? super Object> p, File outdir)
   432     public File bundle(Map<String, ? super Object> params, File outdir)
   432             throws PackagerException {
   433             throws PackagerException {
   433         if (!outdir.isDirectory() && !outdir.mkdirs()) {
   434         if (!outdir.isDirectory() && !outdir.mkdirs()) {
   434             throw new PackagerException("error.cannot-create-output-dir",
   435             throw new PackagerException("error.cannot-create-output-dir",
   435                     outdir.getAbsolutePath());
   436                     outdir.getAbsolutePath());
   436         }
   437         }
   438             throw new PackagerException("error.cannot-write-to-output-dir",
   439             throw new PackagerException("error.cannot-write-to-output-dir",
   439                     outdir.getAbsolutePath());
   440                     outdir.getAbsolutePath());
   440         }
   441         }
   441 
   442 
   442         // validate we have valid tools before continuing
   443         // validate we have valid tools before continuing
   443         String light = TOOL_LIGHT_EXECUTABLE.fetchFrom(p);
   444         String light = TOOL_LIGHT_EXECUTABLE.fetchFrom(params);
   444         String candle = TOOL_CANDLE_EXECUTABLE.fetchFrom(p);
   445         String candle = TOOL_CANDLE_EXECUTABLE.fetchFrom(params);
   445         if (light == null || !new File(light).isFile() ||
   446         if (light == null || !new File(light).isFile() ||
   446             candle == null || !new File(candle).isFile()) {
   447             candle == null || !new File(candle).isFile()) {
   447             Log.verbose(MessageFormat.format(
   448             Log.verbose(MessageFormat.format(
   448                    I18N.getString("message.light-file-string"), light));
   449                    I18N.getString("message.light-file-string"), light));
   449             Log.verbose(MessageFormat.format(
   450             Log.verbose(MessageFormat.format(
   450                    I18N.getString("message.candle-file-string"), candle));
   451                    I18N.getString("message.candle-file-string"), candle));
   451             throw new PackagerException("error.no-wix-tools");
   452             throw new PackagerException("error.no-wix-tools");
   452         }
   453         }
   453 
   454 
   454         File imageDir = MSI_IMAGE_DIR.fetchFrom(p);
   455         File imageDir = MSI_IMAGE_DIR.fetchFrom(params);
   455         try {
   456         try {
   456             imageDir.mkdirs();
   457             imageDir.mkdirs();
   457 
   458 
   458             boolean menuShortcut = MENU_HINT.fetchFrom(p);
   459             boolean menuShortcut = MENU_HINT.fetchFrom(params);
   459             boolean desktopShortcut = SHORTCUT_HINT.fetchFrom(p);
   460             boolean desktopShortcut = SHORTCUT_HINT.fetchFrom(params);
   460             if (!menuShortcut && !desktopShortcut) {
   461             if (!menuShortcut && !desktopShortcut) {
   461                 // both can not be false - user will not find the app
   462                 // both can not be false - user will not find the app
   462                 Log.verbose(I18N.getString("message.one-shortcut-required"));
   463                 Log.verbose(I18N.getString("message.one-shortcut-required"));
   463                 p.put(MENU_HINT.getID(), true);
   464                 params.put(MENU_HINT.getID(), true);
   464             }
   465             }
   465 
   466 
   466             if (prepareProto(p) && prepareWiXConfig(p)
   467             if (prepareProto(params) && prepareWiXConfig(params)
   467                     && prepareBasicProjectConfig(p)) {
   468                     && prepareBasicProjectConfig(params)) {
   468                 File configScriptSrc = getConfig_Script(p);
   469                 File configScriptSrc = getConfig_Script(params);
   469                 if (configScriptSrc.exists()) {
   470                 if (configScriptSrc.exists()) {
   470                     // we need to be running post script in the image folder
   471                     // we need to be running post script in the image folder
   471 
   472 
   472                     // NOTE: Would it be better to generate it to the image
   473                     // NOTE: Would it be better to generate it to the image
   473                     // folder and save only if "verbose" is requested?
   474                     // folder and save only if "verbose" is requested?
   479                     Log.verbose(MessageFormat.format(
   480                     Log.verbose(MessageFormat.format(
   480                             I18N.getString("message.running-wsh-script"),
   481                             I18N.getString("message.running-wsh-script"),
   481                             configScript.getAbsolutePath()));
   482                             configScript.getAbsolutePath()));
   482                     IOUtils.run("wscript", configScript);
   483                     IOUtils.run("wscript", configScript);
   483                 }
   484                 }
   484                 return buildMSI(p, outdir);
   485                 return buildMSI(params, outdir);
   485             }
   486             }
   486             return null;
   487             return null;
   487         } catch (IOException ex) {
   488         } catch (IOException ex) {
   488             Log.verbose(ex);
   489             Log.verbose(ex);
   489             throw new PackagerException(ex);
   490             throw new PackagerException(ex);
  1036     private File getConfig_ProjectFile(Map<String, ? super Object> params) {
  1037     private File getConfig_ProjectFile(Map<String, ? super Object> params) {
  1037         return new File(CONFIG_ROOT.fetchFrom(params),
  1038         return new File(CONFIG_ROOT.fetchFrom(params),
  1038                 APP_NAME.fetchFrom(params) + ".wxs");
  1039                 APP_NAME.fetchFrom(params) + ".wxs");
  1039     }
  1040     }
  1040 
  1041 
  1041     private String getLicenseFile(Map<String, ? super Object> p) {
  1042     private String getLicenseFile(Map<String, ? super Object> params) {
  1042         String licenseFile = LICENSE_FILE.fetchFrom(p);
  1043         String licenseFile = LICENSE_FILE.fetchFrom(params);
  1043         if (licenseFile != null) {
  1044         if (licenseFile != null) {
  1044             File lfile = new File(licenseFile);
  1045             File lfile = new File(licenseFile);
  1045             File destFile = new File(CONFIG_ROOT.fetchFrom(p), lfile.getName());
  1046             File destFile = new File(CONFIG_ROOT.fetchFrom(params),
       
  1047                 lfile.getName());
  1046             String filePath = destFile.getAbsolutePath();
  1048             String filePath = destFile.getAbsolutePath();
  1047             if (filePath.contains(" ")) {
  1049             if (filePath.contains(" ")) {
  1048                 return "\"" + filePath + "\"";
  1050                 return "\"" + filePath + "\"";
  1049             } else {
  1051             } else {
  1050                 return filePath;
  1052                 return filePath;