1 /* 2 * Copyright (c) 2011, 2014, 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.sun.javafx.tools.ant.Callback; 29 import com.sun.javafx.tools.packager.bundlers.*; 30 import com.sun.javafx.tools.packager.bundlers.Bundler.BundleType; 31 import com.sun.javafx.tools.resource.DeployResource; 32 import java.io.File; 33 import java.io.IOException; 34 import java.util.ArrayList; 35 import java.util.HashMap; 36 import java.util.HashSet; 37 import java.util.LinkedList; 38 import java.util.List; 39 import java.util.Map; 40 import java.util.Set; 41 import java.util.TreeSet; 42 43 public class DeployParams extends CommonParams { 44 public enum RunMode { 45 WEBSTART, EMBEDDED, STANDALONE, ALL 46 } 47 48 final List<DeployResource> resources = new ArrayList<>(); 49 50 String id; 51 String title; 52 String vendor; 53 String email; 54 String description; 55 String category; 56 String licenseType; 57 String copyright; 58 String version; 59 Boolean systemWide; 60 Boolean serviceHint; 61 62 String applicationClass; 63 String preloader; 64 65 List<Param> params; 66 List<HtmlParam> htmlParams; 67 List<String> arguments; //unnamed arguments 68 69 int width; 70 int height; 71 String embeddedWidth = null; 72 String embeddedHeight = null; 73 74 String appName; 75 String codebase; 76 77 boolean embedJNLP = true; 78 boolean embedCertificates = false; 79 boolean allPermissions = false; 80 String updateMode = "background"; 81 boolean isExtension = false; 82 boolean isSwingApp = false; 83 84 Boolean needShortcut = null; 85 Boolean needMenu = null; 86 boolean needInstall = false; 87 88 String outfile; 89 //if true then we cobundle js and image files needed 90 // for web deployment with the application 91 boolean includeDT; 92 93 String placeholder = null; 94 String appId = null; 95 96 // didn't have a setter... 97 boolean offlineAllowed = true; 98 99 List<JSCallback> callbacks; 100 101 //list of HTML templates to process 102 List<Template> templates = new LinkedList<>(); 103 104 String jrePlatform = "1.6+"; 105 String fxPlatform = PackagerLib.JAVAFX_VERSION+"+"; 106 File javaRuntimeToUse = null; 107 boolean javaRuntimeWasSet = false; 108 109 //list of jvm args (in theory string can contain spaces and need to be escaped 110 List<String> jvmargs = new LinkedList<>(); 111 Map<String, String> jvmUserArgs = new HashMap<>(); 112 113 //list of jvm properties (can also be passed as VM args 114 // but keeping them separate make it a bit more convinient for JNLP generation) 115 Map<String, String> properties = new HashMap<>(); 116 117 // raw arguments to the bundler 118 Map<String, ? super Object> bundlerArguments = new HashMap<>(); 119 120 String fallbackApp = "com.javafx.main.NoJavaFXFallback"; 121 122 public void setJavaRuntimeSource(File src) { 123 javaRuntimeToUse = src; 124 javaRuntimeWasSet = true; 125 } 126 127 public void setCodebase(String codebase) { 128 this.codebase = codebase; 129 } 130 131 public void setId(String id) { 132 this.id = id; 133 } 134 135 public void setCategory(String category) { 136 this.category = category; 137 } 138 139 public void setLicenseType(String licenseType) { 140 this.licenseType = licenseType; 141 } 142 143 public void setCopyright(String copyright) { 144 this.copyright = copyright; 145 } 146 147 public void setVersion(String version) { 148 this.version = version; 149 } 150 151 public void setSystemWide(Boolean systemWide) { 152 this.systemWide = systemWide; 153 } 154 155 public void setServiceHint(Boolean serviceHint) { 156 this.serviceHint = serviceHint; 157 } 158 159 public void setJRE(String v) { 160 jrePlatform = v; 161 } 162 163 public void setSwingAppWithEmbeddedJavaFX(boolean v) { 164 isSwingApp = v; 165 } 166 167 public void setNeedInstall(boolean b) { 168 needInstall = b; 169 } 170 171 public void setOfflineAllowed(boolean b) { 172 offlineAllowed = b; 173 } 174 175 public void setNeedShortcut(Boolean b) { 176 needShortcut = b; 177 } 178 179 public void setNeedMenu(Boolean b) { 180 needMenu = b; 181 } 182 183 public void setEmbeddedDimensions(String w, String h) { 184 embeddedWidth = w; 185 embeddedHeight = h; 186 } 187 188 public void setFallback(String v) { 189 if (v == null) { 190 return; 191 } 192 193 if ("none".equals(v) || "null".equals(v)) { 194 fallbackApp = null; 195 } else { 196 fallbackApp = v; 197 } 198 } 199 200 public void setJavafx(String v) { 201 fxPlatform = v; 202 } 203 204 public void addJvmArg(String v) { 205 jvmargs.add(v); 206 } 207 208 public void addJvmUserArg(String n, String v) { 209 jvmUserArgs.put(n, v); 210 } 211 212 public void addJvmProperty(String n, String v) { 213 properties.put(n, v); 214 } 215 216 public void setAllPermissions(boolean allPermissions) { 217 this.allPermissions = allPermissions; 218 } 219 220 public void setAppName(String appName) { 221 this.appName = appName; 222 } 223 224 public void setArguments(List<String> args) { 225 this.arguments = args; 226 } 227 228 public void setDescription(String description) { 229 this.description = description; 230 } 231 232 public void setEmbedJNLP(boolean embedJNLP) { 233 this.embedJNLP = embedJNLP; 234 } 235 236 public void setEmbedCertifcates(boolean v) { 237 embedCertificates = v; 238 } 239 240 public void setPlaceholder(String p) { 241 placeholder = p; 242 } 243 244 public void setAppId(String id) { 245 appId = id; 246 } 247 248 public void setHeight(int height) { 249 this.height = height; 250 } 251 252 public void setHtmlParams(List<HtmlParam> htmlParams) { 253 this.htmlParams = htmlParams; 254 } 255 256 public void setOutfile(String outfile) { 257 this.outfile = outfile; 258 } 259 260 public void setParams(List<Param> params) { 261 this.params = params; 262 } 263 264 public void setPreloader(String preloader) { 265 this.preloader = preloader; 266 } 267 268 public void setTitle(String title) { 269 this.title = title; 270 } 271 272 public void setUpdateMode(String updateMode) { 273 this.updateMode = updateMode; 274 } 275 276 public void setVendor(String vendor) { 277 this.vendor = vendor; 278 } 279 280 public void setEmail(String email) { 281 this.email = email; 282 } 283 284 public void setWidth(int width) { 285 this.width = width; 286 } 287 288 public void setExtension(boolean isExtension) { 289 this.isExtension = isExtension; 290 } 291 292 public void setApplicationClass(String applicationClass) { 293 this.applicationClass = applicationClass; 294 } 295 296 public void setIncludeDT(boolean doEmbed) { 297 includeDT = doEmbed; 298 } 299 300 public void setJSCallbacks(List<JSCallback> list) { 301 callbacks = list; 302 } 303 304 public void setCallbacks(List<Callback> list) { 305 List<JSCallback> jslist = new ArrayList<>(list.size()); 306 for (Callback cb: list) { 307 jslist.add(new JSCallback(cb.getName(), cb.getCmd())); 308 } 309 callbacks = jslist; 310 } 311 312 static class Template { 313 File in; 314 File out; 315 316 Template(File in, File out) { 317 this.in = in; 318 this.out = out; 319 } 320 } 321 322 public void addTemplate(File in, File out) { 323 templates.add(new Template(in, out)); 324 } 325 326 //we need to expand as in some cases 327 // (most notably javapackager) 328 //we may get "." as filename and assumption is we include 329 // everything in the given folder 330 // (IOUtils.copyfiles() have recursive behavior) 331 List<File> expandFileset(File root) { 332 List<File> files = new LinkedList<>(); 333 if (com.oracle.tools.packager.IOUtils.isNotSymbolicLink(root)) { 334 if (root.isDirectory()) { 335 File[] children = root.listFiles(); 336 if (children != null) { 337 for (File f : children) { 338 files.addAll(expandFileset(f)); 339 } 340 } 341 } else { 342 files.add(root); 343 } 344 } 345 return files; 346 } 347 348 @Override 349 public void addResource(File baseDir, String path) { 350 File file = new File(baseDir, path); 351 try { 352 //normalize top level dir 353 // to strip things like "." in the path 354 // or it can confuse symlink detection logic 355 file = file.getCanonicalFile(); 356 } catch (IOException ignored) {} 357 for (File f: expandFileset(file)) { 358 resources.add(new DeployResource(baseDir, f)); 359 } 360 } 361 362 @Override 363 public void addResource(File baseDir, File file) { 364 try { 365 //normalize initial file 366 // to strip things like "." in the path 367 // or it can confuse symlink detection logic 368 file = file.getCanonicalFile(); 369 } catch (IOException ignored) {} 370 for (File f: expandFileset(file)) { 371 resources.add(new DeployResource(baseDir, f)); 372 } 373 } 374 375 public void addResource(File baseDir, String path, String type) { 376 resources.add(new DeployResource(baseDir, path, type)); 377 } 378 379 public void addResource(File baseDir, File file, String type) { 380 resources.add(new DeployResource(baseDir, file, type)); 381 } 382 383 public void addResource(File baseDir, File file, String mode, String type, String os, String arch) { 384 resources.add(new DeployResource(baseDir, file, mode, type, os, arch)); 385 } 386 387 @Override 388 public void validate() throws PackagerException { 389 if (outdir == null) { 390 throw new PackagerException("ERR_MissingArgument", "-outdir"); 391 } 392 if (outfile == null) { 393 throw new PackagerException("ERR_MissingArgument", "-outfile"); 394 } 395 if (resources.isEmpty()) { 396 throw new PackagerException("ERR_MissingAppResources"); 397 } 398 if (applicationClass == null) { 399 throw new PackagerException("ERR_MissingArgument", "-appclass"); 400 } 401 } 402 403 //could be icon or splash 404 static class Icon { 405 final static int UNDEFINED = -1; 406 407 String href; 408 String kind; 409 int width = UNDEFINED; 410 int height = UNDEFINED; 411 int depth = UNDEFINED; 412 RunMode mode = RunMode.WEBSTART; 413 414 Icon(String href, String kind, int w, int h, int d, RunMode m) { 415 mode = m; 416 this.href = href; 417 this.kind = kind; 418 if (w > 0) { 419 width = w; 420 } 421 if (h > 0) { 422 height = h; 423 } 424 if (d > 0) { 425 depth = d; 426 } 427 } 428 } 429 430 List<Icon> icons = new LinkedList<>(); 431 432 public void addIcon(String href, String kind, int w, int h, int d, RunMode m) { 433 icons.add(new Icon(href, kind, w, h, d, m)); 434 } 435 436 BundleType bundleType = BundleType.NONE; 437 String targetFormat = null; //means any 438 439 public void setBundleType(BundleType type) { 440 bundleType = type; 441 } 442 443 public BundleType getBundleType() { 444 return bundleType; 445 } 446 447 public void setTargetFormat(String t) { 448 targetFormat = t; 449 } 450 451 public String getTargetFormat() { 452 return targetFormat; 453 } 454 455 private String getArch() { 456 String arch = System.getProperty("os.arch").toLowerCase(); 457 458 if ("x86".equals(arch) || "i386".equals(arch) || "i486".equals(arch) 459 || "i586".equals(arch) || "i686".equals(arch)) { 460 arch = "x86"; 461 } else if ("x86_64".equals(arch) || "amd64".equals("arch")) { 462 arch = "x86_64"; 463 } 464 465 return arch; 466 } 467 468 public void addBundleArgument(String key, String value) { 469 bundlerArguments.put(key, value); 470 } 471 472 public BundleParams getBundleParams() { 473 if (bundleType != BundleType.NONE) { 474 BundleParams bundleParams = new BundleParams(); 475 476 //construct app resources 477 // relative to output folder! 478 Set<File> files = new HashSet<>(); 479 String currentOS = System.getProperty("os.name").toLowerCase(); 480 String currentArch = getArch(); 481 482 for (DeployResource r: resources) { 483 String os = r.getOs(); 484 String arch = r.getArch(); 485 //skip resources for other OS 486 // and nativelib jars (we are including raw libraries) 487 if ((os == null || currentOS.contains(os.toLowerCase())) && 488 (arch == null || currentArch.startsWith(arch.toLowerCase())) 489 && r.getType() != DeployResource.Type.nativelib) { 490 files.add(new File(outdir, r.getRelativePath())); 491 if (r.getType() == DeployResource.Type.license) { 492 bundleParams.addLicenseFile(r.getRelativePath()); 493 } 494 } 495 } 496 com.oracle.tools.packager.RelativeFileSet appResources = new com.oracle.tools.packager.RelativeFileSet(outdir, files); 497 498 bundleParams.setIdentifier(id); 499 bundleParams.setAppResource(appResources); 500 501 if (javaRuntimeWasSet) { 502 bundleParams.setRuntime(javaRuntimeToUse); 503 } 504 bundleParams.setApplicationClass(applicationClass); 505 bundleParams.setName(this.appName); 506 bundleParams.setAppVersion(version); 507 bundleParams.setType(bundleType); 508 bundleParams.setBundleFormat(targetFormat); 509 bundleParams.setVendor(vendor); 510 bundleParams.setEmail(email); 511 bundleParams.setShortcutHint(needShortcut); 512 bundleParams.setMenuHint(needMenu); 513 bundleParams.setSystemWide(systemWide); 514 bundleParams.setServiceHint(serviceHint); 515 bundleParams.setCopyright(copyright); 516 bundleParams.setApplicationCategory(category); 517 bundleParams.setLicenseType(licenseType); 518 bundleParams.setDescription(description); 519 bundleParams.setTitle(title); 520 if (verbose) bundleParams.setVerbose(verbose); 521 522 bundleParams.setJvmProperties(properties); 523 bundleParams.setJvmargs(jvmargs); 524 bundleParams.setJvmUserArgs(jvmUserArgs); 525 526 File appIcon = null; 527 for (Icon ic: icons) { 528 //NB: in theory we should be paying attention to RunMode but 529 // currently everything is marked as webstart internally and runmode 530 // is not publicly documented property 531 if (/* (ic.mode == RunMode.ALL || ic.mode == RunMode.STANDALONE) && */ 532 (ic.kind == null || ic.kind.equals("default"))) { 533 //could be full path or something relative to the output folder 534 appIcon = new File(ic.href); 535 if (!appIcon.exists()) { 536 com.oracle.tools.packager.Log.debug("Icon [" + ic.href + "] is not valid absolute path. " + 537 "Assume it is relative to the output dir."); 538 appIcon = new File(outdir, ic.href); 539 } 540 } 541 } 542 543 bundleParams.setIcon(appIcon); 544 545 // check for collisions 546 TreeSet<String> keys = new TreeSet<>(bundlerArguments.keySet()); 547 keys.retainAll(bundleParams.getBundleParamsAsMap().keySet()); 548 549 if (!keys.isEmpty()) { 550 throw new RuntimeException("Deploy Params and Bundler Arguments overlap in the following values:" + keys.toString()); 551 } 552 553 bundleParams.addAllBundleParams(bundlerArguments); 554 555 return bundleParams; 556 } else { 557 return null; 558 } 559 } 560 }