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