1 /* 2 * Copyright (c) 2011, 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.tools.packager; 27 28 import com.oracle.tools.packager.*; 29 import com.oracle.tools.packager.ConfigException; 30 import com.oracle.tools.packager.UnsupportedPlatformException; 31 import com.sun.javafx.tools.packager.bundlers.Bundler.BundleType; 32 import com.oracle.tools.packager.Log; 33 34 import java.io.File; 35 import java.io.FileInputStream; 36 import java.io.IOException; 37 import java.text.MessageFormat; 38 import java.util.*; 39 import java.util.stream.Stream; 40 import java.nio.file.Files; 41 import java.nio.file.Path; 42 43 import jdk.packager.internal.JLinkBundlerHelper; 44 45 46 public class Main { 47 48 private static final ResourceBundle bundle = 49 ResourceBundle.getBundle("com/sun/javafx/tools/packager/Bundle"); 50 51 private static final String version = bundle.getString("MSG_Version") 52 + " " + PackagerLib.JAVAFX_VERSION + "\n"; 53 private static final String help = bundle.getString("MSG_Help_1") 54 + bundle.getString("MSG_Help_2") 55 + MessageFormat.format(bundle.getString("MSG_Help_3"), File.pathSeparator) 56 + bundle.getString("MSG_Help_4") 57 + bundle.getString("MSG_Help_5") 58 + bundle.getString("MSG_Help_6") 59 + bundle.getString("MSG_Help_7"); 60 61 private static String nextArg(String args[], int i) { 62 return (i == args.length - 1) ? "" : args[i + 1]; 63 } 64 65 private static boolean verbose = false; 66 private static boolean packageAsJar = false; 67 private static boolean genJNLP = false; 68 private static boolean genPackages = false; 69 private static boolean css2Bin = false; 70 71 private static void addResources(CommonParams commonParams, 72 String srcdir, String srcfiles) { 73 if (srcdir == null || "".equals(srcdir)) { 74 return; 75 } 76 77 File baseDir = new File(srcdir); 78 79 if (!baseDir.isDirectory()) { 80 Log.info("Unable to add resources: \"-srcdir\" is not a directory."); 81 return; 82 } 83 84 List<String> fileNames; 85 if (srcfiles != null) { 86 fileNames = Arrays.asList(srcfiles.split(File.pathSeparator)); 87 } else { 88 // "-srcfiles" is omitted, all files in srcdir (which 89 // is a mandatory argument in this case) will be packaged. 90 fileNames = new ArrayList<>(); 91 try (Stream<Path> files = Files.list(baseDir.toPath())) { 92 files.forEach(file -> fileNames.add(file.getFileName().toString())); 93 } catch (IOException e) { 94 Log.info("Unable to add resources: " + e.getMessage()); 95 } 96 } 97 98 fileNames.forEach(file -> commonParams.addResource(baseDir, file)); 99 } 100 101 private static void addArgument(DeployParams deployParams, String argument) { 102 if (deployParams.arguments != null) { 103 deployParams.arguments.add(argument); 104 } else { 105 List<String> list = new LinkedList<>(); 106 list.add(argument); 107 deployParams.setArguments(list); 108 } 109 } 110 111 private static void addArgument(CreateJarParams deployParams, String argument) { 112 if (deployParams.arguments != null) { 113 deployParams.arguments.add(argument); 114 } else { 115 List<String> list = new LinkedList<>(); 116 list.add(argument); 117 deployParams.setArguments(list); 118 } 119 } 120 121 private static Map<String, String> createAttrMap(String arg) { 122 Map<String, String> map = new HashMap<>(); 123 if (arg == null || "".equals(arg)) { 124 return null; 125 } 126 String[] pairsArray = arg.split(","); 127 for (String pair: pairsArray) { 128 String[] attr = pair.split("="); 129 map.put(attr[0].trim(), attr[1].trim()); 130 } 131 return map; 132 } 133 134 private static List<Param> parseParams(String filename) throws IOException { 135 File paramFile = new File(filename); 136 Properties properties = new Properties(); 137 FileInputStream in = new FileInputStream(paramFile); 138 properties.load(in); 139 in.close(); 140 141 List<Param> parameters = new ArrayList<>(properties.size()); 142 143 for (Map.Entry en : properties.entrySet()) { 144 Param p = new Param(); 145 p.setName((String)en.getKey()); 146 p.setValue((String)en.getValue()); 147 parameters.add(p); 148 } 149 return parameters; 150 } 151 152 private static List<HtmlParam> parseHtmlParams(String filename) throws IOException { 153 File paramFile = new File(filename); 154 Properties properties = new Properties(); 155 FileInputStream in = new FileInputStream(paramFile); 156 properties.load(in); 157 in.close(); 158 159 List<HtmlParam> parameters = new ArrayList<>(properties.size()); 160 161 for (Map.Entry en : properties.entrySet()) { 162 HtmlParam p = new HtmlParam(); 163 p.setName((String)en.getKey()); 164 p.setValue((String)en.getValue()); 165 parameters.add(p); 166 } 167 return parameters; 168 } 169 170 private static List<JSCallback> parseCallbacks(String param) { 171 String[] callbacks = param.split(","); 172 List<JSCallback> list = new ArrayList<>(callbacks.length); 173 174 for (String cb: callbacks) { 175 String[] nameCmd = cb.split(":"); 176 if (nameCmd.length == 2) { 177 list.add(new JSCallback(nameCmd[0], nameCmd[1])); 178 } 179 } 180 return list; 181 } 182 183 184 @SuppressWarnings("deprecation") 185 public static void main(String... args) throws Exception { 186 BundleType bundleType = BundleType.NONE; 187 188 if (args.length == 0 || args.length == 1 && args[0].equals("-help")) { 189 System.out.println(help); 190 } else if (args.length == 1 && args[0].equals("-version")) { 191 System.out.println(version); 192 } else { 193 PackagerLib packager = new PackagerLib(); 194 CreateJarParams createJarParams = new CreateJarParams(); 195 DeployParams deployParams = new DeployParams(); 196 CreateBSSParams createBssParams = new CreateBSSParams(); 197 SignJarParams signJarParams = new SignJarParams(); 198 MakeAllParams makeAllParams = new MakeAllParams(); 199 String srcdir = null; 200 String srcfiles = null; 201 202 try { 203 if (args[0].equalsIgnoreCase("-createjar")) { 204 for (int i = 1; i < args.length; i++) { 205 String arg = args[i]; 206 if (arg.equalsIgnoreCase("-appclass")) { 207 createJarParams.setApplicationClass(nextArg(args, i++)); 208 } else if (arg.equalsIgnoreCase("-preloader")) { 209 createJarParams.setPreloader(nextArg(args, i++)); 210 } else if (arg.equalsIgnoreCase("-classpath")) { 211 createJarParams.setClasspath(nextArg(args, i++)); 212 } else if (arg.equalsIgnoreCase("-manifestAttrs")) { 213 createJarParams.setManifestAttrs(createAttrMap(nextArg(args, i++))); 214 } else if (arg.equalsIgnoreCase("-noembedlauncher")) { 215 System.err.println("-noembedlauncher is deprecated"); 216 } else if (arg.equalsIgnoreCase("-nocss2bin")) { 217 createJarParams.setCss2bin(false); 218 } else if (arg.equalsIgnoreCase("-runtimeVersion")) { 219 createJarParams.setFxVersion(nextArg(args, i++)); 220 System.err.println("-runtimeVersion is deprecated"); 221 } else if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) { 222 createJarParams.setVerbose(true); 223 verbose = true; 224 } else if (arg.equalsIgnoreCase("-outdir")) { 225 createJarParams.setOutdir(new File(nextArg(args, i++))); 226 } else if (arg.equalsIgnoreCase("-outfile")) { 227 createJarParams.setOutfile(nextArg(args, i++)); 228 } else if (arg.equalsIgnoreCase("-" + StandardBundlerParam.SOURCE_DIR.getID())) { 229 srcdir = nextArg(args, i++); 230 } else if (arg.equalsIgnoreCase("-srcfiles")) { 231 srcfiles = nextArg(args, i++); 232 } else if (arg.equalsIgnoreCase("-argument")) { 233 addArgument(createJarParams, nextArg(args, i++)); 234 } else if (arg.equalsIgnoreCase("-paramFile")) { 235 createJarParams.setParams(parseParams(nextArg(args, i++))); 236 } else { 237 throw new PackagerException("ERR_UnknownArgument", arg); 238 } 239 } 240 241 addResources(createJarParams, srcdir, srcfiles); 242 packageAsJar = true; 243 } else if (args[0].equalsIgnoreCase("-deploy")) { 244 File templateInFile = null; 245 File templateOutFile = null; 246 deployParams.setBundleType(BundleType.JNLP); 247 deployParams.setTargetFormat("jnlp"); 248 249 //can only set it to true with command line, reset default 250 deployParams.setEmbedJNLP(false); 251 252 for (int i = 1; i < args.length; i++) { 253 String arg = args[i]; 254 if (arg.startsWith("-B")) { 255 String key; 256 String value; 257 258 int keyStart = 2; 259 int equals = arg.indexOf("="); 260 int len = arg.length(); 261 if (equals < keyStart) { 262 if (keyStart < len) { 263 key = arg.substring(keyStart, len); 264 value = Boolean.TRUE.toString(); 265 } else { 266 continue; 267 } 268 } else if (keyStart < equals) { 269 key = arg.substring(keyStart, equals); 270 value = arg.substring(equals+1, len); 271 } else { 272 continue; 273 } 274 deployParams.addBundleArgument(key, value); 275 } else if (arg.equalsIgnoreCase("-title")) { 276 deployParams.setTitle(nextArg(args, i++)); 277 } else if (arg.equalsIgnoreCase("-vendor")) { 278 deployParams.setVendor(nextArg(args, i++)); 279 } else if (arg.equalsIgnoreCase("-native")) { 280 bundleType = BundleType.NATIVE; 281 String format = null; //null means ANY 282 if (i+1 < args.length && !args[i+1].startsWith("-")) { 283 String v = args[++i]; 284 com.sun.javafx.tools.packager.bundlers.Bundler.Bundle bundle = 285 com.sun.javafx.tools.packager.bundlers.Bundler.stringToBundle(v); 286 bundleType = bundle.type; 287 format = bundle.format; 288 } 289 deployParams.setBundleType(bundleType); 290 deployParams.setTargetFormat(format); 291 } else if (arg.equalsIgnoreCase("-description")) { 292 deployParams.setDescription(nextArg(args, i++)); 293 } else if(arg.equalsIgnoreCase("-appclass")) { 294 deployParams.setApplicationClass(nextArg(args, i++)); 295 } else if(arg.equalsIgnoreCase("-daemon")) { 296 deployParams.setServiceHint(true); 297 } else if(arg.equalsIgnoreCase("-installdirChooser")) { 298 deployParams.setInstalldirChooser(true); 299 } else if (arg.equalsIgnoreCase("-preloader")) { 300 deployParams.setPreloader(nextArg(args, i++)); 301 } else if (arg.equalsIgnoreCase("-paramFile")) { 302 deployParams.setParams(parseParams(nextArg(args, i++))); 303 } else if (arg.equalsIgnoreCase("-htmlParamFile")) { 304 deployParams.setHtmlParams(parseHtmlParams(nextArg(args, i++))); 305 } else if (arg.equalsIgnoreCase("-width")) { 306 deployParams.setWidth(Integer.parseInt(nextArg(args, i++))); 307 } else if (arg.equalsIgnoreCase("-height")) { 308 deployParams.setHeight(Integer.parseInt(nextArg(args, i++))); 309 } else if (arg.equalsIgnoreCase("-name")) { 310 deployParams.setAppName(nextArg(args, i++)); 311 } else if (arg.equalsIgnoreCase("-embedJNLP")) { 312 deployParams.setEmbedJNLP(true); 313 } else if (arg.equalsIgnoreCase("-embedCertificates")) { 314 System.err.println("-embedCertificates is deprecated"); 315 } else if (arg.equalsIgnoreCase("-allpermissions")) { 316 deployParams.setAllPermissions(true); 317 } else if (arg.equalsIgnoreCase("-updatemode")) { 318 deployParams.setUpdateMode(nextArg(args, i++)); 319 } else if (arg.equalsIgnoreCase("-isExtension")) { 320 deployParams.setExtension(true); 321 } else if (arg.equalsIgnoreCase("-callbacks")) { 322 deployParams.setJSCallbacks(parseCallbacks(nextArg(args, i++))); 323 } else if (arg.equalsIgnoreCase("-templateInFilename")) { 324 templateInFile = new File(nextArg(args, i++)); 325 } else if (arg.equalsIgnoreCase("-templateOutFilename")) { 326 templateOutFile = new File(nextArg(args, i++)); 327 } else if (arg.equalsIgnoreCase("-appId") || arg.equalsIgnoreCase("-templateId")) { 328 String appIdArg = nextArg(args, i++); 329 deployParams.setAppId(appIdArg); 330 deployParams.setId(appIdArg); 331 } else if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) { 332 deployParams.setVerbose(true); 333 verbose = true; 334 } else if (arg.equalsIgnoreCase("-includedt")) { 335 deployParams.setIncludeDT(true); 336 } else if (arg.equalsIgnoreCase("-outdir")) { 337 deployParams.setOutdir(new File(nextArg(args, i++))); 338 } else if (arg.equalsIgnoreCase("-outfile")) { 339 deployParams.setOutfile(nextArg(args, i++)); 340 } else if (arg.equalsIgnoreCase("-" + StandardBundlerParam.SOURCE_DIR.getID())) { 341 srcdir = nextArg(args, i++); 342 deployParams.srcdir = srcdir; 343 } else if (arg.equalsIgnoreCase("-srcfiles")) { 344 srcfiles = nextArg(args, i++); 345 } else if (arg.equalsIgnoreCase("-argument")) { 346 addArgument(deployParams, nextArg(args, i++)); 347 } else if (arg.equalsIgnoreCase("-nosign")) { 348 deployParams.setSignBundle(false); 349 } else if (arg.equals(ADD_MODULES)) { 350 deployParams.addAddModule(nextArg(args, i++)); 351 } else if (arg.startsWith(ADD_MODULES + "=")) { 352 deployParams.addAddModule(arg.replace(ADD_MODULES + "=", "")); 353 } else if (arg.equals(LIMIT_MODULES)) { 354 deployParams.addLimitModule(nextArg(args, i++)); 355 } else if (arg.startsWith(LIMIT_MODULES + "=")) { 356 deployParams.addLimitModule(arg.replace(LIMIT_MODULES + "=", "")); 357 } else if (arg.equals(STRIP_NATIVE_COMMANDS)) { 358 deployParams.setStripNativeCommands(Boolean.valueOf(nextArg(args, i++))); 359 } else if (arg.equals(STRIP_NATIVE_COMMANDS + "=")) { 360 deployParams.setStripNativeCommands(Boolean.valueOf(arg.replace(STRIP_NATIVE_COMMANDS + "=", ""))); 361 } else if (arg.equals(DETECT_MODULES)) { 362 deployParams.setDetectModules(true); 363 } else if (arg.equals(MODULE_PATH) || arg.equals(P)) { 364 deployParams.modulePath = nextArg(args, i++); 365 } else if (arg.equals(MODULE_PATH + "=")) { 366 deployParams.modulePath = arg.replace(MODULE_PATH + "=", ""); 367 } else if (arg.equals(MODULE) || arg.equals(M)) { 368 deployParams.setModule(nextArg(args, i++)); 369 } else if (arg.equals(MODULE + "=")) { 370 deployParams.setModule(arg.replace(MODULE + "=", "")); 371 } else if (arg.startsWith(J_XDEBUG)) { 372 deployParams.setDebug(arg.replace(J_XDEBUG, "")); 373 } else { 374 throw new PackagerException("ERR_UnknownArgument", arg); 375 } 376 } 377 if (templateInFile != null) { 378 deployParams.addTemplate(templateInFile, templateOutFile); 379 } 380 381 if (deployParams.validateForJNLP()) { 382 genJNLP = true; 383 } 384 385 if (deployParams.validateForBundle()) { 386 genPackages = true; 387 } 388 389 addResources(deployParams, srcdir, srcfiles); 390 } else if (args[0].equalsIgnoreCase("-createbss")) { 391 for (int i = 1; i < args.length; i++) { 392 String arg = args[i]; 393 if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) { 394 createBssParams.setVerbose(true); 395 verbose = true; 396 } else if (arg.equalsIgnoreCase("-outdir")) { 397 createBssParams.setOutdir(new File(nextArg(args, i++))); 398 } else if (arg.equalsIgnoreCase("-srcdir")) { 399 srcdir = nextArg(args, i++); 400 } else if (arg.equalsIgnoreCase("-srcfiles")) { 401 srcfiles = nextArg(args, i++); 402 } else { 403 throw new PackagerException("ERR_UnknownArgument", arg); 404 } 405 } 406 407 addResources(createBssParams, srcdir, srcfiles); 408 css2Bin = true; 409 } else if (args[0].equalsIgnoreCase("-help")) { 410 showBundlerHelp(args[1], args.length > 2 && "-verbose".equals(args[2])); 411 } else { 412 System.err.println(MessageFormat.format( 413 bundle.getString("ERR_UnknownCommand"), 414 args[0])); 415 System.exit(-1); 416 } 417 418 //set default logger 419 if (verbose) { 420 com.oracle.tools.packager.Log.setLogger(new com.oracle.tools.packager.Log.Logger(true)); 421 } else { 422 com.oracle.tools.packager.Log.setLogger(new com.oracle.tools.packager.Log.Logger(false)); 423 } 424 425 if (css2Bin) { 426 createBssParams.validate(); 427 packager.generateBSS(createBssParams); 428 } 429 if (packageAsJar) { 430 createJarParams.validate(); 431 packager.packageAsJar(createJarParams); 432 } 433 if (genJNLP) { 434 deployParams.setBundleType(BundleType.JNLP); 435 deployParams.validate(); 436 packager.generateDeploymentPackages(deployParams); 437 } 438 if (genPackages) { 439 deployParams.setBundleType(bundleType); 440 deployParams.validate(); 441 packager.generateDeploymentPackages(deployParams); 442 } 443 } catch (Exception e) { 444 if (verbose) { 445 throw e; 446 } else { 447 System.err.println(e.getMessage()); 448 if (e.getCause() != null && e.getCause() != e) { 449 System.err.println(e.getCause().getMessage()); 450 } 451 System.exit(-1); 452 } 453 } 454 } 455 } 456 457 private static final String MODULE = "--" + StandardBundlerParam.MODULE.getID(); 458 private static final String M = "-m"; 459 private static final String MODULE_PATH = "--" + StandardBundlerParam.MODULE_PATH.getID(); 460 private static final String P = "-p"; 461 private static final String ADD_MODULES = "--" + StandardBundlerParam.ADD_MODULES.getID(); 462 private static final String LIMIT_MODULES = "--" + StandardBundlerParam.LIMIT_MODULES.getID(); 463 private static final String STRIP_NATIVE_COMMANDS = "--" + StandardBundlerParam.STRIP_NATIVE_COMMANDS.getID(); 464 465 private static final String J_XDEBUG = JLinkBundlerHelper.DEBUG.getID() + ":"; 466 private static final String DETECT_MODULES = "--" + JLinkBundlerHelper.DETECT_MODULES.getID(); 467 468 public static void showBundlerHelp(String bundlerName, boolean verbose) { 469 //TODO I18N 470 if ("bundlers".equals(bundlerName)) { 471 // enumerate bundlers 472 System.out.println("Known Bundlers -- \n"); 473 for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) { 474 try { 475 bundler.validate(new HashMap<>()); 476 } catch (UnsupportedPlatformException upe) { 477 // don't list bundlers this platform cannot run 478 continue; 479 } catch (ConfigException ignore) { 480 // but requiring more than an empty map is perfectly fine. 481 //} catch (RuntimeException re) { 482 // re.printStackTrace(); 483 } 484 485 if (verbose) { 486 System.out.printf( 487 "%s - %s - %s\n\t%s\n", 488 bundler.getID(), 489 bundler.getName(), 490 bundler.getBundleType(), 491 bundler.getDescription() 492 ); 493 } else { 494 System.out.printf( 495 "%s - %s - %s\n", 496 bundler.getID(), 497 bundler.getName(), 498 bundler.getBundleType() 499 ); 500 } 501 } 502 } else { 503 // enumerate parameters for a bundler 504 for (Bundler bundler : Bundlers.createBundlersInstance().getBundlers()) { 505 if (bundler.getID().equals(bundlerName)) { 506 System.out.printf("Bundler Parameters for %s (%s) --\n", bundler.getName(), bundler.getID()); 507 for (BundlerParamInfo bpi : bundler.getBundleParameters()) { 508 if (bpi.getStringConverter() == null) continue; 509 if (verbose) { 510 System.out.printf( 511 "%s - %s - %s\n\t%s\n", 512 bpi.getID(), 513 bpi.getName(), 514 bpi.getValueType().getSimpleName(), 515 bpi.getDescription() 516 ); 517 } else { 518 System.out.printf( 519 "%s - %s - %s\n", 520 bpi.getID(), 521 bpi.getName(), 522 bpi.getValueType().getSimpleName() 523 ); 524 } 525 } 526 return; 527 } 528 } 529 System.out.printf("Sorry, no bundler matching the id %s was found.\n", bundlerName); 530 } 531 } 532 }