1 /* 2 * Copyright (c) 2018, 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 createImage = 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> jpackagerOptions = 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", "rpm", "deb", 52 "dmg", "pkg", "pkg-app-store"}; 53 54 // --output, -o, --input, -i, --files, -f, --main-jar, -j, --class, -c 55 private static final String [] BLOCKED_JPACKAGER_OPTIONS = {"--output", "-o", "--input", "-i", 56 "--files", "-f", "--main-jar", 57 "-j", "--class", "-c"}; 58 59 private static final String RUNTIME_IMAGE_OPTION = "--runtime-image"; 60 61 private static final String ERR_UNKNOWN_OPTION = "Unknown option: "; 62 private static final String ERR_MISSING_VALUE = "Value is required for option "; 63 private static final String ERR_MISSING_MODE = "Error: create-image or create-installer mode is required"; 64 private static final String ERR_MISSING_JNLP = "Error: --jnlp is required"; 65 private static final String ERR_MISSING_OUTPUT = "Error: --output is required"; 66 private static final String ERR_OUTPUT_EXISTS = "Error: output folder already exists"; 67 private static final String ERR_KEEP_EXISTS = "Error: folder for --keep argument already exists"; 68 private static final String ERR_INVALID_PROTOCOL_JNLP = "Error: Invalid protocol for JNLP file. Only HTTP, HTTPS and FILE protocols are supported."; 69 70 public boolean createImage() { 71 return createImage; 72 } 73 74 public boolean createInstaller() { 75 return createInstaller; 76 } 77 78 public String getInstallerType() { 79 return installerType; 80 } 81 82 public String getJNLP() { 83 return jnlp; 84 } 85 86 public String getOutput() { 87 return output; 88 } 89 90 public String keep() { 91 return keep; 92 } 93 94 public boolean help() { 95 return help; 96 } 97 98 public boolean verbose() { 99 return verbose; 100 } 101 102 public boolean version() { 103 return version; 104 } 105 106 public List<String> getJPackagerOptions() { 107 return jpackagerOptions; 108 } 109 110 public boolean isRuntimeImageSet() { 111 return isRuntimeImageSet; 112 } 113 114 // Helper method to dump all options 115 private void display() { 116 System.out.println("Options:"); 117 System.out.println("createImage: " + createImage); 118 System.out.println("createInstaller: " + createInstaller); 119 System.out.println("installerType: " + installerType); 120 System.out.println("jnlp: " + jnlp); 121 System.out.println("output: " + output); 122 System.out.println("keep: " + keep); 123 System.out.println("help: " + help); 124 System.out.println("verbose: " + verbose); 125 System.out.println("version: " + version); 126 for (int i = 0; i < jpackagerOptions.size(); i++) { 127 System.out.println("jpackagerOptions[" + i + "]: " + jpackagerOptions.get(i)); 128 } 129 } 130 131 private void validate() { 132 if (help || version) { 133 return; 134 } 135 136 if (!createImage && !createInstaller) { 137 optionError(ERR_MISSING_MODE); 138 } 139 140 if (jnlp == null) { 141 optionError(ERR_MISSING_JNLP); 142 } else { 143 int index = jnlp.indexOf(":"); 144 if (index == -1 || index == 0) { 145 optionError(ERR_INVALID_PROTOCOL_JNLP); 146 } else { 147 String protocol = jnlp.substring(0, index); 148 if (!protocol.equalsIgnoreCase("http") && 149 !protocol.equalsIgnoreCase("https") && 150 !protocol.equalsIgnoreCase("file")) { 151 optionError(ERR_INVALID_PROTOCOL_JNLP); 152 } 153 } 154 } 155 156 if (output == null) { 157 optionError(ERR_MISSING_OUTPUT); 158 } else { 159 File file = new File(output); 160 if (file.exists()) { 161 optionErrorNoHelp(ERR_OUTPUT_EXISTS); 162 } 163 } 164 165 if (keep != null) { 166 File file = new File(keep); 167 if (file.exists()) { 168 optionErrorNoHelp(ERR_KEEP_EXISTS); 169 } 170 } 171 172 jpackagerOptions.forEach((option) -> { 173 if (isBlockedOption(option)) { 174 Log.error(option + " is not allowed via --jpackager-options, since it will conflict with " 175 + "same option generated by JNLPConverter."); 176 } 177 }); 178 } 179 180 public boolean isOptionPresent(String option) { 181 for (String jpackagerOption : jpackagerOptions) { 182 if (jpackagerOption.equalsIgnoreCase(option)) { 183 return true; 184 } 185 } 186 187 return false; 188 } 189 190 private boolean isBlockedOption(String option) { 191 for (String blockedOption : BLOCKED_JPACKAGER_OPTIONS) { 192 if (blockedOption.equalsIgnoreCase(option)) { 193 return true; 194 } 195 } 196 197 return false; 198 } 199 200 public static void showHelp() { 201 // System.out.println("********* Help should not be longer then 80 characters as per JEP-293 *********"); 202 System.out.println("Usage: java -jar JNLPConverter.jar <mode> <options>"); 203 System.out.println(""); 204 System.out.println("where mode is one of:"); 205 System.out.println(" create-image"); 206 System.out.println(" Generates a platform-specific application image."); 207 System.out.println(" create-installer <type>"); 208 System.out.println(" Generates a platform-specific installer for the application."); 209 System.out.println(" Valid values for \"type\" are \"msi\", \"rpm\", \"deb\", \"dmg\", \"pkg\","); 210 System.out.println(" \"pkg-app-store\". If \"type\" is omitted, all supported types of installable"); 211 System.out.println(" packages for current platform will be generated."); 212 System.out.println(""); 213 System.out.println("Possible options include:"); 214 System.out.println(" -j, --jnlp <path>"); 215 System.out.println(" Full path to JNLP file. Supported protocols are HTTP/HTTPS/FILE."); 216 System.out.println(" -o, --output <path>"); 217 System.out.println(" Name of the directory where generated output files are placed."); 218 System.out.println(" -k, --keep <path>"); 219 System.out.println(" Keep JNLP, JARs and command line arguments for jpackager"); 220 System.out.println(" in directory provided."); 221 System.out.println(" --jpackager-options <options>"); 222 System.out.println(" Specify additional jpackager options or overwrite provided by JNLPConverter."); 223 System.out.println(" All jpackager options can be specified except: --output -o, --input -i,"); 224 System.out.println(" --files -f, --main-jar -j and --class -c."); 225 System.out.println(" -h, --help, -?"); 226 System.out.println(" Print this help message"); 227 System.out.println(" -v, --verbose"); 228 System.out.println(" Enable verbose output."); 229 System.out.println(" --version"); 230 System.out.println(" Version information."); 231 System.out.println("To specify an argument for a long option, you can use --<name>=<value> or"); 232 System.out.println("--<name> <value>."); 233 System.out.println("To specify proxy server use standard Java properties http.proxyHost and http.proxyPort."); 234 } 235 236 private static boolean isInstallerType(String type) { 237 for (String installerType : INSTALLER_TYPES) { 238 if (installerType.equals(type)) { 239 return true; 240 } 241 } 242 243 return false; 244 } 245 246 public static Options parseArgs(String[] args) { 247 Options options = new Options(); 248 249 int index = 0; 250 if (args.length >= 1) { 251 switch (args[0]) { 252 case "create-image": 253 options.createImage = true; 254 index = 1; 255 break; 256 case "create-installer": 257 options.createInstaller = true; 258 index = 1; 259 if (args.length >= 2) { 260 if (isInstallerType(args[1])) { 261 options.installerType = args[1]; 262 index = 2; 263 } 264 } 265 break; 266 case "-h": 267 case "--help": 268 case "-?": 269 case "--version": 270 break; 271 default: 272 optionError(Options.ERR_MISSING_MODE); 273 break; 274 } 275 } 276 277 for (int i = index; i < args.length; i++) { 278 String arg = args[i]; 279 280 if (arg.equals("--jnlp")) { 281 if (++i >= args.length) { 282 optionError(Options.ERR_MISSING_VALUE, "--jnlp"); 283 } 284 options.jnlp = args[i]; 285 } else if (arg.startsWith(JNLP_OPTION_PREFIX)) { 286 options.jnlp = arg.substring(JNLP_OPTION_PREFIX.length()); 287 } else if (arg.equals("--output")) { 288 if (++i >= args.length) { 289 optionError(Options.ERR_MISSING_VALUE, "--output"); 290 } 291 options.output = args[i]; 292 } else if (arg.startsWith(OUTPUT_OPTION_PREFIX)) { 293 options.output = arg.substring(OUTPUT_OPTION_PREFIX.length()); 294 } else if (arg.equals("--keep")) { 295 if (++i >= args.length) { 296 optionError(Options.ERR_MISSING_VALUE, "--keep"); 297 } 298 options.keep = args[i]; 299 } else if (arg.startsWith(KEEP_OPTION_PREFIX)) { 300 options.keep = arg.substring(KEEP_OPTION_PREFIX.length()); 301 } else if (arg.equals("--help")) { 302 options.help = true; 303 } else if (arg.equals("--verbose")) { 304 options.verbose = true; 305 } else if (arg.equals("--version")) { 306 options.version = true; 307 } else if (arg.equals("-j")) { // short options 308 if (++i >= args.length) { 309 optionError(Options.ERR_MISSING_VALUE, "-j"); 310 } 311 options.jnlp = args[i]; 312 } else if (arg.startsWith(JNLP_OPTION_SHORT_PREFIX)) { 313 options.jnlp = arg.substring(JNLP_OPTION_SHORT_PREFIX.length()); 314 } else if (arg.equals("-o")) { 315 if (++i >= args.length) { 316 optionError(Options.ERR_MISSING_VALUE, "-o"); 317 } 318 options.output = args[i]; 319 } else if (arg.startsWith(OUTPUT_OPTION_SHORT_PREFIX)) { 320 options.output = arg.substring(OUTPUT_OPTION_SHORT_PREFIX.length()); 321 } else if (arg.equals("-k")) { 322 if (++i >= args.length) { 323 optionError(Options.ERR_MISSING_VALUE, "-k"); 324 } 325 options.keep = args[i]; 326 } else if (arg.startsWith(KEEP_OPTION_SHORT_PREFIX)) { 327 options.keep = arg.substring(KEEP_OPTION_SHORT_PREFIX.length()); 328 } else if (arg.equals("-h") || arg.equals("-?")) { 329 options.help = true; 330 } else if (arg.equals("-v")) { 331 options.verbose = true; 332 } else if (arg.equals("--jpackager-options")) { 333 for (i = (i + 1); i < args.length; i++) { 334 if (!options.isRuntimeImageSet) { 335 if (args[i].equals(RUNTIME_IMAGE_OPTION)) { 336 options.isRuntimeImageSet = true; 337 } 338 } 339 options.jpackagerOptions.add(args[i]); 340 } 341 } else { 342 optionError(ERR_UNKNOWN_OPTION, arg); 343 } 344 } 345 346 //options.display(); // For testing only 347 options.validate(); 348 349 return options; 350 } 351 352 private static void optionErrorNoHelp(String msg) { 353 System.out.println(msg); 354 System.exit(1); 355 } 356 357 private static void optionError(String msg) { 358 System.out.println(msg); 359 System.out.println(); 360 showHelp(); 361 System.exit(1); 362 } 363 364 private static void optionError(String msg, String option) { 365 System.out.println(msg + option); 366 System.out.println(); 367 showHelp(); 368 System.exit(1); 369 } 370 }