/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.tools.ant;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.oracle.tools.packager.StandardBundlerParam;
import com.sun.javafx.tools.ant.Platform.Jvmarg;
import com.sun.javafx.tools.ant.Platform.Property;
import com.sun.javafx.tools.packager.DeployParams;
import com.oracle.tools.packager.Log;
import com.sun.javafx.tools.packager.PackagerException;
import com.sun.javafx.tools.packager.PackagerLib;
import com.sun.javafx.tools.packager.bundlers.Bundler;
import com.sun.javafx.tools.packager.bundlers.Bundler.Bundle;
import com.sun.javafx.tools.packager.bundlers.Bundler.BundleType;
import java.util.ResourceBundle;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DynamicAttribute;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.DataType;
/**
* Generates package for Web deployment and redistribution of application.
* Package includes of set of jar files, JNLP file and HTML file.
*
* Minimal example:
*
* <fx:deploy width="600" height="400"
* outdir="web-dist" outfile="Fish">
* <info title="Sample application"/>
* <fx:application refid="myapp"/>
* <fx:resources refid="myresources"/>
* </fx:deploy>
*
* Above example will generate HTML/JNLP files into the web-dist directory
* and use "Fish" as prefix for generated files. Details about application and
* its resources are defined elsewhere in the application and resource elements.
*
* Minimal complete example:
*
* <fx:deploy width="600" height="400"
* outdir="web-dist" outfile="Fish">
* <info title="Sample application"/>
* <fx:application name="SampleApp"
* mainClass="testapp.MainApp"
* preloaderClass="testpreloader.Preloader"/>
* <fx:resources>
* <fx:fileset requiredFor="preloader" dir="dist">
* <include name="preloader.jar"/>
* </fx:fileset>
* <fx:fileset dir="dist">
* <include name="helloworld.jar"/>
* </fx:fileset>
* </fx:resources>
* </fx:deploy>
*
* Same as above but here application and resource details are defined in place.
* Note that using references helps with reducing code duplication as fx:jar need
* to be used for double clickable jars.
*
* @ant.task name="deploy" category="javafx"
*/
public class DeployFXTask extends Task implements DynamicAttribute {
private static final ResourceBundle I18N =
ResourceBundle.getBundle(DeployFXTask.class.getName());
private String width = null;
private String height = null;
private String embeddedWidth = null;
private String embeddedHeight = null;
private String outfile = null;
private String outdir = null;
private boolean embedJNLP;
private boolean isExtension = false;
private Boolean signBundle;
//Before FCS default is to include DT files with app
// to ensure tests are using latest and compatible.
//After FCS default is to use shared copy.
private boolean includeDT = false;
private String updateMode="background";
private Info appInfo = null;
private Application app = null;
private Resources resources = null;
private Preferences prefs = null;
private String codebase = null;
//container to embed application into
//could be either string id or js code. If it is string id then it needs to
//be escaped
private String placeholder;
private PackagerLib packager;
private DeployParams deployParams;
private Callbacks callbacks;
boolean offlineAllowed = true;
//default native bundle settings
// use NONE to avoid large disk space and build time overhead
BundleType nativeBundles = BundleType.NONE;
String bundleFormat = null;
boolean versionCheck = true;
private boolean verbose = false;
public void setVerbose(boolean v) {
verbose = v;
}
public void setCodebase(String str) {
codebase = str;
}
public DeployFXTask() {
packager = new PackagerLib();
deployParams = new DeployParams();
}
@Override
public void execute() {
boolean isModular = (app.getModule() != null) && !app.getModule().isEmpty();
deployParams.setOutfile(outfile);
deployParams.setOutdir(new File(outdir));
if (versionCheck) {
if (!com.sun.javafx.tools.ant.VersionCheck.isSameVersion()) {
throw new BuildException(I18N.getString("message.java.version.mismatch"));
}
}
if (!isModular &&
(nativeBundles == BundleType.JNLP ||
nativeBundles == BundleType.ALL ||
nativeBundles == BundleType.NONE)) {
deployParams.setOfflineAllowed(offlineAllowed);
deployParams.setVerbose(verbose);
deployParams.setCodebase(codebase);
deployParams.setSignBundle(signBundle);
if (app.getModule() == null) {
deployParams.setApplicationClass(app.get().mainClass);
}
if (width != null) {
deployParams.setWidth(Integer.valueOf(width));
}
if (height != null) {
deployParams.setHeight(Integer.valueOf(height));
}
if (embeddedWidth != null && embeddedHeight != null) {
deployParams.setEmbeddedDimensions(embeddedWidth, embeddedHeight);
}
deployParams.setEmbedJNLP(embedJNLP);
if (perms != null) {
deployParams.setAllPermissions(perms.getElevated());
}
deployParams.setUpdateMode(updateMode);
deployParams.setExtension(isExtension);
deployParams.setIncludeDT(includeDT);
if (callbacks != null) {
for (Callback cb: callbacks.callbacks) {
deployParams.addCallback(cb.getName(), cb.getCmd());
}
}
setPlatform();
setPreferences();
for (Template t: templateList) {
deployParams.addTemplate(t.infile, t.outfile);
}
}
if (isModular &&
(nativeBundles == BundleType.NATIVE ||
nativeBundles == BundleType.IMAGE ||
nativeBundles == BundleType.INSTALLER ||
nativeBundles == BundleType.ALL)) {
if (app != null) {
if (app.getModule() == null) {
deployParams.setApplicationClass(app.get().mainClass);
}
else {
int index = app.getModule().indexOf("/");
if (index > 0) {
deployParams.setModule(app.getModule());
}
else {
deployParams.setModule(app.getModule() + "/" + app.get().mainClass);
}
}
deployParams.setPreloader(app.get().preloaderClass);
deployParams.setAppId(app.get().id);
deployParams.setAppName(app.get().name);
deployParams.setParams(app.get().parameters);
deployParams.setArguments(app.get().getArguments());
deployParams.setHtmlParams(app.get().htmlParameters);
deployParams.setFallback(app.get().fallbackApp);
deployParams.setSwingAppWithEmbeddedJavaFX(app.get().embeddedIntoSwing);
deployParams.setVersion(app.get().version);
deployParams.setId(app.get().id);
deployParams.setServiceHint(app.get().daemon);
setRuntime();
}
if (appInfo != null) {
deployParams.setTitle(appInfo.title);
deployParams.setVendor(appInfo.vendor);
deployParams.setDescription(appInfo.appDescription);
deployParams.setCategory(appInfo.category);
deployParams.setLicenseType(appInfo.licenseType);
deployParams.setCopyright(appInfo.copyright);
deployParams.setEmail(appInfo.email);
for (Info.Icon i: appInfo.icons) {
if (i instanceof Info.Splash) {
deployParams.addIcon(i.href, i.kind, i.width, i.height, i.depth,
((Info.Splash) i).mode);
} else {
deployParams.addIcon(i.href, i.kind, i.width, i.height, i.depth,
DeployParams.RunMode.WEBSTART);
}
}
deployParams.addBundleArgument(StandardBundlerParam.FILE_ASSOCIATIONS.getID(),
appInfo.fileAssociations.stream()
.map(FileAssociation::createLauncherMap)
.collect(Collectors.toList()));
}
setPlatform();
setPreferences();
}
if (!isModular &&
(nativeBundles == BundleType.NATIVE ||
nativeBundles == BundleType.IMAGE ||
nativeBundles == BundleType.INSTALLER ||
nativeBundles == BundleType.ALL)) {
if (app != null) {
deployParams.setApplicationClass(app.get().mainClass);
deployParams.setPreloader(app.get().preloaderClass);
deployParams.setAppId(app.get().id);
deployParams.setAppName(app.get().name);
deployParams.setParams(app.get().parameters);
deployParams.setArguments(app.get().getArguments());
deployParams.setHtmlParams(app.get().htmlParameters);
deployParams.setFallback(app.get().fallbackApp);
deployParams.setSwingAppWithEmbeddedJavaFX(app.get().embeddedIntoSwing);
deployParams.setVersion(app.get().version);
deployParams.setId(app.get().id);
deployParams.setServiceHint(app.get().daemon);
setRuntime();
}
if (appInfo != null) {
deployParams.setTitle(appInfo.title);
deployParams.setVendor(appInfo.vendor);
deployParams.setDescription(appInfo.appDescription);
deployParams.setCategory(appInfo.category);
deployParams.setLicenseType(appInfo.licenseType);
deployParams.setCopyright(appInfo.copyright);
deployParams.setEmail(appInfo.email);
for (Info.Icon i: appInfo.icons) {
if (i instanceof Info.Splash) {
deployParams.addIcon(i.href, i.kind, i.width, i.height, i.depth,
((Info.Splash) i).mode);
} else {
deployParams.addIcon(i.href, i.kind, i.width, i.height, i.depth,
DeployParams.RunMode.WEBSTART);
}
}
deployParams.addBundleArgument(StandardBundlerParam.FILE_ASSOCIATIONS.getID(),
appInfo.fileAssociations.stream()
.map(FileAssociation::createLauncherMap)
.collect(Collectors.toList()));
}
setPlatform();
setPreferences();
}
for (BundleArgument ba : bundleArgumentList) {
deployParams.addBundleArgument(ba.arg, ba.value);
}
deployParams.setPlaceholder(placeholder);
if (resources != null) {
for (FileSet fs: resources.getResources()) {
Utils.addResources(deployParams, fs);
}
}
List