1 /* 2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jnlp.converter; 25 26 import java.io.File; 27 import java.util.ArrayList; 28 import java.util.List; 29 30 public class Options { 31 32 private boolean createAppImage = false; 33 private boolean createInstaller = false; 34 private String installerType = null; 35 private String jnlp = null; 36 private String output = null; 37 private String keep = null; 38 private boolean help = false; 39 private boolean verbose = false; 40 private boolean version = false; 41 private final List<String> jpackageOptions = new ArrayList<>(); 42 private boolean isRuntimeImageSet = false; 43 44 private static final String JNLP_OPTION_PREFIX = "--jnlp="; 45 private static final String OUTPUT_OPTION_PREFIX = "--output="; 46 private static final String KEEP_OPTION_PREFIX = "--keep="; 47 private static final String JNLP_OPTION_SHORT_PREFIX = "-j"; 48 private static final String OUTPUT_OPTION_SHORT_PREFIX = "-o"; 49 private static final String KEEP_OPTION_SHORT_PREFIX = "-k"; 50 51 private static final String [] INSTALLER_TYPES = {"msi", "exe", "dmg", "pkg", 52 "rpm", "deb"}; 53 54 // --output, -o, --input, -i, --main-jar, --main-class 55 private static final String [] BLOCKED_JPACKAGE_OPTIONS = {"--output", "-o", "--input", "-i", 56 "--main-jar", "--main-class"}; 57 58 private static final String RUNTIME_IMAGE_OPTION = "--runtime-image"; 59 60 private static final String ERR_UNKNOWN_OPTION = "Unknown option: "; 61 private static final String ERR_MISSING_VALUE = "Value is required for option "; 62 private static final String ERR_MISSING_MODE = "Error: create-app-image or create-installer mode is required"; 63 private static final String ERR_MISSING_JNLP = "Error: --jnlp is required"; 64 private static final String ERR_MISSING_OUTPUT = "Error: --output is required"; 65 private static final String ERR_OUTPUT_EXISTS = "Error: output folder already exists"; 66 private static final String ERR_KEEP_EXISTS = "Error: folder for --keep argument already exists"; 67 private static final String ERR_INVALID_PROTOCOL_JNLP = "Error: Invalid protocol for JNLP file. Only HTTP, HTTPS and FILE protocols are supported."; 68 69 public boolean createAppImage() { 70 return createAppImage; 71 } 72 73 public boolean createInstaller() { 74 return createInstaller; 75 } 76 77 public String getInstallerType() { 78 return installerType; 79 } 80 81 public String getJNLP() { 82 return jnlp; 83 } 84 85 public String getOutput() { 86 return output; 87 } 88 89 public String keep() { 90 return keep; 91 } 92 93 public boolean help() { 94 return help; 95 } 96 97 public boolean verbose() { 98 return verbose; 99 } 100 101 public boolean version() { 102 return version; 103 } 104 105 public List<String> getJPackageOptions() { 106 return jpackageOptions; 107 } 108 109 public boolean isRuntimeImageSet() { 110 return isRuntimeImageSet; 111 } 112 113 // Helper method to dump all options 114 private void display() { 115 System.out.println("Options:"); 116 System.out.println("createAppImage: " + createAppImage); 117 System.out.println("createInstaller: " + createInstaller); 118 System.out.println("installerType: " + installerType); 119 System.out.println("jnlp: " + jnlp); 120 System.out.println("output: " + output); 121 System.out.println("keep: " + keep); 122 System.out.println("help: " + help); 123 System.out.println("verbose: " + verbose); 124 System.out.println("version: " + version); 125 for (int i = 0; i < jpackageOptions.size(); i++) { 126 System.out.println("jpackageOptions[" + i + "]: " + jpackageOptions.get(i)); 127 } 128 } 129 130 private void validate() { 131 if (help || version) { 132 return; 133 } 134 135 if (!createAppImage && !createInstaller) { 136 optionError(ERR_MISSING_MODE); 137 } 138 139 if (jnlp == null) { 140 optionError(ERR_MISSING_JNLP); 141 } else { 142 int index = jnlp.indexOf(":"); 143 if (index == -1 || index == 0) { 144 optionError(ERR_INVALID_PROTOCOL_JNLP); 145 } else { 146 String protocol = jnlp.substring(0, index); 147 if (!protocol.equalsIgnoreCase("http") && 148 !protocol.equalsIgnoreCase("https") && 149 !protocol.equalsIgnoreCase("file")) { 150 optionError(ERR_INVALID_PROTOCOL_JNLP); 151 } 152 } 153 } 154 155 if (output == null) { 156 optionError(ERR_MISSING_OUTPUT); 157 } else { 158 File file = new File(output); 159 if (file.exists()) { 160 optionErrorNoHelp(ERR_OUTPUT_EXISTS); 161 } 162 } 163 164 if (keep != null) { 165 File file = new File(keep); 166 if (file.exists()) { 167 optionErrorNoHelp(ERR_KEEP_EXISTS); 168 } 169 } 170 171 jpackageOptions.forEach((option) -> { 172 if (isBlockedOption(option)) { 173 Log.error(option + " is not allowed via --jpackage-options, since it will conflict with " 174 + "same option generated by JNLPConverter."); 175 } 176 }); 177 } 178 179 public boolean isOptionPresent(String option) { 180 for (String jpackageOption : jpackageOptions) { 181 if (jpackageOption.equalsIgnoreCase(option)) { 182 return true; 183 } 184 } 185 186 return false; 187 } 188 189 private boolean isBlockedOption(String option) { 190 for (String blockedOption : BLOCKED_JPACKAGE_OPTIONS) { 191 if (blockedOption.equalsIgnoreCase(option)) { 192 return true; 193 } 194 } 195 196 return false; 197 } 198 199 public static void showHelp() { 200 // System.out.println("********* Help should not be longer then 80 characters as per JEP-293 *********"); 201 System.out.println("Usage: java -jar JNLPConverter.jar <mode> <options>"); 202 System.out.println(""); 203 System.out.println("where mode is one of:"); 204 System.out.println(" create-app-image"); 205 System.out.println(" Generates a platform-specific application image."); 206 System.out.println(" create-installer"); 207 System.out.println(" Generates a platform-specific installer for the application."); 208 System.out.println(""); 209 System.out.println("Possible options include:"); 210 System.out.println(" -j, --jnlp <path>"); 211 System.out.println(" Full path to JNLP file. Supported protocols are HTTP/HTTPS/FILE."); 212 System.out.println(" -o, --output <path>"); 213 System.out.println(" Name of the directory where generated output files are placed."); 214 System.out.println(" -k, --keep <path>"); 215 System.out.println(" Keep JNLP, JARs and command line arguments for jpackage"); 216 System.out.println(" in directory provided."); 217 System.out.println(" --jpackage-options <options>"); 218 System.out.println(" Specify additional jpackage options or overwrite provided by JNLPConverter."); 219 System.out.println(" All jpackage options can be specified except: --output -o, --input -i,"); 220 System.out.println(" --main-jar -j and --class -c."); 221 System.out.println(" --installer-type <type>"); 222 System.out.println(" The type of the installer to create"); 223 System.out.println(" Valid values are: {\"exe\", \"msi\", \"rpm\", \"deb\", \"pkg\", \"dmg\"}"); 224 System.out.println(" If this option is not specified (in create-installer mode) all"); 225 System.out.println(" supported types of installable packages for the current"); 226 System.out.println(" platform will be created."); 227 System.out.println(" -h, --help, -?"); 228 System.out.println(" Print this help message"); 229 System.out.println(" -v, --verbose"); 230 System.out.println(" Enable verbose output."); 231 System.out.println(" --version"); 232 System.out.println(" Version information."); 233 System.out.println("To specify an argument for a long option, you can use --<name>=<value> or"); 234 System.out.println("--<name> <value>."); 235 System.out.println("To specify proxy server use standard Java properties http.proxyHost and http.proxyPort."); 236 } 237 238 private static boolean isInstallerType(String type) { 239 for (String installerType : INSTALLER_TYPES) { 240 if (installerType.equals(type)) { 241 return true; 242 } 243 } 244 245 return false; 246 } 247 248 public static Options parseArgs(String[] args) { 249 Options options = new Options(); 250 251 int index = 0; 252 if (args.length >= 1) { 253 switch (args[0]) { 254 case "create-app-image": 255 options.createAppImage = true; 256 index = 1; 257 break; 258 case "create-installer": 259 options.createInstaller = true; 260 index = 1; 261 break; 262 case "-h": 263 case "--help": 264 case "-?": 265 case "--version": 266 break; 267 default: 268 optionError(Options.ERR_MISSING_MODE); 269 break; 270 } 271 } 272 273 for (int i = index; i < args.length; i++) { 274 String arg = args[i]; 275 276 if (arg.equals("--jnlp")) { 277 if (++i >= args.length) { 278 optionError(Options.ERR_MISSING_VALUE, "--jnlp"); 279 } 280 options.jnlp = args[i]; 281 } else if (arg.startsWith(JNLP_OPTION_PREFIX)) { 282 options.jnlp = arg.substring(JNLP_OPTION_PREFIX.length()); 283 } else if (arg.equals("--output")) { 284 if (++i >= args.length) { 285 optionError(Options.ERR_MISSING_VALUE, "--output"); 286 } 287 options.output = args[i]; 288 } else if (arg.startsWith(OUTPUT_OPTION_PREFIX)) { 289 options.output = arg.substring(OUTPUT_OPTION_PREFIX.length()); 290 } else if (arg.equals("--keep")) { 291 if (++i >= args.length) { 292 optionError(Options.ERR_MISSING_VALUE, "--keep"); 293 } 294 options.keep = args[i]; 295 } else if (arg.startsWith(KEEP_OPTION_PREFIX)) { 296 options.keep = arg.substring(KEEP_OPTION_PREFIX.length()); 297 } else if (arg.equals("--help")) { 298 options.help = true; 299 } else if (arg.equals("--verbose")) { 300 options.verbose = true; 301 } else if (arg.equals("--version")) { 302 options.version = true; 303 } else if (arg.equals("-j")) { // short options 304 if (++i >= args.length) { 305 optionError(Options.ERR_MISSING_VALUE, "-j"); 306 } 307 options.jnlp = args[i]; 308 } else if (arg.startsWith(JNLP_OPTION_SHORT_PREFIX)) { 309 options.jnlp = arg.substring(JNLP_OPTION_SHORT_PREFIX.length()); 310 } else if (arg.equals("-o")) { 311 if (++i >= args.length) { 312 optionError(Options.ERR_MISSING_VALUE, "-o"); 313 } 314 options.output = args[i]; 315 } else if (arg.startsWith(OUTPUT_OPTION_SHORT_PREFIX)) { 316 options.output = arg.substring(OUTPUT_OPTION_SHORT_PREFIX.length()); 317 } else if (arg.equals("-k")) { 318 if (++i >= args.length) { 319 optionError(Options.ERR_MISSING_VALUE, "-k"); 320 } 321 options.keep = args[i]; 322 } else if (arg.startsWith(KEEP_OPTION_SHORT_PREFIX)) { 323 options.keep = arg.substring(KEEP_OPTION_SHORT_PREFIX.length()); 324 } else if (arg.equals("-h") || arg.equals("-?")) { 325 options.help = true; 326 } else if (arg.equals("-v")) { 327 options.verbose = true; 328 } else if (arg.equals("--jpackage-options")) { 329 for (i = (i + 1); i < args.length; i++) { 330 if (!options.isRuntimeImageSet) { 331 if (args[i].equals(RUNTIME_IMAGE_OPTION)) { 332 options.isRuntimeImageSet = true; 333 } 334 } 335 options.jpackageOptions.add(args[i]); 336 } 337 } else if (arg.equals("--installer-type")) { 338 if ((i + 1) < args.length) { 339 if (isInstallerType(args[i + 1])) { 340 options.installerType = args[i + 1]; 341 i++; 342 } 343 } 344 } else { 345 optionError(ERR_UNKNOWN_OPTION, arg); 346 } 347 } 348 349 //options.display(); // For testing only 350 options.validate(); 351 352 return options; 353 } 354 355 private static void optionErrorNoHelp(String msg) { 356 System.out.println(msg); 357 System.exit(1); 358 } 359 360 private static void optionError(String msg) { 361 System.out.println(msg); 362 System.out.println(); 363 showHelp(); 364 System.exit(1); 365 } 366 367 private static void optionError(String msg, String option) { 368 System.out.println(msg + option); 369 System.out.println(); 370 showHelp(); 371 System.exit(1); 372 } 373 }