src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java
branchJDK-8200758-branch
changeset 57414 6eda749d3117
parent 57392 46d4b0aa4542
child 57421 0410ee319681
equal deleted inserted replaced
57413:45c74e654794 57414:6eda749d3117
    62  */
    62  */
    63 public class Arguments {
    63 public class Arguments {
    64     private static final ResourceBundle I18N = ResourceBundle.getBundle(
    64     private static final ResourceBundle I18N = ResourceBundle.getBundle(
    65             "jdk.jpackage.internal.resources.MainResources");
    65             "jdk.jpackage.internal.resources.MainResources");
    66 
    66 
    67     private static final String APPIMAGE_MODE = "create-app-image";
    67     private static final String IMAGE_PACKAGE_TYPE = "app-image";
    68     private static final String INSTALLER_MODE = "create-installer";
       
    69 
       
    70     private static final String FA_EXTENSIONS = "extension";
    68     private static final String FA_EXTENSIONS = "extension";
    71     private static final String FA_CONTENT_TYPE = "mime-type";
    69     private static final String FA_CONTENT_TYPE = "mime-type";
    72     private static final String FA_DESCRIPTION = "description";
    70     private static final String FA_DESCRIPTION = "description";
    73     private static final String FA_ICON = "icon";
    71     private static final String FA_ICON = "icon";
    74 
    72 
    75     static final BundlerParamInfo<Boolean> CREATE_APP_IMAGE =
       
    76             new StandardBundlerParam<>(
       
    77                     APPIMAGE_MODE,
       
    78                     Boolean.class,
       
    79                     p -> Boolean.FALSE,
       
    80                     (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ?
       
    81                             true : Boolean.valueOf(s));
       
    82 
       
    83     static final BundlerParamInfo<Boolean> CREATE_INSTALLER =
       
    84             new StandardBundlerParam<>(
       
    85                     INSTALLER_MODE,
       
    86                     Boolean.class,
       
    87                     p -> Boolean.FALSE,
       
    88                     (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ?
       
    89                             true : Boolean.valueOf(s));
       
    90 
       
    91     // regexp for parsing args (for example, for additional launchers)
    73     // regexp for parsing args (for example, for additional launchers)
    92     private static Pattern pattern = Pattern.compile(
    74     private static Pattern pattern = Pattern.compile(
    93           "(?:(?:([\"'])(?:\\\\\\1|.)*?(?:\\1|$))|(?:\\\\[\"'\\s]|[^\\s]))++");
    75           "(?:(?:([\"'])(?:\\\\\\1|.)*?(?:\\1|$))|(?:\\\\[\"'\\s]|[^\\s]))++");
    94 
    76 
    95     private DeployParams deployParams = null;
    77     private DeployParams deployParams = null;
    96     private BundlerType bundleType = null;
    78     private String packageType = null;
    97 
    79 
    98     private int pos = 0;
    80     private int pos = 0;
    99     private List<String> argList = null;
    81     private List<String> argList = null;
   100 
    82 
   101     private List<CLIOptions> allOptions = null;
    83     private List<CLIOptions> allOptions = null;
   104     private String output = null;
    86     private String output = null;
   105 
    87 
   106     private boolean hasMainJar = false;
    88     private boolean hasMainJar = false;
   107     private boolean hasMainClass = false;
    89     private boolean hasMainClass = false;
   108     private boolean hasMainModule = false;
    90     private boolean hasMainModule = false;
   109     private boolean hasTargetFormat = false;
       
   110     public boolean userProvidedBuildRoot = false;
    91     public boolean userProvidedBuildRoot = false;
   111 
    92 
   112     private String buildRoot = null;
    93     private String buildRoot = null;
   113     private String mainJarPath = null;
    94     private String mainJarPath = null;
   114 
    95 
   115     private static boolean runtimeInstaller = false;
    96     private static boolean runtimeInstaller = false;
   116 
       
   117     private List<jdk.jpackage.internal.Bundler> platformBundlers = null;
       
   118 
    97 
   119     private List<AddLauncherArguments> addLaunchers = null;
    98     private List<AddLauncherArguments> addLaunchers = null;
   120 
    99 
   121     private static Map<String, CLIOptions> argIds = new HashMap<>();
   100     private static Map<String, CLIOptions> argIds = new HashMap<>();
   122     private static Map<String, CLIOptions> argShortIds = new HashMap<>();
   101     private static Map<String, CLIOptions> argShortIds = new HashMap<>();
   138         }
   117         }
   139         Log.debug ("\njpackage argument list: \n" + argList + "\n");
   118         Log.debug ("\njpackage argument list: \n" + argList + "\n");
   140         pos = 0;
   119         pos = 0;
   141 
   120 
   142         deployParams = new DeployParams();
   121         deployParams = new DeployParams();
   143         bundleType = BundlerType.NONE;
   122 
       
   123         packageType = null;
   144 
   124 
   145         allOptions = new ArrayList<>();
   125         allOptions = new ArrayList<>();
   146 
   126 
   147         addLaunchers = new ArrayList<>();
   127         addLaunchers = new ArrayList<>();
   148     }
   128     }
   149 
   129 
   150     // CLIOptions is public for DeployParamsTest
   130     // CLIOptions is public for DeployParamsTest
   151     public enum CLIOptions {
   131     public enum CLIOptions {
   152         CREATE_APP_IMAGE(APPIMAGE_MODE, OptionCategories.MODE, () -> {
   132         PACKAGE_TYPE("package-type", OptionCategories.PROPERTY, () -> {
   153             context().bundleType = BundlerType.IMAGE;
   133             context().packageType = popArg();
   154             context().deployParams.setTargetFormat("image");
   134             context().deployParams.setTargetFormat(context().packageType);
   155             setOptionValue(APPIMAGE_MODE, true);
       
   156         }),
       
   157 
       
   158         CREATE_INSTALLER(INSTALLER_MODE, OptionCategories.MODE, () -> {
       
   159             setOptionValue(INSTALLER_MODE, true);
       
   160             context().bundleType = BundlerType.INSTALLER;
       
   161             String format = "installer";
       
   162             context().deployParams.setTargetFormat(format);
       
   163         }),
       
   164 
       
   165         INSTALLER_TYPE("installer-type", OptionCategories.PROPERTY, () -> {
       
   166             String type = popArg();
       
   167             if (BundlerType.INSTALLER.equals(context().bundleType)) {
       
   168                 context().deployParams.setTargetFormat(type);
       
   169                 context().hasTargetFormat = true;
       
   170             }
       
   171             setOptionValue("installer-type", type);
       
   172         }),
   135         }),
   173 
   136 
   174         INPUT ("input", "i", OptionCategories.PROPERTY, () -> {
   137         INPUT ("input", "i", OptionCategories.PROPERTY, () -> {
   175             context().input = popArg();
   138             context().input = popArg();
   176             setOptionValue("input", context().input);
   139             setOptionValue("input", context().input);
   497                 } else {
   460                 } else {
   498                     throw new PackagerException("ERR_InvalidOption", arg);
   461                     throw new PackagerException("ERR_InvalidOption", arg);
   499                 }
   462                 }
   500             }
   463             }
   501 
   464 
   502             if (allOptions.isEmpty() || !allOptions.get(0).isMode()) {
       
   503                 // first argument should always be a mode.
       
   504                 throw new PackagerException("ERR_MissingMode");
       
   505             }
       
   506 
       
   507             if (hasMainJar && !hasMainClass) {
   465             if (hasMainJar && !hasMainClass) {
   508                 // try to get main-class from manifest
   466                 // try to get main-class from manifest
   509                 String mainClass = getMainClassFromManifest();
   467                 String mainClass = getMainClassFromManifest();
   510                 if (mainClass != null) {
   468                 if (mainClass != null) {
   511                     CLIOptions.setOptionValue(
   469                     CLIOptions.setOptionValue(
   512                             CLIOptions.APPCLASS.getId(), mainClass);
   470                             CLIOptions.APPCLASS.getId(), mainClass);
   513                 }
   471                 }
   514             }
   472             }
   515 
   473 
   516             // display warning for arguments that are not supported
   474             // display error for arguments that are not supported
   517             // for current configuration.
   475             // for current configuration.
   518 
   476 
   519             validateArguments();
   477             validateArguments();
   520 
   478 
   521             addResources(deployParams, input);
   479             addResources(deployParams, input);
   522 
       
   523             deployParams.setBundleType(bundleType);
       
   524 
   480 
   525             List<Map<String, ? super Object>> launchersAsMap =
   481             List<Map<String, ? super Object>> launchersAsMap =
   526                     new ArrayList<>();
   482                     new ArrayList<>();
   527 
   483 
   528             for (AddLauncherArguments sl : addLaunchers) {
   484             for (AddLauncherArguments sl : addLaunchers) {
   561             }
   517             }
   562             if (runtimeInstaller && bp.getName() == null) {
   518             if (runtimeInstaller && bp.getName() == null) {
   563                 throw new PackagerException("ERR_NoJreInstallerName");
   519                 throw new PackagerException("ERR_NoJreInstallerName");
   564             }
   520             }
   565 
   521 
   566             return generateBundle(bp.getBundleParamsAsMap());
   522             generateBundle(bp.getBundleParamsAsMap());
       
   523             return true;
   567         } catch (Exception e) {
   524         } catch (Exception e) {
   568             if (Log.isVerbose()) {
   525             if (Log.isVerbose()) {
   569                 Log.verbose(e);
   526                 Log.verbose(e);
   570             } else {
   527             } else {
   571                 String msg1 = e.getMessage();
   528                 String msg1 = e.getMessage();
   580             return false;
   537             return false;
   581         }
   538         }
   582     }
   539     }
   583 
   540 
   584     private void validateArguments() throws PackagerException {
   541     private void validateArguments() throws PackagerException {
   585         CLIOptions mode = allOptions.get(0);
   542         String packageType = deployParams.getTargetFormat();
   586         boolean imageOnly = (mode == CLIOptions.CREATE_APP_IMAGE);
   543         String ptype = (packageType != null) ? packageType : "default";
       
   544         boolean imageOnly = IMAGE_PACKAGE_TYPE.equals(packageType);
   587         boolean hasAppImage = allOptions.contains(
   545         boolean hasAppImage = allOptions.contains(
   588                 CLIOptions.PREDEFINED_APP_IMAGE);
   546                 CLIOptions.PREDEFINED_APP_IMAGE);
   589         boolean hasRuntime = allOptions.contains(
   547         boolean hasRuntime = allOptions.contains(
   590                 CLIOptions.PREDEFINED_RUNTIME_IMAGE);
   548                 CLIOptions.PREDEFINED_RUNTIME_IMAGE);
   591         boolean installerOnly = !imageOnly && hasAppImage;
   549         boolean installerOnly = !imageOnly && hasAppImage;
   592         boolean runtimeInstall = !imageOnly && hasRuntime && !hasAppImage &&
   550         runtimeInstaller = !imageOnly && hasRuntime && !hasAppImage &&
   593                 !hasMainModule && !hasMainJar;
   551                 !hasMainModule && !hasMainJar;
   594 
   552 
   595         for (CLIOptions option : allOptions) {
   553         for (CLIOptions option : allOptions) {
   596             if (!ValidOptions.checkIfSupported(option)) {
   554             if (!ValidOptions.checkIfSupported(option)) {
   597                 // includes option valid only on different platform
   555                 // includes option valid only on different platform
   598                 throw new PackagerException("ERR_UnsupportedOption",
   556                 throw new PackagerException("ERR_UnsupportedOption",
   599                         option.getIdWithPrefix());
   557                         option.getIdWithPrefix());
   600             }
   558             }
   601             if (imageOnly) {
   559             if (imageOnly) {
   602                 if (!ValidOptions.checkIfImageSupported(option)) {
   560                 if (!ValidOptions.checkIfImageSupported(option)) {
   603                     throw new PackagerException("ERR_NotImageOption",
   561                     throw new PackagerException("ERR_InvalidTypeOption",
   604                         option.getIdWithPrefix());
   562                         option.getIdWithPrefix(), packageType);
   605                 }
   563                 }
   606             } else if (installerOnly || runtimeInstall) {
   564             } else if (installerOnly || runtimeInstaller) {
   607                 if (!ValidOptions.checkIfInstallerSupported(option)) {
   565                 if (!ValidOptions.checkIfInstallerSupported(option)) {
   608                     String key = runtimeInstaller ?
   566                     if (runtimeInstaller) {
   609                         "ERR_NoInstallerEntryPoint" : "ERR_NotInstallerOption";
   567                         throw new PackagerException("ERR_NoInstallerEntryPoint",
   610                     throw new PackagerException(key, option.getIdWithPrefix());
   568                             option.getIdWithPrefix());
       
   569                     } else {
       
   570                         throw new PackagerException("ERR_InvalidTypeOption",
       
   571                             option.getIdWithPrefix(), ptype);
       
   572                    }
   611                 }
   573                 }
   612             }
   574             }
   613         }
   575         }
   614         if (installerOnly && hasRuntime) {
   576         if (installerOnly && hasRuntime) {
   615             // note --runtime-image is only for image or runtime installer.
   577             // note --runtime-image is only for image or runtime installer.
   616             throw new PackagerException("ERR_NotInstallerOption",
   578             throw new PackagerException("ERR_InvalidTypeOption",
   617                     CLIOptions.PREDEFINED_RUNTIME_IMAGE.getIdWithPrefix());
   579                     CLIOptions.PREDEFINED_RUNTIME_IMAGE.getIdWithPrefix(),
       
   580                     ptype);
   618         }
   581         }
   619         if (hasMainJar && hasMainModule) {
   582         if (hasMainJar && hasMainModule) {
   620             throw new PackagerException("ERR_BothMainJarAndModule");
   583             throw new PackagerException("ERR_BothMainJarAndModule");
   621         }
   584         }
   622         if (imageOnly && !hasMainJar && !hasMainModule) {
   585         if (imageOnly && !hasMainJar && !hasMainModule) {
   623             throw new PackagerException("ERR_NoEntryPoint");
   586             throw new PackagerException("ERR_NoEntryPoint");
   624         }
   587         }
   625     }
   588     }
   626 
   589 
   627     private List<jdk.jpackage.internal.Bundler> getPlatformBundlers() {
   590     private jdk.jpackage.internal.Bundler getPlatformBundler() {
   628 
   591         String bundleType = (packageType == null ? "IMAGE" : "INSTALLER");
   629         if (platformBundlers != null) {
   592 
   630             return platformBundlers;
       
   631         }
       
   632 
       
   633         platformBundlers = new ArrayList<>();
       
   634         for (jdk.jpackage.internal.Bundler bundler :
   593         for (jdk.jpackage.internal.Bundler bundler :
   635                 Bundlers.createBundlersInstance().getBundlers(
   594                 Bundlers.createBundlersInstance().getBundlers(bundleType)) {
   636                         bundleType.toString())) {
   595             if ((packageType == null) ||
   637             if (hasTargetFormat && deployParams.getTargetFormat() != null &&
   596                      packageType.equalsIgnoreCase(bundler.getID())) {
   638                     !deployParams.getTargetFormat().equalsIgnoreCase(
   597                  if (bundler.supported(runtimeInstaller)) {
   639                     bundler.getID())) {
   598                      return bundler;
   640                 continue;
   599                  }
   641             }
   600             }
   642             if (bundler.supported(runtimeInstaller)) {
   601         }
   643                  platformBundlers.add(bundler);
   602         return null;
   644             }
   603     }
   645         }
   604 
   646 
   605     private void generateBundle(Map<String,? super Object> params)
   647         return platformBundlers;
       
   648     }
       
   649 
       
   650     private boolean generateBundle(Map<String,? super Object> params)
       
   651             throws PackagerException {
   606             throws PackagerException {
   652 
   607 
   653         boolean bundleCreated = false;
   608         boolean bundleCreated = false;
   654 
   609 
   655         // the temp-root needs to be fetched from the params early,
   610         // the temp-root needs to be fetched from the params early,
   657         // additional launchers) from generating a separate temp-root when
   612         // additional launchers) from generating a separate temp-root when
   658         // the default is used (the default is a new temp directory)
   613         // the default is used (the default is a new temp directory)
   659         // The bundler.cleanup() below would not otherwise be able to
   614         // The bundler.cleanup() below would not otherwise be able to
   660         // clean these extra (and unneeded) temp directories.
   615         // clean these extra (and unneeded) temp directories.
   661         StandardBundlerParam.TEMP_ROOT.fetchFrom(params);
   616         StandardBundlerParam.TEMP_ROOT.fetchFrom(params);
   662         List<jdk.jpackage.internal.Bundler> bundlers = getPlatformBundlers();
   617 
   663         if (bundlers.isEmpty()) {
   618         // determine what bundler to run
       
   619         jdk.jpackage.internal.Bundler bundler = getPlatformBundler();
       
   620 
       
   621         if (bundler == null) {
   664             throw new PackagerException("ERR_InvalidInstallerType",
   622             throw new PackagerException("ERR_InvalidInstallerType",
   665                     deployParams.getTargetFormat());
   623                       deployParams.getTargetFormat());
   666         }
   624         }
   667         PackagerException pe = null;
   625 
   668         for (jdk.jpackage.internal.Bundler bundler : bundlers) {
   626         Map<String, ? super Object> localParams = new HashMap<>(params);
   669             Map<String, ? super Object> localParams = new HashMap<>(params);
   627         try {
   670             try {
   628             bundler.validate(localParams);
   671                 if (bundler.validate(localParams)) {
   629             File result = bundler.execute(localParams, deployParams.outdir);
   672                     File result =
   630             if (!userProvidedBuildRoot) {
   673                             bundler.execute(localParams, deployParams.outdir);
   631                 bundler.cleanup(localParams);
   674                     if (!userProvidedBuildRoot) {
   632             }
   675                         bundler.cleanup(localParams);
   633             if (result == null) {
   676                     }
   634                 throw new PackagerException("MSG_BundlerFailed",
   677                     if (result == null) {
   635                         bundler.getID(), bundler.getName());
   678                         throw new PackagerException("MSG_BundlerFailed",
   636             }
   679                                 bundler.getID(), bundler.getName());
   637             Log.verbose(MessageFormat.format(
   680                     }
   638                     I18N.getString("message.bundle-created"),
   681                     bundleCreated = true; // at least one bundle was created
   639                     bundler.getName()));
   682                 }
   640         } catch (UnsupportedPlatformException upe) {
       
   641             Log.debug(upe);
       
   642             throw new PackagerException(upe,
       
   643                     "MSG_BundlerPlatformException", bundler.getName());
       
   644         } catch (ConfigException e) {
       
   645             Log.debug(e);
       
   646             if (e.getAdvice() != null)  {
       
   647                 throw new PackagerException(e, "MSG_BundlerConfigException",
       
   648                         bundler.getName(), e.getMessage(), e.getAdvice());
       
   649             } else {
       
   650                 throw new PackagerException(e,
       
   651                        "MSG_BundlerConfigExceptionNoAdvice",
       
   652                         bundler.getName(), e.getMessage());
       
   653             }
       
   654         } catch (RuntimeException re) {
       
   655             Log.debug(re);
       
   656             throw new PackagerException(re, "MSG_BundlerRuntimeException",
       
   657                     bundler.getName(), re.toString());
       
   658         } finally {
       
   659             if (userProvidedBuildRoot) {
   683                 Log.verbose(MessageFormat.format(
   660                 Log.verbose(MessageFormat.format(
   684                         I18N.getString("message.bundle-created"),
   661                         I18N.getString("message.debug-working-directory"),
   685                         bundler.getName()));
   662                         (new File(buildRoot)).getAbsolutePath()));
   686             } catch (UnsupportedPlatformException upe) {
   663             }
   687                 Log.debug(upe);
   664         }
   688                 if (pe == null) {
       
   689                     pe = new PackagerException(upe,
       
   690                             "MSG_BundlerPlatformException", bundler.getName());
       
   691                 }
       
   692             } catch (ConfigException e) {
       
   693                 Log.debug(e);
       
   694                 if (pe == null) {
       
   695                     pe = (e.getAdvice() != null) ?
       
   696                             new PackagerException(e,
       
   697                             "MSG_BundlerConfigException",
       
   698                             bundler.getName(), e.getMessage(), e.getAdvice()) :
       
   699                             new PackagerException(e,
       
   700                            "MSG_BundlerConfigExceptionNoAdvice",
       
   701                             bundler.getName(), e.getMessage());
       
   702                 }
       
   703             } catch (RuntimeException re) {
       
   704                 Log.debug(re);
       
   705                 if (pe == null) {
       
   706                     pe = new PackagerException(re,
       
   707                             "MSG_BundlerRuntimeException",
       
   708                             bundler.getName(), re.toString());
       
   709                 }
       
   710             } finally {
       
   711                 if (userProvidedBuildRoot) {
       
   712                     Log.verbose(MessageFormat.format(
       
   713                             I18N.getString("message.debug-working-directory"),
       
   714                             (new File(buildRoot)).getAbsolutePath()));
       
   715                 }
       
   716             }
       
   717         }
       
   718         if (pe != null) {
       
   719             // throw packager exception only after trying all bundlers
       
   720             throw pe;
       
   721         }
       
   722         return bundleCreated;
       
   723     }
   665     }
   724 
   666 
   725     private void addResources(DeployParams deployParams,
   667     private void addResources(DeployParams deployParams,
   726             String inputdir) throws PackagerException {
   668             String inputdir) throws PackagerException {
   727 
   669