8198472: Add support for creating bundles from JNLP files
Submitten-by: almatvee
Reviewed-by: herrick, kcr, prr, asemenyuk
--- a/make/CompileDemos.gmk Fri Oct 12 18:58:40 2018 -0400
+++ b/make/CompileDemos.gmk Fri Oct 12 19:00:51 2018 -0400
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, 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
@@ -219,6 +219,11 @@
MAIN_CLASS := transparentruler.Ruler, \
))
+$(eval $(call SetupBuildDemo, JNLPConverter, \
+ DEMO_SUBDIR := jpackager, \
+ MAIN_CLASS := jnlp.converter.Main, \
+))
+
################################################################################
# Copy html and README files.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/README.txt Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,23 @@
+About JNLPConverter
+===================
+
+JNLPConverter is a standalone tool which uses jpackager to create bundles from
+Java Web Start(TM) Applications and helps to migrate from JNLP to jpackager.
+JNLPConverter will locate and use the jpackager tool from the same JDK as used
+to run JNLPConverter. JNLPConverter supports HTTP/HTTPS and FILE protocol.
+
+Running JNLPConverter
+=====================
+
+To run the JNLPConverter:
+
+ java -jar JNLPConverter.jar <mode> <options>
+
+To get help on JNLPConverter options:
+
+ java -jar JNLPConverter.jar --help
+
+These instructions assume that this installation's version of the java command
+is in your path. If it isn't, then you should either specify the complete path
+to the java command or update your PATH environment variable as described
+in the installation instructions for the Java(TM) SE Development Kit.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/HTTPHelper.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import jnlp.converter.parser.GeneralUtil;
+
+public class HTTPHelper {
+
+ public static final int BUFFER_SIZE = 4096;
+
+ public static String downloadFile(String url, String destFolder, String destFileName) throws MalformedURLException, IOException {
+ HttpURLConnection connection = null;
+ String destFile = null;
+
+ try {
+ if (url.contains(" ")) {
+ url = url.replace(" ", "%20");
+ }
+ if (url.contains("\\")) {
+ url = url.replace("\\", "/");
+ }
+
+ URL resource = new URL(url);
+ connection = (HttpURLConnection) resource.openConnection();
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ destFile = destFolder + File.separator + destFileName;
+ Log.verbose("Downloading " + url + " to " + destFile);
+
+ try (InputStream inputStream = connection.getInputStream();
+ OutputStream outputStream = new FileOutputStream(destFile)) {
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ int length;
+ do {
+ length = inputStream.read(buffer);
+ if (length > 0) {
+ outputStream.write(buffer, 0, length);
+ }
+ } while (length > 0);
+ }
+ } else {
+ HTTPHelperException e = new HTTPHelperException("Error: Cannot download " + url + ". Server response code: " + responseCode);
+ e.setResponseCode(responseCode);
+ throw e;
+ }
+ } catch (IOException e) {
+ if (e instanceof HTTPHelperException) {
+ throw e;
+ } else {
+ throw new HTTPHelperException("Error: Cannot download " + url + ". " + e.getClass().getSimpleName() + ": " + e.getMessage());
+ }
+ } finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+
+ return destFile;
+ }
+
+ public static String copyFile(String url, String destFolder, String destFileName) throws Exception {
+ if (url.contains(" ")) {
+ url = url.replace(" ", "%20");
+ }
+
+ URI sourceURI = new URI(url);
+
+ String sourceFile = sourceURI.getPath();
+ File file = new File(sourceFile);
+ if (!file.exists()) {
+ throw new FileNotFoundException("Error: " + sourceFile + " does not exist.");
+ }
+
+ String destFile = destFolder + File.separator + destFileName;
+ file = new File(destFile);
+ if (file.exists()) {
+ file.delete();
+ }
+
+ Path sourcePath = Paths.get(sourceURI);
+ Path destPath = Paths.get(destFile);
+ Log.verbose("Copying " + url + " to " + destFile);
+ Files.copy(sourcePath, destPath);
+
+ return destFile;
+ }
+
+ public static boolean isHTTPUrl(String url) {
+ return (url.startsWith("http://") || url.startsWith("https://"));
+ }
+
+ public static byte[] getJNLPBits(String versionedJNLP, String jnlp) throws Exception {
+ String jnlpFilePath = null;
+ byte[] bits = null;
+
+ if (isHTTPUrl(jnlp)) {
+ try {
+ jnlpFilePath = downloadFile(versionedJNLP, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
+ } catch (HTTPHelperException ex) {
+ if (ex.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND &&
+ !versionedJNLP.equals(jnlp)) {
+ Log.warning("Downloading versioned JNLP from " + versionedJNLP + " failed.");
+ Log.warning(ex.getMessage());
+ Log.warning("Downloading " + jnlp + " instead.");
+ jnlpFilePath = downloadFile(jnlp, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
+ } else {
+ throw ex;
+ }
+ }
+ JNLPConverter.markFileToDelete(jnlpFilePath);
+ } else {
+ try {
+ jnlpFilePath = copyFile(versionedJNLP, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
+ } catch (FileNotFoundException ex) {
+ System.out.println("Error copying versioned JNLP from " + versionedJNLP);
+ System.out.println(ex.getMessage());
+ System.out.println("Copying " + jnlp + " instead.");
+ jnlpFilePath = HTTPHelper.copyFile(jnlp, JNLPConverter.getJnlpDownloadFolderStatic(), getFileNameFromURL(jnlp));
+ }
+ JNLPConverter.markFileToDelete(jnlpFilePath);
+ }
+
+ File jnlpFile = new File(jnlpFilePath);
+ if (jnlpFile.exists()) {
+ bits = GeneralUtil.readBytes(new FileInputStream(jnlpFile), jnlpFile.length());
+ }
+
+ return bits;
+ }
+
+ public static String getFileNameFromURL(String url) throws IOException {
+ int index;
+ int index1 = url.lastIndexOf('/');
+ int index2 = url.lastIndexOf('\\');
+
+ if (index1 >= index2) {
+ index = index1;
+ } else {
+ index = index2;
+ }
+
+ if (index != -1) {
+ String name = url.substring(index + 1, url.length());
+ name = name.replace("%20", " ");
+ if (name.endsWith(".jnlp") || name.endsWith(".jar")) { // JNLP or JAR
+ return name;
+ } else if (name.endsWith(".ico")) { // Icons
+ return name;
+ } else {
+ throw new IOException("Error: Unsupported file extension for " + url);
+ }
+ } else {
+ throw new IOException("Error: URL (" + url + ") should end with file name.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/HTTPHelperException.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter;
+
+import java.io.IOException;
+
+public class HTTPHelperException extends IOException {
+ private int responseCode = -1;
+
+ public HTTPHelperException(String msg) {
+ super(msg);
+ }
+
+ public void setResponseCode(int code) {
+ responseCode = code;
+ }
+
+ public int getResponseCode() {
+ return responseCode;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/JNLPConverter.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,865 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import jnlp.converter.parser.JNLPDesc;
+import jnlp.converter.parser.JNLPDesc.AssociationDesc;
+import jnlp.converter.parser.JNLPDesc.IconDesc;
+import jnlp.converter.parser.ResourcesDesc.JARDesc;
+import jnlp.converter.parser.XMLFormat;
+
+public class JNLPConverter {
+
+ private final Options options;
+ private JNLPDesc jnlpd = null;
+ private final List<String> launchArgs = new ArrayList<>();
+
+ private String downloadFolder = null;
+ private String jnlpDownloadFolder = null;
+ private static String jnlpDownloadFolderStatic;
+ private String jarDownloadFolder = null;
+ private String iconDownloadFolder = null;
+ private String propDownloadFolder = null;
+
+ private static String jpackagerPath = null;
+
+ private static boolean markFileToDelete = false;
+
+ private static final String FA_EXTENSIONS = "extension";
+ private static final String FA_CONTENT_TYPE = "mime-type";
+ private static final String FA_DESCRIPTION = "description";
+ private static final String FA_ICON = "icon";
+
+ public JNLPConverter(Options options) {
+ this.options = options;
+ jnlpDownloadFolderStatic = getJnlpDownloadFolder();
+ markFileToDelete = (options.keep() == null);
+ }
+
+ public String [] getLaunchArgs() {
+ return launchArgs.toArray(new String[0]);
+ }
+
+ public void convert() {
+ try {
+ loadJNLPDesc();
+ downloadResources();
+ validate();
+ buildLaunchArgs();
+ saveLaunchArgs();
+ runJPackager();
+ } catch (Exception ex) {
+ Log.error(ex.getLocalizedMessage());
+ }
+ }
+
+ private JNLPDesc getJNLPD(String jnlp) throws Exception {
+ URL codebase = getCodeBase(jnlp);
+ byte[] bits = HTTPHelper.getJNLPBits(jnlp, jnlp);
+ return XMLFormat.parse(bits, codebase, jnlp);
+ }
+
+ private void loadJNLPDesc() throws Exception {
+ String jnlp = options.getJNLP();
+ jnlpd = getJNLPD(jnlp);
+
+ // Check for required options in case of FX
+ if (jnlpd.isFXApp()) {
+ if (!options.isRuntimeImageSet()) {
+ throw new Exception("This is a JavaFX Web-Start application which requires a runtime image capable of running JavaFX applications, which can be specified by the jpackager option --runtime-image (using --jpackager-options).");
+ }
+ }
+
+ // Check href. It can be same as URL we provided or new one
+ // if JNLP has different href or codebase. We assume that
+ // XMLFormat.parse() will handle any errors in href and codebase
+ // correctly.
+ String href = jnlpd.getHref();
+ if (href != null && !href.equalsIgnoreCase(jnlp)) {
+ if (href.startsWith("file:")) {
+ URI hrefURI = new URI(href);
+ URI jnlpURI = new URI(jnlp);
+
+ String hrefPath = hrefURI.getPath();
+ String jnlpPath = jnlpURI.getPath();
+
+ if (!hrefPath.equalsIgnoreCase(jnlpPath)) {
+ jnlp = href;
+ jnlpd = getJNLPD(jnlp);
+ }
+ } else {
+ jnlp = href;
+ jnlpd = getJNLPD(jnlp);
+ }
+ }
+
+ if (jnlpd.getName() == null) {
+ jnlpd.setName(getNameFromURL(jnlp));
+ }
+ }
+
+ private static String getNameFromURL(String url) throws IOException {
+ int index;
+ int index1 = url.lastIndexOf('/');
+ int index2 = url.lastIndexOf('\\');
+
+ if (index1 >= index2) {
+ index = index1;
+ } else {
+ index = index2;
+ }
+
+ if (index != -1) {
+ String name = url.substring(index + 1, url.length());
+ if (name.endsWith(".jnlp")) {
+ return name.substring(0, name.length() - 5);
+ }
+ }
+
+ return null;
+ }
+
+ private URL getCodeBase(String jnlp) throws Exception {
+ int index = jnlp.lastIndexOf('/');
+ if (index != -1) {
+ if (HTTPHelper.isHTTPUrl(jnlp)) {
+ return new URL(jnlp.substring(0, index + 1));
+ } else {
+ String codeBasePath = jnlp.substring(0, index);
+ if (!codeBasePath.endsWith("/")) {
+ codeBasePath += "/";
+ }
+ return new URI(codeBasePath).toURL();
+ }
+ }
+
+ return null;
+ }
+
+ public static void markFileToDelete(String file) {
+ if (file == null || file.isEmpty()) {
+ return;
+ }
+
+ if (markFileToDelete) {
+ try {
+ File f = new File(file);
+ f.deleteOnExit();
+ } catch (Exception e) {
+ // Print exception, but do not fail conversion.
+ Log.warning(e.getLocalizedMessage());
+ }
+ }
+ }
+
+ public static void deleteFile(String file) {
+ try {
+ File f = new File(file);
+ f.delete();
+ } catch (Exception e) {
+ Log.warning(e.getLocalizedMessage());
+ }
+ }
+
+ private void downloadResources() throws Exception {
+ List<JARDesc> jars = jnlpd.getResources();
+ for (JARDesc jar : jars) {
+ if (jar.getVersion() != null) {
+ if (!jnlpd.isVersionEnabled()) {
+ throw new Exception("Error: Version based download protocol is not supported without -Djnlp.versionEnabled=true.");
+ }
+ }
+
+ String destFile = null;
+ if (HTTPHelper.isHTTPUrl(jar.getLocation().toString())) {
+ if (jar.getVersion() != null) {
+ try {
+ destFile = HTTPHelper.downloadFile(jar.getVersionLocation().toString(), getJarDownloadFolder(), HTTPHelper.getFileNameFromURL(jar.getLocation().toString()));
+ } catch (HTTPHelperException ex) {
+ if (ex.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
+ System.out.println("Error downloading versioned JAR from " + jar.getVersionLocation());
+ System.out.println(ex.getMessage());
+ System.out.println("Downloading " + jar.getLocation() + " instead.");
+ destFile = HTTPHelper.downloadFile(jar.getLocation().toString(), getJarDownloadFolder(), HTTPHelper.getFileNameFromURL(jar.getLocation().toString()));
+ } else {
+ throw ex;
+ }
+ }
+ } else {
+ destFile = HTTPHelper.downloadFile(jar.getLocation().toString(), getJarDownloadFolder(), HTTPHelper.getFileNameFromURL(jar.getLocation().toString()));
+ }
+ markFileToDelete(destFile);
+ } else {
+ if (jar.getVersion() != null) {
+ try {
+ destFile = HTTPHelper.copyFile(jar.getVersionLocation().toString(), getJarDownloadFolder(), HTTPHelper.getFileNameFromURL(jar.getLocation().toString()));
+ } catch (FileNotFoundException ex) {
+ System.out.println("Error copying versioned JAR from " + jar.getVersionLocation());
+ System.out.println(ex.getMessage());
+ System.out.println("Copying " + jar.getLocation() + " instead.");
+ destFile = HTTPHelper.copyFile(jar.getLocation().toString(), getJarDownloadFolder(), HTTPHelper.getFileNameFromURL(jar.getLocation().toString()));
+ }
+ } else {
+ destFile = HTTPHelper.copyFile(jar.getLocation().toString(), getJarDownloadFolder(), HTTPHelper.getFileNameFromURL(jar.getLocation().toString()));
+ }
+ markFileToDelete(destFile);
+ }
+
+ if (jar.isNativeLib()) {
+ unpackNativeLib(destFile);
+ deleteFile(destFile);
+ } else {
+ jnlpd.addFile(jar.getName());
+ }
+ }
+
+ IconDesc icon = jnlpd.getIcon();
+ if (icon != null) {
+ String destFile;
+
+ if (HTTPHelper.isHTTPUrl(icon.getLocation())) {
+ destFile = HTTPHelper.downloadFile(icon.getLocation(), getIconDownloadFolder(), HTTPHelper.getFileNameFromURL(icon.getLocation()));
+ } else {
+ destFile = HTTPHelper.copyFile(icon.getLocation(), getIconDownloadFolder(), HTTPHelper.getFileNameFromURL(icon.getLocation()));
+ }
+
+ markFileToDelete(destFile);
+ icon.setLocalLocation(destFile);
+ }
+
+ AssociationDesc [] associations = jnlpd.getAssociations();
+ if (associations != null) {
+ for (AssociationDesc association : associations) {
+ if (association.getIconUrl() != null) {
+ String destFile;
+ if (HTTPHelper.isHTTPUrl(association.getIconUrl())) {
+ destFile = HTTPHelper.downloadFile(association.getIconUrl(), getIconDownloadFolder(), HTTPHelper.getFileNameFromURL(association.getIconUrl()));
+ } else {
+ destFile = HTTPHelper.copyFile(association.getIconUrl(), getIconDownloadFolder(), HTTPHelper.getFileNameFromURL(association.getIconUrl()));
+ }
+
+ markFileToDelete(destFile);
+ association.setIconLocalLocation(destFile);
+ }
+ }
+ }
+ }
+
+ public void unpackNativeLib(String file) throws IOException {
+ try (JarFile jarFile = new JarFile(file)) {
+ Enumeration entries = jarFile.entries();
+
+ while (entries.hasMoreElements()) {
+ JarEntry entry = (JarEntry) entries.nextElement();
+
+ // Skip directories
+ if (entry.isDirectory()) {
+ continue;
+ }
+
+ String entryName = entry.getName();
+ // Skip anything in sub-directories
+ if (entryName.contains("\\") || entryName.contains("/")) {
+ continue;
+ }
+
+ // Skip anything not ending with .dll, .dylib or .so
+ if (!entryName.endsWith(".dll") && !entryName.endsWith(".dylib") && !entryName.endsWith(".so")) {
+ continue;
+ }
+
+ File destFile = new File(getJarDownloadFolder(), entryName);
+ if (destFile.exists()) {
+ Log.warning(destFile.getAbsolutePath() + " already exist and will not be overwriten by native library from " + file + ".");
+ continue;
+ }
+
+ InputStream inputStream = jarFile.getInputStream(entry);
+ FileOutputStream outputStream = new FileOutputStream(destFile);
+
+ byte[] buffer = new byte[HTTPHelper.BUFFER_SIZE];
+ int length;
+ do {
+ length = inputStream.read(buffer);
+ if (length > 0) {
+ outputStream.write(buffer, 0, length);
+ }
+ } while (length > 0);
+
+ jnlpd.addFile(entryName);
+ }
+ }
+ }
+
+ private void validate() {
+ if (jnlpd.getMainJar() == null) {
+ Log.error("Cannot find main jar");
+ }
+
+ if (jnlpd.getMainClass() == null) {
+ Log.error("Cannot find main class");
+ }
+ }
+
+ private void addLaunchArg(String arg, List<String> launchArgs) {
+ if (arg != null && !arg.isEmpty()) {
+ if (!options.isOptionPresent(arg)){
+ launchArgs.add(arg);
+ } else {
+ Log.info(arg + " generated by JNLPConverter is dropped, since it is overwriten via --jpackager-options");
+ }
+ }
+ }
+
+ private void addLaunchArg(String arg, String value, List<String> launchArgs) {
+ if (arg != null && !arg.isEmpty() && value != null && !value.isEmpty()) {
+ if (!options.isOptionPresent(arg)){
+ launchArgs.add(arg);
+ launchArgs.add(value);
+ } else {
+ Log.info(arg + "=" + value +" generated by JNLPConverter is dropped, since it is overwriten via --jpackager-options");
+ }
+ }
+ }
+
+ private void displayLaunchArgs() {
+ if (Log.isVerbose()) {
+ System.out.println();
+ System.out.println("jpackager launch arguments (each argument starts on new line):");
+ launchArgs.forEach((arg) -> {
+ System.out.println(arg);
+ });
+ }
+ }
+
+ private static int fileAssociationsCount = 0;
+ private String getFileAssociationsFile() {
+ String file = getPropDownloadFolder();
+ file += File.separator;
+ file += "fileAssociation";
+ file += String.valueOf(fileAssociationsCount);
+ file += ".properties";
+
+ fileAssociationsCount++;
+
+ return file;
+ }
+
+ private void buildLaunchArgs() {
+ if (options.createImage()) {
+ addLaunchArg("create-image", launchArgs);
+ } else if (options.createInstaller()) {
+ if (options.getInstallerType() == null) {
+ addLaunchArg("create-installer", launchArgs);
+ } else {
+ addLaunchArg("create-installer", options.getInstallerType(), launchArgs);
+ }
+ }
+
+ // Set verbose for jpackager if it is set for us.
+ if (options.verbose()) {
+ addLaunchArg("--verbose", launchArgs);
+ }
+
+ addLaunchArg("--input", getJarDownloadFolder(), launchArgs);
+ addLaunchArg("--output", options.getOutput(), launchArgs);
+ addLaunchArg("--name", jnlpd.getName(), launchArgs);
+ addLaunchArg("--version", jnlpd.getVersion(), launchArgs);
+ addLaunchArg("--vendor", jnlpd.getVendor(), launchArgs);
+ addLaunchArg("--description", jnlpd.getDescription(), launchArgs);
+ addLaunchArg("--icon", jnlpd.getIconLocation(), launchArgs);
+ addLaunchArg("--main-jar", jnlpd.getMainJar(), launchArgs);
+ addLaunchArg("--class", jnlpd.getMainClass(), launchArgs);
+
+ addFiles(launchArgs);
+ addArguments(launchArgs);
+ addJVMArgs(launchArgs);
+
+ if (jnlpd.isDesktopHint()) {
+ if (Platform.isWindows()) {
+ addLaunchArg("--win-shortcut", launchArgs);
+ } else {
+ Log.warning("Ignoring shortcut hint, since it is not supported on current platform.");
+ }
+ }
+
+ if (jnlpd.isMenuHint()) {
+ if (Platform.isWindows()) {
+ addLaunchArg("--win-menu", launchArgs);
+ addLaunchArg("--win-menu-group", jnlpd.getSubMenu(), launchArgs);
+ } else {
+ Log.warning("Ignoring menu hint, since it is not supported on current platform.");
+ }
+ }
+
+ AssociationDesc [] associations = jnlpd.getAssociations();
+ if (associations != null) {
+ for (AssociationDesc association : associations) {
+ String file = getFileAssociationsFile();
+ markFileToDelete(file);
+
+ try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)))) {
+ if (association.getExtensions() != null && association.getMimeType() != null) {
+ out.println(FA_EXTENSIONS + "=" + quote(association.getExtensions()));
+ out.println(FA_CONTENT_TYPE + "=" + quote(association.getMimeType()));
+
+ if (association.getMimeDescription() != null) {
+ out.println(FA_DESCRIPTION + "=" + association.getMimeDescription());
+ }
+
+ if (association.getIconLocalLocation() != null) {
+ out.println(FA_ICON + "=" + quote(association.getIconLocalLocation()));
+ }
+
+ addLaunchArg("--file-associations", file, launchArgs);
+ }
+ } catch (Exception ex) {
+ Log.warning(ex.toString());
+ if (association.getExtensions() != null) {
+ Log.warning("File assoication for " + association.getExtensions() + " will be ignored due to exception above.");
+ }
+ }
+ }
+ }
+
+ // Add options from --jpackager-options
+ List<String> jpackagerOptions = options.getJPackagerOptions();
+ jpackagerOptions.forEach((option) -> {
+ launchArgs.add(option);
+ });
+
+ displayLaunchArgs();
+ }
+
+ private String getCommandFileName() {
+ Platform platform = Platform.getPlatform();
+ switch (platform) {
+ case WINDOWS:
+ return "run_jpackager.bat";
+ case LINUX:
+ return "run_jpackager.sh";
+ case MAC:
+ return "run_jpackager.sh";
+ default:
+ Log.error("Cannot determine platform type.");
+ return "";
+ }
+ }
+
+ private void saveLaunchArgs() {
+ if (options.keep() != null) {
+ File keepFolder = new File(options.keep());
+ String cmdFile = keepFolder.getAbsolutePath() + File.separator + getCommandFileName();
+ try (PrintWriter out = new PrintWriter(cmdFile)) {
+ out.print(getJPackagerPath());
+ launchArgs.forEach((arg) -> {
+ out.print(" ");
+
+ if (arg.contains(" ")) {
+ int len = arg.length();
+ if (len >= 1) {
+ if (arg.charAt(0) != '"' && arg.charAt(len - 1) != '"') {
+ out.print("\"" + arg + "\"");
+ } else {
+ if (Platform.isWindows()) {
+ out.print(arg);
+ } else {
+ arg = escapeQuote(arg);
+ out.print("\"" + arg + "\"");
+ }
+ }
+ }
+ } else {
+ out.print(arg);
+ }
+ });
+ } catch (FileNotFoundException ex) {
+ Log.error("Cannot save file with command line: " + ex.getLocalizedMessage());
+ }
+ }
+ }
+
+ private void runJPackager() {
+ List<String> command = new ArrayList<>();
+ command.add(getJPackagerPath());
+ command.addAll(launchArgs);
+
+ ProcessBuilder builder = new ProcessBuilder();
+ builder.inheritIO();
+ builder.command(command);
+
+ try {
+ Process process = builder.start();
+ int exitCode = process.waitFor();
+ if (exitCode != 0) {
+ Log.warning("jpackager retrun non zero code: " + exitCode);
+ }
+ } catch (IOException | InterruptedException ex) {
+ Log.error(ex.getMessage());
+ }
+ }
+
+ private void addFileList(String arg, List<String> filesToAdd, List<String> launchArgs) {
+ if (filesToAdd.isEmpty()) {
+ return;
+ }
+
+ String filesArg = "";
+ for (int i = 0; i < filesToAdd.size(); i++) {
+ filesArg += quote(filesToAdd.get(i));
+ if ((i + 1) != filesToAdd.size()) {
+ filesArg += File.pathSeparator;
+ }
+ }
+
+ launchArgs.add(arg);
+ launchArgs.add(filesArg);
+ }
+
+ private void addFiles(List<String> launchArgs) {
+ addFileList("--files", jnlpd.getFiles(), launchArgs);
+ }
+
+ private void addArguments(List<String> launchArgs) {
+ List<String> arguments = jnlpd.getArguments();
+ if (arguments.isEmpty()) {
+ return;
+ }
+
+ String argsStr = "";
+ for (int i = 0; i < arguments.size(); i++) {
+ String arg = arguments.get(i);
+ argsStr += quote(arg);
+ if ((i + 1) != arguments.size()) {
+ argsStr += " ";
+ }
+ }
+
+ launchArgs.add("--arguments");
+ if (Platform.isWindows()) {
+ if (argsStr.contains(" ")) {
+ if (argsStr.contains("\"")) {
+ argsStr = escapeQuote(argsStr);
+ }
+ argsStr = "\"" + argsStr + "\"";
+ }
+ }
+ launchArgs.add(argsStr);
+ }
+
+ private void addJVMArgs(List<String> launchArgs) {
+ List<String> jvmArgs = jnlpd.getVMArgs();
+ if (jvmArgs.isEmpty()) {
+ return;
+ }
+
+ String jvmArgsStr = "";
+ for (int i = 0; i < jvmArgs.size(); i++) {
+ String arg = jvmArgs.get(i);
+ jvmArgsStr += quote(arg);
+ if ((i + 1) != jvmArgs.size()) {
+ jvmArgsStr += " ";
+ }
+ }
+
+ launchArgs.add("--jvm-args");
+ if (Platform.isWindows()) {
+ if (jvmArgsStr.contains(" ")) {
+ if (jvmArgsStr.contains("\"")) {
+ jvmArgsStr = escapeQuote(jvmArgsStr);
+ }
+ jvmArgsStr = "\"" + jvmArgsStr + "\"";
+ }
+ }
+ launchArgs.add(jvmArgsStr);
+ }
+
+ private String quote(String in) {
+ if (in == null) {
+ return null;
+ }
+
+ if (in.isEmpty()) {
+ return "";
+ }
+
+ if (!in.contains("=")) {
+ // Not a property
+ if (in.contains(" ")) {
+ in = escapeQuote(in);
+ return "\"" + in + "\"";
+ }
+ return in;
+ }
+
+ if (!in.contains(" ")) {
+ return in; // No need to quote
+ }
+
+ int paramIndex = in.indexOf("=");
+ if (paramIndex <= 0) {
+ return in; // Something wrong, just skip quoting
+ }
+
+ String param = in.substring(0, paramIndex);
+ String value = in.substring(paramIndex + 1);
+
+ if (value.length() == 0) {
+ return in; // No need to quote
+ }
+
+ value = escapeQuote(value);
+
+ return param + "=" + "\"" + value + "\"";
+ }
+
+ private String escapeQuote(String in) {
+ if (in == null) {
+ return null;
+ }
+
+ if (in.isEmpty()) {
+ return "";
+ }
+
+ if (in.contains("\"")) {
+ // Use code points to preserve non-ASCII chars
+ StringBuilder sb = new StringBuilder();
+ int codeLen = in.codePointCount(0, in.length());
+ for (int i = 0; i < codeLen; i++) {
+ int code = in.codePointAt(i);
+ // Note: No need to escape '\' on Linux or OS X.
+ // jpackager expects us to pass arguments and properties with quotes and spaces as a map
+ // with quotes being escaped with additional \ for internal quotes.
+ // So if we want two properties below:
+ // -Djnlp.Prop1=Some "Value" 1
+ // -Djnlp.Prop2=Some Value 2
+ // jpackager will need:
+ // "-Djnlp.Prop1=\"Some \\"Value\\" 1\" -Djnlp.Prop2=\"Some Value 2\""
+ // but since we using ProcessBuilder to run jpackager we will need to escape
+ // our escape symbols as well, so we will need to pass string below to ProcessBuilder:
+ // "-Djnlp.Prop1=\\\"Some \\\\\\\"Value\\\\\\\" 1\\\" -Djnlp.Prop2=\\\"Some Value 2\\\""
+ switch (code) {
+ case '"':
+ // " -> \" -> \\\"
+ if (i == 0 || in.codePointAt(i - 1) != '\\') {
+ if (Platform.isWindows()) {
+ sb.appendCodePoint('\\');
+ sb.appendCodePoint('\\');
+ }
+ sb.appendCodePoint('\\');
+ sb.appendCodePoint(code);
+ }
+ break;
+ case '\\':
+ // We need to escape already escaped symbols as well
+ if ((i + 1) < codeLen) {
+ int nextCode = in.codePointAt(i + 1);
+ if (nextCode == '"') {
+ // \" -> \\\"
+ sb.appendCodePoint('\\');
+ sb.appendCodePoint('\\');
+ sb.appendCodePoint('\\');
+ sb.appendCodePoint(nextCode);
+ } else {
+ sb.appendCodePoint('\\');
+ sb.appendCodePoint(code);
+ }
+ } else {
+ if (Platform.isWindows()) {
+ sb.appendCodePoint('\\');
+ }
+ sb.appendCodePoint(code);
+ }
+ break;
+ default:
+ sb.appendCodePoint(code);
+ break;
+ }
+ }
+ return sb.toString();
+ }
+
+ return in;
+ }
+
+ public synchronized String getDownloadFolder() {
+ if (downloadFolder == null) {
+ try {
+ File file;
+ if (options.keep() == null) {
+ Path path = Files.createTempDirectory("JNLPConverter");
+ file = path.toFile();
+ file.deleteOnExit();
+ } else {
+ file = new File(options.keep());
+ if (!file.exists()) {
+ file.mkdir();
+ }
+ }
+
+ downloadFolder = file.getAbsolutePath();
+ } catch (IOException e) {
+ Log.error(e.getLocalizedMessage());
+ }
+ }
+
+ return downloadFolder;
+ }
+
+ public final synchronized String getJnlpDownloadFolder() {
+ if (jnlpDownloadFolder == null) {
+ File file = new File(getDownloadFolder() + File.separator + "jnlp");
+ file.mkdir();
+ markFileToDelete(getDownloadFolder() + File.separator + "jnlp");
+ jnlpDownloadFolder = file.getAbsolutePath();
+ }
+
+ return jnlpDownloadFolder;
+ }
+
+ public static String getJnlpDownloadFolderStatic() {
+ return jnlpDownloadFolderStatic;
+ }
+
+ public synchronized String getJarDownloadFolder() {
+ if (jarDownloadFolder == null) {
+ File file = new File(getDownloadFolder() + File.separator + "jar");
+ file.mkdir();
+ markFileToDelete(getDownloadFolder() + File.separator + "jar");
+ jarDownloadFolder = file.getAbsolutePath();
+ }
+
+ return jarDownloadFolder;
+ }
+
+ public synchronized String getIconDownloadFolder() {
+ if (iconDownloadFolder == null) {
+ File file = new File(getDownloadFolder() + File.separator + "icon");
+ file.mkdir();
+ markFileToDelete(getDownloadFolder() + File.separator + "icon");
+ iconDownloadFolder = file.getAbsolutePath();
+ }
+
+ return iconDownloadFolder;
+ }
+
+ public synchronized String getPropDownloadFolder() {
+ if (propDownloadFolder == null) {
+ File file = new File(getDownloadFolder() + File.separator + "prop");
+ file.mkdir();
+ markFileToDelete(getDownloadFolder() + File.separator + "prop");
+ propDownloadFolder = file.getAbsolutePath();
+ }
+
+ return propDownloadFolder;
+ }
+
+ public synchronized static String getJPackagerPath() {
+ if (jpackagerPath == null) {
+ jpackagerPath = System.getProperty("java.home");
+ jpackagerPath += File.separator;
+ jpackagerPath += "bin";
+ jpackagerPath += File.separator;
+
+ Platform platform = Platform.getPlatform();
+ switch (platform) {
+ case WINDOWS:
+ jpackagerPath += "jpackager.exe";
+ break;
+ case LINUX:
+ jpackagerPath += "jpackager";
+ break;
+ case MAC:
+ jpackagerPath += "jpackager";
+ break;
+ default:
+ Log.error("Cannot determine platform type.");
+ break;
+ }
+
+ Log.verbose("jpackager: " + jpackagerPath);
+ }
+
+ return jpackagerPath;
+ }
+
+ public static String getIconFormat(String icon) {
+ // GIF, JPEG, ICO, or PNG
+ if (icon.toLowerCase().endsWith(".gif")) {
+ return "GIF";
+ } else if (icon.toLowerCase().endsWith(".jpg")) {
+ return "JPEG";
+ } else if (icon.toLowerCase().endsWith(".ico")) {
+ return "ICO";
+ } else if (icon.toLowerCase().endsWith(".png")) {
+ return "PNG";
+ }
+
+ return "UNKNOWN";
+ }
+
+ public static boolean isIconSupported(String icon) {
+ Platform platform = Platform.getPlatform();
+ switch (platform) {
+ case WINDOWS:
+ if (icon.endsWith(".ico")) {
+ return true;
+ } else {
+ Log.warning("Icon file format (" + getIconFormat(icon) + ") is not supported on Windows for file " + icon + ".");
+ return false;
+ }
+ case LINUX:
+ if (icon.endsWith(".png")) {
+ return true;
+ } else {
+ Log.warning("Icon file format (" + getIconFormat(icon) + ") is not supported on Linux for file " + icon + ".");
+ return false;
+ }
+ case MAC:
+ Log.warning("Icon file format (" + getIconFormat(icon) + ") is not supported on OS X for file " + icon + ".");
+ return false;
+ }
+
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/Log.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package jnlp.converter;
+
+public class Log {
+ private static boolean verbose = false;
+
+ public static void setVerbose(boolean verbose) {
+ Log.verbose = verbose;
+ }
+
+ public static boolean isVerbose() {
+ return verbose;
+ }
+
+ public static void verbose(String msg) {
+ if (verbose) {
+ System.out.println(msg);
+ }
+ }
+
+ public static void info(String msg) {
+ System.out.println("Info: " + msg);
+ }
+
+ public static void warning(String msg) {
+ System.err.println("Warning: " + msg);
+ }
+
+ public static void error(String msg) {
+ System.err.println("Error: " + msg);
+ System.exit(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/Main.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter;
+
+import java.io.File;
+
+public class Main {
+
+ private static void showHelp() {
+ Options.showHelp();
+ }
+
+ private static void showVersion() {
+ System.out.println("Version: 1.0");
+ }
+
+ private static void createBundle(Options options) {
+ Log.verbose("Creating bundle for JNLP: " + options.getJNLP());
+ Log.verbose("Output folder: " + options.getOutput());
+
+ JNLPConverter converter = new JNLPConverter(options);
+ converter.convert();
+ }
+
+ private static void validateJDK() {
+ String jpackagerPath = JNLPConverter.getJPackagerPath();
+ File file = new File(jpackagerPath);
+ if (!file.exists()) {
+ Log.error("Cannot find " + jpackagerPath + ". Make sure you running JNLPConverter with supported JDK version.");
+ }
+ }
+
+ public static void main(String[] args) {
+ Options options = Options.parseArgs(args); // Only valid options will be returned
+
+ Log.setVerbose(options.verbose());
+
+ validateJDK();
+
+ if (options.help()) {
+ showHelp();
+ } else if (options.version()) {
+ showVersion();
+ } else {
+ createBundle(options);
+ }
+
+ System.exit(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/Options.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Options {
+
+ private boolean createImage = false;
+ private boolean createInstaller = false;
+ private String installerType = null;
+ private String jnlp = null;
+ private String output = null;
+ private String keep = null;
+ private boolean help = false;
+ private boolean verbose = false;
+ private boolean version = false;
+ private final List<String> jpackagerOptions = new ArrayList<>();
+ private boolean isRuntimeImageSet = false;
+
+ private static final String JNLP_OPTION_PREFIX = "--jnlp=";
+ private static final String OUTPUT_OPTION_PREFIX = "--output=";
+ private static final String KEEP_OPTION_PREFIX = "--keep=";
+ private static final String JNLP_OPTION_SHORT_PREFIX = "-j";
+ private static final String OUTPUT_OPTION_SHORT_PREFIX = "-o";
+ private static final String KEEP_OPTION_SHORT_PREFIX = "-k";
+
+ private static final String [] INSTALLER_TYPES = {"msi", "rpm", "deb",
+ "dmg", "pkg", "pkg-app-store"};
+
+ // --output, -o, --input, -i, --files, -f, --main-jar, -j, --class, -c
+ private static final String [] BLOCKED_JPACKAGER_OPTIONS = {"--output", "-o", "--input", "-i",
+ "--files", "-f", "--main-jar",
+ "-j", "--class", "-c"};
+
+ private static final String RUNTIME_IMAGE_OPTION = "--runtime-image";
+
+ private static final String ERR_UNKNOWN_OPTION = "Unknown option: ";
+ private static final String ERR_MISSING_VALUE = "Value is required for option ";
+ private static final String ERR_MISSING_MODE = "Error: create-image or create-installer mode is required";
+ private static final String ERR_MISSING_JNLP = "Error: --jnlp is required";
+ private static final String ERR_MISSING_OUTPUT = "Error: --output is required";
+ private static final String ERR_OUTPUT_EXISTS = "Error: output folder already exists";
+ private static final String ERR_KEEP_EXISTS = "Error: folder for --keep argument already exists";
+ private static final String ERR_INVALID_PROTOCOL_JNLP = "Error: Invalid protocol for JNLP file. Only HTTP, HTTPS and FILE protocols are supported.";
+
+ public boolean createImage() {
+ return createImage;
+ }
+
+ public boolean createInstaller() {
+ return createInstaller;
+ }
+
+ public String getInstallerType() {
+ return installerType;
+ }
+
+ public String getJNLP() {
+ return jnlp;
+ }
+
+ public String getOutput() {
+ return output;
+ }
+
+ public String keep() {
+ return keep;
+ }
+
+ public boolean help() {
+ return help;
+ }
+
+ public boolean verbose() {
+ return verbose;
+ }
+
+ public boolean version() {
+ return version;
+ }
+
+ public List<String> getJPackagerOptions() {
+ return jpackagerOptions;
+ }
+
+ public boolean isRuntimeImageSet() {
+ return isRuntimeImageSet;
+ }
+
+ // Helper method to dump all options
+ private void display() {
+ System.out.println("Options:");
+ System.out.println("createImage: " + createImage);
+ System.out.println("createInstaller: " + createInstaller);
+ System.out.println("installerType: " + installerType);
+ System.out.println("jnlp: " + jnlp);
+ System.out.println("output: " + output);
+ System.out.println("keep: " + keep);
+ System.out.println("help: " + help);
+ System.out.println("verbose: " + verbose);
+ System.out.println("version: " + version);
+ for (int i = 0; i < jpackagerOptions.size(); i++) {
+ System.out.println("jpackagerOptions[" + i + "]: " + jpackagerOptions.get(i));
+ }
+ }
+
+ private void validate() {
+ if (help || version) {
+ return;
+ }
+
+ if (!createImage && !createInstaller) {
+ optionError(ERR_MISSING_MODE);
+ }
+
+ if (jnlp == null) {
+ optionError(ERR_MISSING_JNLP);
+ } else {
+ int index = jnlp.indexOf(":");
+ if (index == -1 || index == 0) {
+ optionError(ERR_INVALID_PROTOCOL_JNLP);
+ } else {
+ String protocol = jnlp.substring(0, index);
+ if (!protocol.equalsIgnoreCase("http") &&
+ !protocol.equalsIgnoreCase("https") &&
+ !protocol.equalsIgnoreCase("file")) {
+ optionError(ERR_INVALID_PROTOCOL_JNLP);
+ }
+ }
+ }
+
+ if (output == null) {
+ optionError(ERR_MISSING_OUTPUT);
+ } else {
+ File file = new File(output);
+ if (file.exists()) {
+ optionErrorNoHelp(ERR_OUTPUT_EXISTS);
+ }
+ }
+
+ if (keep != null) {
+ File file = new File(keep);
+ if (file.exists()) {
+ optionErrorNoHelp(ERR_KEEP_EXISTS);
+ }
+ }
+
+ jpackagerOptions.forEach((option) -> {
+ if (isBlockedOption(option)) {
+ Log.error(option + " is not allowed via --jpackager-options, since it will conflict with "
+ + "same option generated by JNLPConverter.");
+ }
+ });
+ }
+
+ public boolean isOptionPresent(String option) {
+ for (String jpackagerOption : jpackagerOptions) {
+ if (jpackagerOption.equalsIgnoreCase(option)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isBlockedOption(String option) {
+ for (String blockedOption : BLOCKED_JPACKAGER_OPTIONS) {
+ if (blockedOption.equalsIgnoreCase(option)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static void showHelp() {
+// System.out.println("********* Help should not be longer then 80 characters as per JEP-293 *********");
+ System.out.println("Usage: java -jar JNLPConverter.jar <mode> <options>");
+ System.out.println("");
+ System.out.println("where mode is one of:");
+ System.out.println(" create-image");
+ System.out.println(" Generates a platform-specific application image.");
+ System.out.println(" create-installer <type>");
+ System.out.println(" Generates a platform-specific installer for the application.");
+ System.out.println(" Valid values for \"type\" are \"msi\", \"rpm\", \"deb\", \"dmg\", \"pkg\",");
+ System.out.println(" \"pkg-app-store\". If \"type\" is omitted, all supported types of installable");
+ System.out.println(" packages for current platform will be generated.");
+ System.out.println("");
+ System.out.println("Possible options include:");
+ System.out.println(" -j, --jnlp <path>");
+ System.out.println(" Full path to JNLP file. Supported protocols are HTTP/HTTPS/FILE.");
+ System.out.println(" -o, --output <path>");
+ System.out.println(" Name of the directory where generated output files are placed.");
+ System.out.println(" -k, --keep <path>");
+ System.out.println(" Keep JNLP, JARs and command line arguments for jpackager");
+ System.out.println(" in directory provided.");
+ System.out.println(" --jpackager-options <options>");
+ System.out.println(" Specify additional jpackager options or overwrite provided by JNLPConverter.");
+ System.out.println(" All jpackager options can be specified except: --output -o, --input -i,");
+ System.out.println(" --files -f, --main-jar -j and --class -c.");
+ System.out.println(" -h, --help, -?");
+ System.out.println(" Print this help message");
+ System.out.println(" -v, --verbose");
+ System.out.println(" Enable verbose output.");
+ System.out.println(" --version");
+ System.out.println(" Version information.");
+ System.out.println("To specify an argument for a long option, you can use --<name>=<value> or");
+ System.out.println("--<name> <value>.");
+ System.out.println("To specify proxy server use standard Java properties http.proxyHost and http.proxyPort.");
+ }
+
+ private static boolean isInstallerType(String type) {
+ for (String installerType : INSTALLER_TYPES) {
+ if (installerType.equals(type)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static Options parseArgs(String[] args) {
+ Options options = new Options();
+
+ int index = 0;
+ if (args.length >= 1) {
+ switch (args[0]) {
+ case "create-image":
+ options.createImage = true;
+ index = 1;
+ break;
+ case "create-installer":
+ options.createInstaller = true;
+ index = 1;
+ if (args.length >= 2) {
+ if (isInstallerType(args[1])) {
+ options.installerType = args[1];
+ index = 2;
+ }
+ }
+ break;
+ case "-h":
+ case "--help":
+ case "-?":
+ case "--version":
+ break;
+ default:
+ optionError(Options.ERR_MISSING_MODE);
+ break;
+ }
+ }
+
+ for (int i = index; i < args.length; i++) {
+ String arg = args[i];
+
+ if (arg.equals("--jnlp")) {
+ if (++i >= args.length) {
+ optionError(Options.ERR_MISSING_VALUE, "--jnlp");
+ }
+ options.jnlp = args[i];
+ } else if (arg.startsWith(JNLP_OPTION_PREFIX)) {
+ options.jnlp = arg.substring(JNLP_OPTION_PREFIX.length());
+ } else if (arg.equals("--output")) {
+ if (++i >= args.length) {
+ optionError(Options.ERR_MISSING_VALUE, "--output");
+ }
+ options.output = args[i];
+ } else if (arg.startsWith(OUTPUT_OPTION_PREFIX)) {
+ options.output = arg.substring(OUTPUT_OPTION_PREFIX.length());
+ } else if (arg.equals("--keep")) {
+ if (++i >= args.length) {
+ optionError(Options.ERR_MISSING_VALUE, "--keep");
+ }
+ options.keep = args[i];
+ } else if (arg.startsWith(KEEP_OPTION_PREFIX)) {
+ options.keep = arg.substring(KEEP_OPTION_PREFIX.length());
+ } else if (arg.equals("--help")) {
+ options.help = true;
+ } else if (arg.equals("--verbose")) {
+ options.verbose = true;
+ } else if (arg.equals("--version")) {
+ options.version = true;
+ } else if (arg.equals("-j")) { // short options
+ if (++i >= args.length) {
+ optionError(Options.ERR_MISSING_VALUE, "-j");
+ }
+ options.jnlp = args[i];
+ } else if (arg.startsWith(JNLP_OPTION_SHORT_PREFIX)) {
+ options.jnlp = arg.substring(JNLP_OPTION_SHORT_PREFIX.length());
+ } else if (arg.equals("-o")) {
+ if (++i >= args.length) {
+ optionError(Options.ERR_MISSING_VALUE, "-o");
+ }
+ options.output = args[i];
+ } else if (arg.startsWith(OUTPUT_OPTION_SHORT_PREFIX)) {
+ options.output = arg.substring(OUTPUT_OPTION_SHORT_PREFIX.length());
+ } else if (arg.equals("-k")) {
+ if (++i >= args.length) {
+ optionError(Options.ERR_MISSING_VALUE, "-k");
+ }
+ options.keep = args[i];
+ } else if (arg.startsWith(KEEP_OPTION_SHORT_PREFIX)) {
+ options.keep = arg.substring(KEEP_OPTION_SHORT_PREFIX.length());
+ } else if (arg.equals("-h") || arg.equals("-?")) {
+ options.help = true;
+ } else if (arg.equals("-v")) {
+ options.verbose = true;
+ } else if (arg.equals("--jpackager-options")) {
+ for (i = (i + 1); i < args.length; i++) {
+ if (!options.isRuntimeImageSet) {
+ if (args[i].equals(RUNTIME_IMAGE_OPTION)) {
+ options.isRuntimeImageSet = true;
+ }
+ }
+ options.jpackagerOptions.add(args[i]);
+ }
+ } else {
+ optionError(ERR_UNKNOWN_OPTION, arg);
+ }
+ }
+
+ //options.display(); // For testing only
+ options.validate();
+
+ return options;
+ }
+
+ private static void optionErrorNoHelp(String msg) {
+ System.out.println(msg);
+ System.exit(1);
+ }
+
+ private static void optionError(String msg) {
+ System.out.println(msg);
+ System.out.println();
+ showHelp();
+ System.exit(1);
+ }
+
+ private static void optionError(String msg, String option) {
+ System.out.println(msg + option);
+ System.out.println();
+ showHelp();
+ System.exit(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/Platform.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter;
+
+import java.util.regex.Pattern;
+
+public enum Platform {
+ UNKNOWN, WINDOWS, LINUX, MAC;
+ private static final Platform platform;
+ private static final int majorVersion;
+ private static final int minorVersion;
+
+ static {
+ String os = System.getProperty("os.name").toLowerCase();
+
+ if (os.contains("win")) {
+ platform = Platform.WINDOWS;
+ } else if (os.contains("nix") || os.contains("nux")) {
+ platform = Platform.LINUX;
+ } else if (os.contains("mac")) {
+ platform = Platform.MAC;
+ } else {
+ platform = Platform.UNKNOWN;
+ }
+
+ String version = System.getProperty("os.version");
+ String[] parts = version.split(Pattern.quote("."));
+
+ if (parts.length > 0) {
+ majorVersion = Integer.parseInt(parts[0]);
+
+ if (parts.length > 1) {
+ minorVersion = Integer.parseInt(parts[0]);
+ } else {
+ minorVersion = -1;
+ }
+ } else {
+ majorVersion = -1;
+ minorVersion = -1;
+ }
+ }
+
+ private Platform() {
+ }
+
+ public static Platform getPlatform() {
+ return platform;
+ }
+
+ public static boolean isWindows() {
+ return (platform == Platform.WINDOWS);
+ }
+
+ public static int getMajorVersion() {
+ return majorVersion;
+ }
+
+ public static int getMinorVersion() {
+ return minorVersion;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/GeneralUtil.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.util.Locale;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Handy class to add some utility methods for dealing with property matching
+ * etc.
+ */
+public class GeneralUtil {
+
+ public static boolean prefixMatchStringList(String[] prefixList, String target) {
+ // No prefixes matches everything
+ if (prefixList == null) {
+ return true;
+ }
+ // No target, but a prefix list does not match anything
+ if (target == null) {
+ return false;
+ }
+ for (String prefix : prefixList) {
+ if (target.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String getOSArch() {
+ return System.getProperty("os.arch");
+ }
+
+ public static boolean prefixMatchArch(String[] prefixList) {
+ // No prefixes matches everything
+ if (prefixList == null) {
+ return true;
+ }
+
+ // check for the current arch
+ String arch = getOSArch();
+ for (String prefix : prefixList) {
+ if (arch.startsWith(prefix)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Converts a space delimited string to a list of strings
+ */
+ public static String[] getStringList(String str) {
+ if (str == null) {
+ return null;
+ }
+ ArrayList<String> list = new ArrayList<>();
+ int i = 0;
+ int length = str.length();
+ StringBuffer sb = null;
+ while (i < length) {
+ char ch = str.charAt(i);
+ switch (ch) {
+ case ' ':
+ // A space was hit. Add string to list
+ if (sb != null) {
+ list.add(sb.toString());
+ sb = null;
+ }
+ break;
+ case '\\':
+ // It is a delimiter. Add next character
+ if (i + 1 < length) {
+ ch = str.charAt(++i);
+ if (sb == null) {
+ sb = new StringBuffer();
+ }
+ sb.append(ch);
+ }
+ break;
+ default:
+ if (sb == null) {
+ sb = new StringBuffer();
+ } sb.append(ch);
+ break;
+ }
+ i++; // Next character
+ }
+ // Make sure to add the last part to the list too
+ if (sb != null) {
+ list.add(sb.toString());
+ }
+ if (list.isEmpty()) {
+ return null;
+ }
+ String[] results = new String[list.size()];
+ return list.toArray(results);
+ }
+
+ /**
+ * Checks if string list matches default locale
+ */
+ public static boolean matchLocale(String[] localeList, Locale locale) {
+ // No locale specified matches everything
+ if (localeList == null) {
+ return true;
+ }
+ for (String localeList1 : localeList) {
+ if (matchLocale(localeList1, locale)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if string matches default locale
+ */
+ public static boolean matchLocale(String localeStr, Locale locale) {
+ if (localeStr == null || localeStr.length() == 0) {
+ return true;
+ }
+
+ // Compare against default locale
+ String language;
+ String country;
+ String variant;
+
+ // The locale string is of the form language_country_variant
+ StringTokenizer st = new StringTokenizer(localeStr, "_", false);
+ if (st.hasMoreElements() && locale.getLanguage().length() > 0) {
+ language = st.nextToken();
+ if (!language.equalsIgnoreCase(locale.getLanguage())) {
+ return false;
+ }
+ }
+ if (st.hasMoreElements() && locale.getCountry().length() > 0) {
+ country = st.nextToken();
+ if (!country.equalsIgnoreCase(locale.getCountry())) {
+ return false;
+ }
+ }
+ if (st.hasMoreElements() && locale.getVariant().length() > 0) {
+ variant = st.nextToken();
+ if (!variant.equalsIgnoreCase(locale.getVariant())) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static long heapValToLong(String heapValue) {
+ if (heapValue == null) {
+ return -1;
+ }
+ long multiplier = 1;
+ if (heapValue.toLowerCase().lastIndexOf('m') != -1) {
+ // units are megabytes, 1 megabyte = 1024 * 1024 bytes
+ multiplier = 1024 * 1024;
+ heapValue = heapValue.substring(0, heapValue.length() - 1);
+ } else if (heapValue.toLowerCase().lastIndexOf('k') != -1) {
+ // units are kilobytes, 1 kilobyte = 1024 bytes
+ multiplier = 1024;
+ heapValue = heapValue.substring(0, heapValue.length() - 1);
+ }
+ long theValue;
+ try {
+ theValue = Long.parseLong(heapValue);
+ theValue = theValue * multiplier;
+ } catch (NumberFormatException e) {
+ theValue = -1;
+ }
+ return theValue;
+ }
+
+ public static byte[] readBytes(InputStream is, long size) throws IOException {
+ // Sanity on file size (restrict to 1M)
+ if (size > 1024 * 1024) {
+ throw new IOException("File too large");
+ }
+
+ BufferedInputStream bis;
+ if (is instanceof BufferedInputStream) {
+ bis = (BufferedInputStream) is;
+ } else {
+ bis = new BufferedInputStream(is);
+ }
+
+ if (size <= 0) {
+ size = 10 * 1024; // Default to 10K
+ }
+ byte[] b = new byte[(int) size];
+ int n;
+ int bytesRead = 0;
+ n = bis.read(b, bytesRead, b.length - bytesRead);
+ while (n != -1) {
+ bytesRead += n;
+ // Still room in array
+ if (b.length == bytesRead) {
+ byte[] bb = new byte[b.length * 2];
+ System.arraycopy(b, 0, bb, 0, b.length);
+ b = bb;
+ }
+ // Read next line
+ n = bis.read(b, bytesRead, b.length - bytesRead);
+ }
+ bis.close();
+ is.close();
+
+ if (bytesRead != b.length) {
+ byte[] bb = new byte[bytesRead];
+ System.arraycopy(b, 0, bb, 0, bytesRead);
+ b = bb;
+ }
+ return b;
+ }
+
+ public static String getOSFullName() {
+ return System.getProperty("os.name");
+ }
+
+ /**
+ * Makes sure a URL is a path URL, i.e., ends with '/'
+ */
+ public static URL asPathURL(URL url) {
+ if (url == null) {
+ return null;
+ }
+
+ String path = url.getFile();
+ if (path != null && !path.endsWith("/")) {
+ try {
+ return new URL(url.getProtocol(),
+ url.getHost(),
+ url.getPort(),
+ url.getFile() + "/");
+ } catch (MalformedURLException mue) {
+ // Should not happen
+ }
+ }
+ // Just return same URl
+ return url;
+ }
+
+ public static Locale getDefaultLocale() {
+ return Locale.getDefault();
+ }
+
+ public static String toNormalizedString(URL u) {
+ if (u == null) {
+ return "";
+ }
+
+ try {
+ if (u.getPort() == u.getDefaultPort()) {
+ u = new URL(u.getProtocol().toLowerCase(),
+ u.getHost().toLowerCase(), -1, u.getFile());
+ } else {
+ u = new URL(u.getProtocol().toLowerCase(),
+ u.getHost().toLowerCase(), u.getPort(), u.getFile());
+ }
+ } catch (MalformedURLException ex) {
+ }
+ return u.toExternalForm();
+ }
+
+ public static boolean sameURLs(URL u1, URL u2) {
+ if (u1 == null || u2 == null || (u1 == u2)) {
+ return (u1 == u2);
+ }
+ //NB: do not use URL.sameFile() as it will do DNS lookup
+ // Also, do quick check before slow string comparisons
+ String f1 = u1.getFile();
+ String f2 = u2.getFile();
+ return (f1.length() == f2.length()) && sameBase(u1, u2)
+ && f1.equalsIgnoreCase(f2);
+ }
+
+ public static boolean sameBase(URL u1, URL u2) {
+ return u1 != null && u2 != null &&
+ sameHost(u1, u2) && samePort(u1, u2) && sameProtocol(u1, u2);
+ }
+
+ private static boolean sameProtocol(URL u1, URL u2) {
+ //protocols are known to be lowercase
+ return u1.getProtocol().equals(u2.getProtocol());
+ }
+
+ private static boolean sameHost(URL u1, URL u2) {
+ String host = u1.getHost();
+ String otherHost = u2.getHost();
+ if (host == null || otherHost == null) {
+ return (host == null && otherHost == null);
+ } else {
+ //avoid slow comparison for strings of different length
+ return ((host.length() == otherHost.length())
+ && host.equalsIgnoreCase(otherHost));
+ }
+ }
+
+ private static boolean samePort(URL u1, URL u2) {
+ return getPort(u1) == getPort(u2);
+ }
+
+ public static int getPort(URL u) {
+ if (u.getPort() != -1) {
+ return u.getPort();
+ } else {
+ return u.getDefaultPort();
+ }
+ }
+
+ public static URL getBase(URL url) {
+ if (url == null) return null;
+ String file = url.getFile();
+ if (file != null) {
+ int idx = file.lastIndexOf('/');
+ if (idx != -1 ) {
+ file = file.substring(0, idx + 1);
+ }
+ try {
+ return new URL(
+ url.getProtocol(),
+ url.getHost(),
+ url.getPort(),
+ file);
+ } catch(MalformedURLException mue) {
+ System.err.println(mue.getMessage());
+ }
+ }
+ // Just return same URL
+ return url;
+ }
+
+ private static String getEmbeddedVersionPath(String path, String version) {
+ int index = path.lastIndexOf("/");
+ String filename = path.substring(index + 1);
+ path = path.substring(0, index + 1);
+
+ String ext = null;
+ index = filename.lastIndexOf(".");
+ if (index != -1) {
+ ext = filename.substring(index + 1);
+ filename = filename.substring(0, index);
+ }
+
+ StringBuilder filenameSB = new StringBuilder(filename);
+ if (version != null) {
+ filenameSB.append("__V");
+ filenameSB.append(version);
+ }
+ if (ext != null) {
+ filenameSB.append(".");
+ filenameSB.append(ext);
+ }
+
+ path += filenameSB.toString();
+ return path;
+ }
+
+ public static URL getEmbeddedVersionURL(URL u, String version) throws Exception {
+ if (u == null) {
+ return null;
+ }
+
+ if (version == null || version.indexOf("*") != -1
+ || version.indexOf("+") != -1) {
+ // Do not support * or + in version string
+ return u;
+ }
+
+ URL versionURL = null;
+
+ String protocol = u.getProtocol();
+ String host = u.getHost();
+ int port = u.getPort();
+ String path = u.getPath();
+
+ path = getEmbeddedVersionPath(path, version);
+
+ versionURL = new URL(protocol, host, port, path);
+
+ return versionURL;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/JNLPDesc.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,617 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import jnlp.converter.Log;
+
+import jnlp.converter.parser.ResourcesDesc.JARDesc;
+import jnlp.converter.parser.ResourcesDesc.JREDesc;
+
+public class JNLPDesc {
+ private String specVersion = null;
+ private String codebase = null;
+ private String version = null;
+ private String href = null;
+ private String name = null;
+ private String title = null;
+ private String vendor = null;
+ private String mainJar = null;
+ private String [] descriptions = null;
+ private IconDesc [] icons = null;
+ private ShortcutDesc shortcuts = null;
+ private AssociationDesc [] associations = null;
+ private String mainClass = null;
+ private final List<String> arguments = new ArrayList<>();
+ private final List<String> files = new ArrayList<>();
+ private final List<JARDesc> resources = new ArrayList<>();
+ private final List<String> vmArgs = new ArrayList<>();
+ private boolean isLibrary = false;
+ private boolean isInstaller = false;
+ private boolean isJRESet = false;
+ private ResourcesDesc resourcesDesc;
+ private boolean isVersionEnabled = false;
+ private boolean isSandbox = true;
+ private boolean isFXApp = false;
+
+ public void setSpecVersion(String specVersion) {
+ this.specVersion = specVersion;
+
+ // Valid values are 1.0, 1.5, 6.0, 6.0.10, 6.0.18, 7.0, 8.20, 9 or a wildcard such as 1.0+.
+ if (!specVersion.startsWith("1.0") &&
+ !specVersion.startsWith("1.5") &&
+ !specVersion.startsWith("6.0") &&
+ !specVersion.startsWith("6.0.10") &&
+ !specVersion.startsWith("6.0.18") &&
+ !specVersion.startsWith("7.0") &&
+ !specVersion.startsWith("8.20") &&
+ !specVersion.startsWith("9")) {
+ System.out.println("Warning: Invalid version of the JNLP specification found: "
+ + specVersion + ". Valid values are 1.0, 1.5, 6.0, 6.0.10, 6.0.18, 7.0,"
+ + " 8.20, 9 or a wildcard such as 1.0+.");
+ }
+ }
+
+ public String getSpecVersion() {
+ return specVersion;
+ }
+
+ public void setCodebase(String codebase) {
+ this.codebase = codebase;
+ }
+
+ public String getCodebase() {
+ return codebase;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setVendor(String vendor) {
+ this.vendor = vendor;
+ }
+
+ public String getVendor() {
+ return vendor;
+ }
+
+ public void setMainJar(String mainJar) {
+ if (this.mainJar == null) {
+ this.mainJar = mainJar;
+ } else {
+ Log.warning("Main jar already set to '" + this.mainJar + "'. "
+ + "Attempt to set main jar to '" + mainJar + "' will be ignored.");
+ }
+ }
+
+ public String getMainJar() {
+ return mainJar;
+ }
+
+ public void setDescriptions(String [] descriptions) {
+ this.descriptions = descriptions;
+ }
+
+ public String getDescription() {
+ String description = null;
+ if (descriptions != null) {
+ if (descriptions[InformationDesc.DESC_DEFAULT] != null) {
+ description = descriptions[InformationDesc.DESC_DEFAULT];
+ } else if (descriptions[InformationDesc.DESC_SHORT] != null) {
+ description = descriptions[InformationDesc.DESC_SHORT];
+ } else if (descriptions[InformationDesc.DESC_ONELINE] != null) {
+ description = descriptions[InformationDesc.DESC_ONELINE];
+ } else if (descriptions[InformationDesc.DESC_TOOLTIP] != null) {
+ description = descriptions[InformationDesc.DESC_TOOLTIP];
+ }
+
+ if (description != null) {
+ if (description.contains("\r") || description.contains("\n")) {
+ Log.warning("Multiple lines of text in description is not supported and description will be converted to single line by replacing new lines with spaces.");
+ Log.warning("Original description:");
+ Log.warning(description);
+ String descs[] = description.split("\n");
+ description = "";
+ for (String desc : descs) {
+ desc = desc.trim();
+ if (desc.endsWith("\r")) { // In case new line was \r\n
+ if (desc.length() != 1) {
+ desc = desc.substring(0, desc.length() - 1);
+ } else {
+ continue;
+ }
+ }
+
+ if (desc.isEmpty()) {
+ continue;
+ }
+
+ if (!description.isEmpty()) {
+ description += " ";
+ }
+
+ description += desc;
+ }
+ Log.warning("Converted description:");
+ Log.warning(description);
+ }
+ }
+ }
+
+ return description;
+ }
+
+ public void setIcons(IconDesc [] icons) {
+ this.icons = icons;
+ }
+
+ public IconDesc getIcon() {
+ for (IconDesc icon : icons) {
+ if (icon.getKind() == IconDesc.ICON_KIND_DEFAULT) {
+ return icon;
+ }
+ }
+
+ for (IconDesc icon : icons) {
+ if (icon.getKind() == IconDesc.ICON_KIND_SHORTCUT) {
+ return icon;
+ }
+ }
+
+ return null;
+ }
+
+ public String getIconLocation() {
+ IconDesc icon = getIcon();
+ if (icon != null) {
+ return icon.getLocalLocation();
+ }
+
+ return null;
+ }
+
+ public void setShortcuts(ShortcutDesc shortcuts) {
+ this.shortcuts = shortcuts;
+ }
+
+ public boolean isDesktopHint() {
+ if (shortcuts != null) {
+ return shortcuts.getDesktop();
+ }
+
+ return false;
+ }
+
+ public boolean isMenuHint() {
+ if (shortcuts != null) {
+ return shortcuts.getMenu();
+ }
+
+ return false;
+ }
+
+ public String getSubMenu() {
+ if (shortcuts != null) {
+ return shortcuts.getSubmenu();
+ }
+
+ return null;
+ }
+
+ public void setAssociations(AssociationDesc [] associations) {
+ this.associations = associations;
+ }
+
+ public AssociationDesc [] getAssociations() {
+ return associations;
+ }
+
+ public void setMainClass(String mainClass, boolean isJavafxDesc) {
+ if (isJavafxDesc) {
+ this.mainClass = mainClass;
+ } else if (this.mainClass == null) {
+ this.mainClass = mainClass;
+ }
+ }
+
+ public String getMainClass() {
+ return mainClass;
+ }
+
+ public void addArguments(String argument) {
+ if (argument != null && !argument.isEmpty()) {
+ arguments.add(argument);
+ }
+ }
+
+ public List<String> getArguments() {
+ return arguments;
+ }
+
+ public void setProperty(String name, String value) {
+ if (name.equalsIgnoreCase("jnlp.versionEnabled") && value.equalsIgnoreCase("true")) {
+ isVersionEnabled = true;
+ return;
+ }
+
+ addVMArg("-D" + name + "=" + value);
+ }
+
+ public boolean isVersionEnabled() {
+ return isVersionEnabled;
+ }
+
+ public boolean isSandbox() {
+ return isSandbox;
+ }
+
+ public void setIsSandbox(boolean value) {
+ isSandbox = value;
+ }
+
+ public boolean isFXApp() {
+ return isFXApp;
+ }
+
+ public void setIsFXApp(boolean value) {
+ isFXApp = value;
+ }
+
+ public void addFile(String file) {
+ if (file != null) {
+ files.add(file);
+ }
+ }
+
+ public List<String> getFiles() {
+ return files;
+ }
+
+ private boolean isResourceExists(JARDesc resource) {
+ for (JARDesc r : resources) {
+ if (r.getLocation().equals(resource.getLocation())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void addResource(JARDesc resource) {
+ if (resource != null) {
+ if (isResourceExists(resource)) {
+ Log.warning("Ignoring repeated resource " + resource.getLocation());
+ return;
+ }
+ resources.add(resource);
+ }
+ }
+
+ public List<JARDesc> getResources() {
+ return resources;
+ }
+
+ public void addVMArg(String arg) {
+ if (arg != null) {
+ vmArgs.add(arg);
+ }
+ }
+
+ public List<String> getVMArgs() {
+ return vmArgs;
+ }
+
+ public void setIsLibrary(boolean isLibrary) {
+ this.isLibrary = isLibrary;
+ }
+
+ public boolean isLibrary() {
+ return isLibrary;
+ }
+
+ public void setIsInstaller(boolean isInstaller) {
+ this.isInstaller = isInstaller;
+ }
+
+ public boolean isInstaller() {
+ return isInstaller;
+ }
+
+ public void setIsJRESet(boolean isJRESet) {
+ this.isJRESet = isJRESet;
+ }
+
+ public boolean isJRESet() {
+ return isJRESet;
+ }
+
+ public void setResourcesDesc(ResourcesDesc resourcesDesc) {
+ this.resourcesDesc = resourcesDesc;
+ }
+
+ public ResourcesDesc getResourcesDesc() {
+ return resourcesDesc;
+ }
+
+ public void parseResourceDesc() throws Exception {
+ if (resourcesDesc != null && !resourcesDesc.isEmpty()) {
+ setMainJar(resourcesDesc.getMainJar().getName());
+
+ JARDesc[] jars = resourcesDesc.getAllJarDescs();
+ for (JARDesc jar : jars) {
+ addResource(jar);
+ }
+
+ JREDesc jreDesc = resourcesDesc.getJreDesc();
+ if (jreDesc != null) {
+ String [] args = jreDesc.getVmArgsList();
+ if (args != null) {
+ for (String arg : args) {
+ addVMArg(arg);
+ }
+ }
+
+ if (jreDesc.getMinHeap() != -1) {
+ addVMArg("-Xms" + jreDesc.getMinHeap());
+ }
+
+ if (jreDesc.getMaxHeap() != -1) {
+ addVMArg("-Xmx" + jreDesc.getMaxHeap());
+ }
+ }
+
+ Properties props = resourcesDesc.getResourceProperties();
+ Enumeration e = props.propertyNames();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ String value = props.getProperty(key);
+ setProperty(key, value);
+ }
+ }
+ }
+
+ public static class InformationDesc {
+
+ private final String _title;
+ private final String _vendor;
+ private final String[] _descriptions;
+ private final IconDesc[] _icons;
+ private ShortcutDesc _shortcutHints;
+ private AssociationDesc[] _associations;
+
+ public InformationDesc(String title, String vendor,
+ String[] descriptions,
+ IconDesc[] icons,
+ ShortcutDesc shortcutHints,
+ AssociationDesc[] associations) {
+ _title = (title == null) ? "" : title;
+ _vendor = (vendor == null) ? "" : vendor;
+ if (descriptions == null) {
+ descriptions = new String[NOF_DESC];
+ }
+ _descriptions = descriptions;
+ _icons = icons;
+ _shortcutHints = shortcutHints;
+ _associations = associations;
+ }
+
+ /**
+ * Constants for the getInfoDescription
+ */
+ final public static int DESC_DEFAULT = 0;
+ final public static int DESC_SHORT = 1;
+ final public static int DESC_ONELINE = 2;
+ final public static int DESC_TOOLTIP = 3;
+ final public static int NOF_DESC = 4;
+
+ /**
+ * Information
+ */
+ public String getTitle() {
+ return _title;
+ }
+
+ public String getVendor() {
+ return _vendor;
+ }
+
+ public IconDesc[] getIcons() {
+ return _icons;
+ }
+
+ public ShortcutDesc getShortcut() {
+ if (_shortcutHints == null) {
+ return null;
+ }
+ return new ShortcutDesc(_shortcutHints.getDesktop(), _shortcutHints.getMenu(), _shortcutHints.getSubmenu());
+ }
+
+ public AssociationDesc[] getAssociations() {
+ return _associations;
+ }
+
+ /**
+ * Sets new shortcut hints.
+ *
+ * @param shortcutDesc the new shortcut hints to set
+ */
+ public void setShortcut(ShortcutDesc shortcut) {
+ _shortcutHints = shortcut;
+ }
+
+ /**
+ * Sets new associations.
+ *
+ * @param assoc the association to set
+ */
+ public void setAssociation(AssociationDesc assoc) {
+ if (assoc == null) {
+ _associations = null;
+ } else {
+ _associations = new AssociationDesc[]{assoc};
+ }
+ }
+
+ /**
+ * Returns the description of the given kind. will return null if none
+ * there
+ */
+ public String getDescription(int kind) {
+ return _descriptions[kind];
+ }
+
+ public String[] getDescription() {
+ return _descriptions;
+ }
+ }
+
+ public static class IconDesc {
+
+ private final String _location;
+ private String _localLocation;
+ private final int _kind;
+
+ final public static int ICON_KIND_DEFAULT = 0;
+ final public static int ICON_KIND_SHORTCUT = 5;
+
+ public IconDesc(URL location, int kind) {
+ _location = location.toExternalForm();
+ _kind = kind;
+ }
+
+ public String getLocation() {
+ return _location;
+ }
+
+ public void setLocalLocation(String localLocation) {
+ _localLocation = localLocation;
+ }
+
+ public String getLocalLocation() {
+ return _localLocation;
+ }
+
+ public int getKind() {
+ return _kind;
+ }
+ }
+
+ public static class ShortcutDesc {
+
+ private final boolean _desktop;
+ private final boolean _menu;
+ private final String _submenu;
+
+ public ShortcutDesc(boolean desktop, boolean menu, String submenu) {
+ _desktop = desktop;
+ _menu = menu;
+ _submenu = submenu;
+ }
+
+ public boolean getDesktop() {
+ return _desktop;
+ }
+
+ public boolean getMenu() {
+ return _menu;
+ }
+
+ public String getSubmenu() {
+ return _submenu;
+ }
+ }
+
+ public static class AssociationDesc {
+
+ private final String _extensions;
+ private final String _mimeType;
+ private final String _description;
+ private final String _icon;
+ private String _iconLocalLocation;
+
+ public AssociationDesc(String extensions, String mimeType, String description, URL icon) {
+ _extensions = extensions;
+ _mimeType = mimeType;
+ _description = description;
+ _icon = (icon != null) ? icon.toExternalForm() : null;
+ }
+
+ public void setIconLocalLocation(String localLocation) {
+ _iconLocalLocation = localLocation;
+ }
+
+ public String getIconLocalLocation() {
+ return _iconLocalLocation;
+ }
+
+ public String getExtensions() {
+ return _extensions;
+ }
+
+ public String getMimeType() {
+ return _mimeType;
+ }
+
+ public String getMimeDescription() {
+ return _description;
+ }
+
+ public String getIconUrl() {
+ return _icon;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/ResourceType.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+/*
+ * Public super class for all resource entries
+ */
+interface ResourceType {
+ /** Visit this specific type */
+ void visit(ResourceVisitor visitor) throws Exception;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/ResourceVisitor.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import jnlp.converter.parser.ResourcesDesc.JARDesc;
+import jnlp.converter.parser.ResourcesDesc.PropertyDesc;
+import jnlp.converter.parser.ResourcesDesc.JREDesc;
+import jnlp.converter.parser.ResourcesDesc.ExtensionDesc;
+
+/**
+ * A visitor class for the various ResourceType objects
+ * with dummy visit methods for all types.
+ */
+public class ResourceVisitor {
+
+ public void visitJARDesc(JARDesc jad) {
+ }
+
+ public void visitPropertyDesc(PropertyDesc prd) {
+ }
+
+ public void visitExtensionDesc(ExtensionDesc ed) throws Exception {
+ }
+
+ public void visitJREDesc(JREDesc jrd) {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/ResourcesDesc.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.net.URL;
+import java.util.Properties;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import jnlp.converter.HTTPHelper;
+
+/**
+ * This class contains information about the codebase and properties, i.e., how
+ * to locate the classes and optional-packages
+ */
+public class ResourcesDesc implements ResourceType {
+
+ private final List<ResourceType> _list;
+ private volatile JNLPDesc _parent = null;
+
+ /**
+ * Create empty resource list
+ */
+ public ResourcesDesc() {
+ _list = new CopyOnWriteArrayList<>();
+ }
+
+ public JNLPDesc getParent() {
+ return _parent;
+ }
+
+ void setParent(JNLPDesc parent) {
+ _parent = parent;
+ for (int i = 0; i < _list.size(); i++) {
+ Object o = _list.get(i);
+ if (o instanceof JREDesc) {
+ JREDesc jredesc = (JREDesc) o;
+ if (jredesc.getNestedResources() != null) {
+ jredesc.getNestedResources().setParent(parent);
+ }
+ }
+ }
+ }
+
+ public void addResource(ResourceType rd) {
+ if (rd != null) {
+ _list.add(rd);
+ }
+ }
+
+ boolean isEmpty() {
+ return _list.isEmpty();
+ }
+
+ public JARDesc[] getLocalJarDescs() {
+ ArrayList<JARDesc> jds = new ArrayList<>(_list.size());
+ for (ResourceType rt : _list) {
+ if (rt instanceof JARDesc) {
+ jds.add((JARDesc) rt);
+ }
+ }
+ return jds.toArray(new JARDesc[jds.size()]);
+ }
+
+ public JREDesc getJreDesc() {
+ for (ResourceType rt : _list) {
+ if (rt instanceof JREDesc) {
+ return (JREDesc)rt;
+ }
+ }
+
+ return null;
+ }
+
+ public ExtensionDesc[] getExtensionDescs() throws Exception {
+ final ArrayList<ExtensionDesc> extList = new ArrayList<>();
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitExtensionDesc(ExtensionDesc ed) throws Exception {
+ // add all extensiondesc recursively
+ addExtToList(extList);
+ }
+ });
+ return extList.toArray(new ExtensionDesc[extList.size()]);
+ }
+
+ public JARDesc[] getAllJarDescs() throws Exception {
+ List<JARDesc> jarList = new ArrayList<>();
+ addJarsToList(jarList);
+ return jarList.toArray(new JARDesc[jarList.size()]);
+ }
+
+ /**
+ * Add to a list of all the ExtensionDesc. This method goes recusivly through
+ * all ExtensionDesc
+ */
+ private void addExtToList(final List<ExtensionDesc> list) throws Exception {
+ // Iterate through list an add ext jnlp to the list.
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitExtensionDesc(ExtensionDesc ed) throws Exception {
+ if (ed.getExtensionDesc() != null) {
+ ed.getExtensionDesc().getMainJar();
+ ResourcesDesc rd = ed.getExtensionDesc().getResourcesDesc();
+ if (rd != null) {
+ rd.addExtToList(list);
+ }
+ }
+ list.add(ed);
+ }
+ });
+ }
+
+ private void addJarsToList(final List<JARDesc> list) throws Exception {
+
+ // Iterate through list an add resources to the list.
+ // The ordering of resources are preserved
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitJARDesc(JARDesc jd) {
+ list.add(jd);
+ }
+
+ @Override
+ public void visitExtensionDesc(ExtensionDesc ed) throws Exception {
+ if (ed.getExtensionDesc() != null) {
+ ResourcesDesc rd = ed.getExtensionDesc().getResourcesDesc();
+ if (rd != null) {
+ rd.addJarsToList(list);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Get all the resources needed when a specific resource is requested.
+ * Returns null if no resource was found
+ */
+ public JARDesc[] getResource(final URL location) throws Exception {
+ final JARDesc[] resources = new JARDesc[1];
+ // Find the given resource
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitJARDesc(JARDesc jd) {
+ if (GeneralUtil.sameURLs(jd.getLocation(), location)) {
+ resources[0] = jd;
+ }
+ }
+ });
+
+ // Found no resource?
+ if (resources[0] == null) {
+ return null;
+ }
+
+ // No part, so just one resource
+ return resources;
+ }
+
+ /* Returns the Expected Main Jar
+ * first jar with attribute main="true"
+ * else first jar if none has that attribute
+ * will look in extensions, and nested resource blocks if matching
+ */
+ protected JARDesc getMainJar() throws Exception {
+ // Normal trick to get around final arguments to inner classes
+ final JARDesc[] results = new JARDesc[2];
+
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitJARDesc(JARDesc jd) {
+ if (jd.isJavaFile()) {
+ // Keep track of first Java File
+ if (results[0] == null || results[0].isNativeLib()) {
+ results[0] = jd;
+ }
+ // Keep tack of Java File marked main
+ if (jd.isMainJarFile()) {
+ results[1] = jd;
+ }
+ } else if (jd.isNativeLib()) {
+ // if jnlp extension has only native lib
+ if (results[0] == null) {
+ results[0] = jd;
+ }
+ }
+ }
+
+ @Override
+ public void visitExtensionDesc(ExtensionDesc ed) throws Exception {
+ // only check if no main yet and it is not an installer
+ if (results[1] == null && !ed.isInstaller()) {
+ JNLPDesc extLd = ed.getExtensionDesc();
+ if (extLd != null && extLd.isLibrary()) {
+ ResourcesDesc rd = extLd.getResourcesDesc();
+ if (rd != null) {
+ // look for main jar in extension resource
+ rd.visit(this);
+ }
+ }
+ }
+ }
+ });
+
+ // Default is the first, if none is specified as main. This might
+ // return NULL if there is no JAR resources.
+ JARDesc first = results[0];
+ JARDesc main = results[1];
+
+ // if main is null then return first;
+ // libraries have no such thing as a main jar, so return first;
+ // otherwise return main
+ // only returns null if there are no jars.
+ return (main == null) ? first : main;
+ }
+
+ /*
+ * Get the properties defined for this object
+ */
+ public Properties getResourceProperties() throws Exception {
+ final Properties props = new Properties();
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitPropertyDesc(PropertyDesc pd) {
+ props.setProperty(pd.getKey(), pd.getValue());
+ }
+
+ @Override
+ public void visitExtensionDesc(ExtensionDesc ed) throws Exception {
+ JNLPDesc jnlpd = ed.getExtensionDesc();
+ ResourcesDesc rd = jnlpd.getResourcesDesc();
+ if (rd != null) {
+ Properties extProps = rd.getResourceProperties();
+ Enumeration e = extProps.propertyNames();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ String value = extProps.getProperty(key);
+ props.setProperty(key, value);
+ }
+ }
+ }
+ });
+ return props;
+ }
+
+ /*
+ * Get the properties defined for this object, in the right order.
+ */
+ public List<Property> getResourcePropertyList() throws Exception {
+ final LinkedList<Property> propList = new LinkedList<>();
+ visit(new ResourceVisitor() {
+ @Override
+ public void visitPropertyDesc(PropertyDesc pd) {
+ propList.add(new Property(pd.getKey(), pd.getValue()));
+ }
+ });
+ return propList;
+ }
+
+ /**
+ * visitor dispatch
+ */
+ @Override
+ public void visit(ResourceVisitor rv) throws Exception {
+ for (int i = 0; i < _list.size(); i++) {
+ ResourceType rt = _list.get(i);
+ rt.visit(rv);
+ }
+ }
+
+ public void addNested(ResourcesDesc nested) throws Exception {
+ if (nested != null) {
+ nested.visit(new ResourceVisitor() {
+ @Override
+ public void visitJARDesc(JARDesc jd) {
+ _list.add(jd);
+ }
+
+ @Override
+ public void visitPropertyDesc(PropertyDesc pd) {
+ _list.add(pd);
+ }
+
+ @Override
+ public void visitExtensionDesc(ExtensionDesc ed) {
+ _list.add(ed);
+ }
+ });
+ }
+
+ }
+
+ public static class JARDesc implements ResourceType {
+
+ private URL _location;
+ private String _locationString;
+ private String _version;
+ private boolean _isNativeLib;
+ private boolean _isMainFile; // Only used for Java JAR files (a main JAR file is implicitly eager)
+ private ResourcesDesc _parent; // Back-pointer to the Resources that contains this JAR
+
+ public JARDesc(URL location, String version, boolean isMainFile, boolean isNativeLib, ResourcesDesc parent) {
+ _location = location;
+ _locationString = GeneralUtil.toNormalizedString(location);
+ _version = version;
+ _isMainFile = isMainFile;
+ _isNativeLib = isNativeLib;
+ _parent = parent;
+ }
+
+ /**
+ * Type of JAR resource
+ */
+ public boolean isNativeLib() {
+ return _isNativeLib;
+ }
+
+ public boolean isJavaFile() {
+ return !_isNativeLib;
+ }
+
+ /**
+ * Returns URL/version for JAR file
+ */
+ public URL getVersionLocation() throws Exception {
+ if (getVersion() == null) {
+ return _location;
+ } else {
+ return GeneralUtil.getEmbeddedVersionURL(getLocation(), getVersion());
+ }
+ }
+
+ public URL getLocation() {
+ return _location;
+ }
+
+ public String getVersion() {
+ return _version;
+ }
+
+ public String getName() {
+ // File can be separated by '/' or '\\'
+ int index;
+ int index1 = _locationString.lastIndexOf('/');
+ int index2 = _locationString.lastIndexOf('\\');
+
+ if (index1 >= index2) {
+ index = index1;
+ } else {
+ index = index2;
+ }
+
+ if (index != -1) {
+ return _locationString.substring(index + 1, _locationString.length());
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns if this is the main JAR file
+ */
+ public boolean isMainJarFile() {
+ return _isMainFile;
+ }
+
+ /**
+ * Get parent LaunchDesc
+ */
+ public ResourcesDesc getParent() {
+ return _parent;
+ }
+
+ /**
+ * Visitor dispatch
+ */
+ public void visit(ResourceVisitor rv) {
+ rv.visitJARDesc(this);
+ }
+ }
+
+ public static class PropertyDesc implements ResourceType {
+
+ private String _key;
+ private String _value;
+
+ public PropertyDesc(String key, String value) {
+ _key = key;
+ _value = value;
+ }
+
+ // Accessors
+ public String getKey() {
+ return _key;
+ }
+
+ public String getValue() {
+ return _value;
+ }
+
+ /**
+ * Visitor dispatch
+ */
+ public void visit(ResourceVisitor rv) {
+ rv.visitPropertyDesc(this);
+ }
+
+ }
+
+ public static class JREDesc implements ResourceType {
+
+ private String _version;
+ private long _maxHeap;
+ private long _minHeap;
+ private String _vmargs;
+ private ResourcesDesc _resourceDesc;
+ private JNLPDesc _extensioDesc;
+ private String _archList;
+
+ /*
+ * Constructor to create new instance based on the requirements from JNLP file.
+ */
+ public JREDesc(String version, long minHeap, long maxHeap, String vmargs,
+ ResourcesDesc resourcesDesc, String archList) {
+
+ _version = version;
+ _maxHeap = maxHeap;
+ _minHeap = minHeap;
+ _vmargs = vmargs;
+ _resourceDesc = resourcesDesc;
+ _extensioDesc = null;
+ _archList = archList;
+ }
+
+ public String[] getArchList() {
+ return GeneralUtil.getStringList(_archList);
+ }
+
+ public String getVersion() {
+ return _version;
+ }
+
+ public long getMinHeap() {
+ return _minHeap;
+ }
+
+ public long getMaxHeap() {
+ return _maxHeap;
+ }
+
+ public String getVmArgs() {
+ return _vmargs;
+ }
+
+ public String[] getVmArgsList() {
+ return GeneralUtil.getStringList(_vmargs);
+ }
+
+ public ResourcesDesc getNestedResources() {
+ return _resourceDesc;
+ }
+
+ public JNLPDesc getExtensionDesc() {
+ return _extensioDesc;
+ }
+
+ public void setExtensionDesc(JNLPDesc ld) {
+ _extensioDesc = ld;
+ }
+
+ /* visitor dispatch */
+ public void visit(ResourceVisitor rv) {
+ rv.visitJREDesc(this);
+ }
+ }
+
+ public static class Property implements Cloneable {
+
+ public static final String JNLP_VERSION_ENABLED = "jnlp.versionEnabled";
+
+ String key;
+ String value;
+
+ public Property(String spec) {
+ spec = spec.trim();
+ if (!spec.startsWith("-D") || spec.length() < 3) {
+ throw new IllegalArgumentException("Property invalid");
+ }
+
+ int endKey = spec.indexOf("=");
+ if (endKey < 0) {
+ // it's legal to have no assignment
+ this.key = spec.substring(2); // skip "-D"
+ this.value = "";
+ } else {
+ this.key = spec.substring(2, endKey);
+ this.value = spec.substring(endKey + 1);
+ }
+ }
+
+ public static Property createProperty(String spec) {
+ Property prop = null;
+ try {
+ prop = new Property(spec);
+ } catch (IllegalArgumentException iae) {
+ }
+ return prop;
+ }
+
+ public Property(String key, String value) {
+ this.key = key;
+ if (value != null) {
+ this.value = value;
+ } else {
+ this.value = "";
+ }
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ // @return String representation, unquoted, unified presentation
+ public String toString() {
+ if (value.length() == 0) {
+ return "-D" + key;
+ }
+ return "-D" + key + "=" + value;
+ }
+
+ public void addTo(Properties props) {
+ props.setProperty(key, value);
+ }
+
+ // Hash Object
+ public boolean equals(Object o) {
+ if (!(o instanceof Property)) {
+ return false;
+ }
+ Property op = (Property) o;
+ int hashTheirs = op.hashCode();
+ int hashThis = hashCode();
+ return hashTheirs == hashThis;
+ }
+
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ private static List<Object> jnlpProps = Arrays.asList(new Object[]{
+ JNLP_VERSION_ENABLED
+ });
+
+ public static boolean isJnlpProperty(String spec) {
+ try {
+ Property p = new Property(spec);
+ return isJnlpPropertyKey(p.getKey());
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public static boolean isJnlpPropertyKey(String key) {
+ return key != null && jnlpProps.contains(key);
+ }
+ }
+
+ public static class ExtensionDesc implements ResourceType {
+ // Tag elements
+
+ private final URL _location;
+ private final String _locationString;
+ private final String _version;
+ private final URL _codebase;
+
+ // Link to launchDesc
+ private JNLPDesc _extensionLd; // Link to launchDesc for extension
+
+ public ExtensionDesc(URL location, String version) {
+ _location = location;
+ _locationString = GeneralUtil.toNormalizedString(location);
+ _version = version;
+ _codebase = GeneralUtil.asPathURL(GeneralUtil.getBase(location));
+ _extensionLd = null;
+ }
+
+ public boolean isInstaller() throws Exception {
+ if (getExtensionDesc() != null) {
+ return _extensionLd.isInstaller();
+ }
+ return false;
+ }
+
+ public URL getLocation() {
+ return _location;
+ }
+
+ public String getVersionLocation() throws Exception {
+ if (getVersion() == null) {
+ return _locationString;
+ } else {
+ return GeneralUtil.toNormalizedString(GeneralUtil.getEmbeddedVersionURL(getLocation(), getVersion()));
+ }
+ }
+
+ public String getVersion() {
+ return _version;
+ }
+
+ public URL getCodebase() {
+ return _codebase;
+ }
+
+ /*
+ * Information about the resources
+ */
+ public JNLPDesc getExtensionDesc() throws Exception {
+ if (_extensionLd == null) {
+ byte[] bits = HTTPHelper.getJNLPBits(getVersionLocation(), _locationString);
+ _extensionLd = XMLFormat.parse(bits, getCodebase(), getVersionLocation());
+ }
+ return _extensionLd;
+ }
+
+ public void setExtensionDesc(JNLPDesc desc) {
+ _extensionLd = desc;
+ }
+
+ /**
+ * Visitor dispatch
+ */
+ public void visit(ResourceVisitor rv) throws Exception {
+ rv.visitExtensionDesc(this);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/VersionID.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * VersionID contains a JNLP version ID.
+ *
+ * The VersionID also contains a prefix indicator that can
+ * be used when stored with a VersionString
+ *
+ */
+public class VersionID implements Comparable<VersionID> {
+ private final String[] _tuple; // Array of Integer or String objects
+ private final boolean _usePrefixMatch; // star (*) prefix
+ private final boolean _useGreaterThan; // plus (+) greather-than
+ private final boolean _isCompound; // and (&) operator
+ private final VersionID _rest; // remaining part after the &
+
+ /**
+ * Creates a VersionID object from a given <code>String</code>.
+ * @param str version string to parse
+ */
+ public VersionID(String str) {
+ if (str == null || str.length() == 0) {
+ _tuple = new String[0];
+ _useGreaterThan = false;
+ _usePrefixMatch = false;
+ _isCompound = false;
+ _rest = null;
+ return;
+ }
+
+ // Check for compound
+ int amp = str.indexOf("&");
+ if (amp >= 0) {
+ _isCompound = true;
+ VersionID firstPart = new VersionID(str.substring(0, amp));
+ _rest = new VersionID(str.substring(amp+1));
+ _tuple = firstPart._tuple;
+ _usePrefixMatch = firstPart._usePrefixMatch;
+ _useGreaterThan = firstPart._useGreaterThan;
+ } else {
+ _isCompound = false;
+ _rest = null;
+ // Check for postfix
+ if (str.endsWith("+")) {
+ _useGreaterThan = true;
+ _usePrefixMatch = false;
+ str = str.substring(0, str.length() - 1);
+ } else if (str.endsWith("*")) {
+ _useGreaterThan = false;
+ _usePrefixMatch = true;
+ str = str.substring(0, str.length() - 1);
+ } else {
+ _useGreaterThan = false;
+ _usePrefixMatch = false;
+ }
+
+ ArrayList<String> list = new ArrayList<>();
+ int start = 0;
+ for (int i = 0; i < str.length(); i++) {
+ // Split at each separator character
+ if (".-_".indexOf(str.charAt(i)) != -1) {
+ if (start < i) {
+ String value = str.substring(start, i);
+ list.add(value);
+ }
+ start = i + 1;
+ }
+ }
+ if (start < str.length()) {
+ list.add(str.substring(start, str.length()));
+ }
+ _tuple = list.toArray(new String[0]);
+ }
+ }
+
+ /** @return true if no flags are set */
+ public boolean isSimpleVersion() {
+ return !_useGreaterThan && !_usePrefixMatch && !_isCompound;
+ }
+
+ /** Match 'this' versionID against vid.
+ * The _usePrefixMatch/_useGreaterThan flag is used to determine if a
+ * prefix match of an exact match should be performed
+ * if _isCompound, must match _rest also.
+ */
+ public boolean match(VersionID vid) {
+ if (_isCompound) {
+ if (!_rest.match(vid)) {
+ return false;
+ }
+ }
+ return (_usePrefixMatch) ? this.isPrefixMatchTuple(vid) :
+ (_useGreaterThan) ? vid.isGreaterThanOrEqualTuple(this) :
+ matchTuple(vid);
+ }
+
+ /** Compares if two version IDs are equal */
+ @Override
+ public boolean equals(Object o) {
+ if (matchTuple(o)) {
+ VersionID ov = (VersionID) o;
+ if (_rest == null || _rest.equals(ov._rest)) {
+ if ((_useGreaterThan == ov._useGreaterThan) &&
+ (_usePrefixMatch == ov._usePrefixMatch)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /** Computes a hash code for a VersionID */
+ @Override
+ public int hashCode() {
+ boolean first = true;
+ int hashCode = 0;
+ for (String tuple : _tuple) {
+ if (first) {
+ first = false;
+ hashCode = tuple.hashCode();
+ } else {
+ hashCode = hashCode ^ tuple.hashCode();
+ }
+ }
+ return hashCode;
+ }
+
+ /** Compares if two version IDs are equal */
+ private boolean matchTuple(Object o) {
+ // Check for null and type
+ if (o == null || !(o instanceof VersionID)) {
+ return false;
+ }
+ VersionID vid = (VersionID) o;
+
+ // Normalize arrays
+ String[] t1 = normalize(_tuple, vid._tuple.length);
+ String[] t2 = normalize(vid._tuple, _tuple.length);
+
+ // Check contents
+ for (int i = 0; i < t1.length; i++) {
+ Object o1 = getValueAsObject(t1[i]);
+ Object o2 = getValueAsObject(t2[i]);
+ if (!o1.equals(o2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private Object getValueAsObject(String value) {
+ if (value.length() > 0 && value.charAt(0) != '-') {
+ try {
+ return Integer.valueOf(value);
+ } catch (NumberFormatException nfe) {
+ /* fall through */
+ }
+ }
+ return value;
+ }
+
+ public boolean isGreaterThan(VersionID vid) {
+ if (vid == null) {
+ return false;
+ }
+ return isGreaterThanOrEqualHelper(vid, false, true);
+ }
+
+ public boolean isGreaterThanOrEqual(VersionID vid) {
+ if (vid == null) {
+ return false;
+ }
+ return isGreaterThanOrEqualHelper(vid, true, true);
+ }
+
+ boolean isGreaterThanOrEqualTuple(VersionID vid) {
+ return isGreaterThanOrEqualHelper(vid, true, false);
+ }
+
+ /** Compares if 'this' is greater than vid */
+ private boolean isGreaterThanOrEqualHelper(VersionID vid,
+ boolean allowEqual, boolean useRest) {
+
+ if (useRest && _isCompound) {
+ if (!_rest.isGreaterThanOrEqualHelper(vid, allowEqual, true)) {
+ return false;
+ }
+ }
+ // Normalize the two strings
+ String[] t1 = normalize(_tuple, vid._tuple.length);
+ String[] t2 = normalize(vid._tuple, _tuple.length);
+
+ for (int i = 0; i < t1.length; i++) {
+ // Compare current element
+ Object e1 = getValueAsObject(t1[i]);
+ Object e2 = getValueAsObject(t2[i]);
+ if (e1.equals(e2)) {
+ // So far so good
+ } else {
+ if (e1 instanceof Integer && e2 instanceof Integer) {
+ // if both can be parsed as ints, compare ints
+ return ((Integer)e1).intValue() > ((Integer)e2).intValue();
+ } else {
+ if (e1 instanceof Integer) {
+ return false; // e1 (numeric) < e2 (non-numeric)
+ } else if (e2 instanceof Integer) {
+ return true; // e1 (non-numeric) > e2 (numeric)
+ }
+
+ String s1 = t1[i];
+ String s2 = t2[i];
+
+ return s1.compareTo(s2) > 0;
+ }
+
+ }
+ }
+ // If we get here, they are equal
+ return allowEqual;
+ }
+
+ /** Checks if 'this' is a prefix of vid */
+ private boolean isPrefixMatchTuple(VersionID vid) {
+
+ // Make sure that vid is at least as long as the prefix
+ String[] t2 = normalize(vid._tuple, _tuple.length);
+
+ for (int i = 0; i < _tuple.length; i++) {
+ Object e1 = _tuple[i];
+ Object e2 = t2[i];
+ if (e1.equals(e2)) {
+ // So far so good
+ } else {
+ // Not a prefix
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Normalize an array to a certain lengh */
+ private String[] normalize(String[] list, int minlength) {
+ if (list.length < minlength) {
+ // Need to do padding
+ String[] newlist = new String[minlength];
+ System.arraycopy(list, 0, newlist, 0, list.length);
+ Arrays.fill(newlist, list.length, newlist.length, "0");
+ return newlist;
+ } else {
+ return list;
+ }
+ }
+
+ @Override
+ public int compareTo(VersionID o) {
+ if (o == null || !(o instanceof VersionID)) {
+ return -1;
+ }
+ VersionID vid = o;
+ return equals(vid) ? 0 : (isGreaterThanOrEqual(vid) ? 1 : -1);
+ }
+
+ /** Show it as a string */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < _tuple.length - 1; i++) {
+ sb.append(_tuple[i]);
+ sb.append('.');
+ }
+ if (_tuple.length > 0) {
+ sb.append(_tuple[_tuple.length - 1]);
+ }
+ if (_useGreaterThan) {
+ sb.append('+');
+ }
+ if (_usePrefixMatch) {
+ sb.append('*');
+ }
+ if (_isCompound) {
+ sb.append("&");
+ sb.append(_rest);
+ }
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/VersionString.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+/*
+ * Utility class that knows to handle version strings
+ * A version string is of the form:
+ *
+ * (version-id ('+'?) ' ') *
+ *
+ */
+public class VersionString {
+ private final ArrayList<VersionID> _versionIds;
+
+ /** Constructs a VersionString object from string */
+ public VersionString(String vs) {
+ _versionIds = new ArrayList<>();
+ if (vs != null) {
+ StringTokenizer st = new StringTokenizer(vs, " ", false);
+ while (st.hasMoreElements()) {
+ // Note: The VersionID class takes care of a postfixed '+'
+ _versionIds.add(new VersionID(st.nextToken()));
+ }
+ }
+ }
+
+ public VersionString(VersionID id) {
+ _versionIds = new ArrayList<>();
+ if (id != null) {
+ _versionIds.add(id);
+ }
+ }
+
+ public boolean isSimpleVersion() {
+ if (_versionIds.size() == 1) {
+ return _versionIds.get(0).isSimpleVersion();
+ }
+ return false;
+ }
+
+ /** Check if this VersionString object contains the VersionID m */
+ public boolean contains(VersionID m) {
+ for (int i = 0; i < _versionIds.size(); i++) {
+ VersionID vi = _versionIds.get(i);
+ boolean check = vi.match(m);
+ if (check) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Check if this VersionString object contains the VersionID m, given as a string */
+ public boolean contains(String versionid) {
+ return contains(new VersionID(versionid));
+ }
+
+ /** Check if this VersionString object contains anything greater than m */
+ public boolean containsGreaterThan(VersionID m) {
+ for (int i = 0; i < _versionIds.size(); i++) {
+ VersionID vi = _versionIds.get(i);
+ boolean check = vi.isGreaterThan(m);
+ if (check) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Check if this VersionString object contains anything greater than the VersionID m, given as a string */
+ public boolean containsGreaterThan(String versionid) {
+ return containsGreaterThan(new VersionID(versionid));
+ }
+
+ /** Check if the versionString 'vs' contains the VersionID 'vi' */
+ public static boolean contains(String vs, String vi) {
+ return (new VersionString(vs)).contains(vi);
+ }
+
+ /** Pretty-print object */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < _versionIds.size(); i++) {
+ sb.append(_versionIds.get(i).toString());
+ sb.append(' ');
+ }
+ return sb.toString();
+ }
+
+ public List<VersionID> getAllVersionIDs() {
+ return _versionIds;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/XMLFormat.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.ArrayList;
+import jnlp.converter.JNLPConverter;
+import jnlp.converter.parser.exception.MissingFieldException;
+import jnlp.converter.parser.exception.BadFieldException;
+import jnlp.converter.parser.exception.JNLParseException;
+import jnlp.converter.parser.xml.XMLEncoding;
+import jnlp.converter.parser.xml.XMLParser;
+import jnlp.converter.parser.xml.XMLNode;
+import jnlp.converter.parser.JNLPDesc.AssociationDesc;
+import jnlp.converter.parser.JNLPDesc.IconDesc;
+import jnlp.converter.parser.JNLPDesc.InformationDesc;
+import jnlp.converter.parser.JNLPDesc.ShortcutDesc;
+import jnlp.converter.parser.ResourcesDesc.JARDesc;
+import jnlp.converter.parser.ResourcesDesc.JREDesc;
+import jnlp.converter.Log;
+import jnlp.converter.parser.ResourcesDesc.ExtensionDesc;
+import jnlp.converter.parser.ResourcesDesc.PropertyDesc;
+import org.xml.sax.SAXParseException;
+
+public class XMLFormat {
+
+ public static XMLNode parseBits(byte[] bits) throws JNLParseException {
+ return parse(decode(bits));
+ }
+
+ private static String decode(byte[] bits) throws JNLParseException {
+ try {
+ return XMLEncoding.decodeXML(bits);
+ } catch (Exception e) {
+ throw new JNLParseException(e,
+ "exception determining encoding of jnlp file", 0);
+ }
+ }
+
+ private static XMLNode parse(String source) throws JNLParseException {
+ try {
+ return (new XMLParser(source).parse());
+ } catch (SAXParseException spe) {
+ throw new JNLParseException(spe,
+ "exception parsing jnlp file", spe.getLineNumber());
+ } catch (Exception e) {
+ throw new JNLParseException(e,
+ "exception parsing jnlp file", 0);
+ }
+ }
+
+ /**
+ * thisCodebase, if set, is used to determine the codebase,
+ * if JNLP codebase is not absolute.
+ *
+ * @param thisCodebase base URL of this JNLPDesc location
+ */
+ public static JNLPDesc parse(byte[] bits, URL thisCodebase, String jnlp)
+ throws Exception {
+
+ JNLPDesc jnlpd = new JNLPDesc();
+ String source = decode(bits).trim();
+ XMLNode root = parse(source);
+
+ if (root == null || root.getName() == null) {
+ throw new JNLParseException(null, null, 0);
+ }
+
+ // Check that root element is a <jnlp> tag
+ if (!root.getName().equals("jnlp")) {
+ throw (new MissingFieldException(source, "<jnlp>"));
+ }
+
+ // Read <jnlp> attributes (path is empty, i.e., "")
+ // (spec, version, codebase, href)
+ String specVersion = XMLUtils.getAttribute(root, "", "spec", "1.0+");
+ jnlpd.setSpecVersion(specVersion);
+ String version = XMLUtils.getAttribute(root, "", "version");
+ jnlpd.setVersion(version);
+
+ // Make sure the codebase URL ends with a '/'.
+ //
+ // Regarding the JNLP spec,
+ // the thisCodebase is used to determine the codebase.
+ // codebase = new URL(thisCodebase, codebase)
+ URL codebase = GeneralUtil.asPathURL(XMLUtils.getAttributeURL(source,
+ thisCodebase, root, "", "codebase"));
+ if (codebase == null && thisCodebase != null) {
+ codebase = thisCodebase;
+ }
+ jnlpd.setCodebase(codebase.toExternalForm());
+
+ // Get href for JNLP file
+ URL href = XMLUtils.getAttributeURL(source, codebase, root, "", "href");
+ jnlpd.setHref(href.toExternalForm());
+
+ // Read <security> attributes
+ if (XMLUtils.isElementPath(root, "<security><all-permissions>")) {
+ jnlpd.setIsSandbox(false);
+ } else if (XMLUtils.isElementPath(root,
+ "<security><j2ee-application-client-permissions>")) {
+ jnlpd.setIsSandbox(false);
+ }
+
+ // We can be fxapp, and also be applet, or application, or neither
+ boolean isFXApp = false;
+ boolean isApplet = false;
+ if (XMLUtils.isElementPath(root, "<javafx-desc>")) {
+ // no new type for javafx-desc - needs one of the others
+ buildFXAppDesc(source, root, "<javafx-desc>", jnlpd);
+ jnlpd.setIsFXApp(true);
+ isFXApp = true;
+ }
+
+ /*
+ * Note - the jnlp specification says there must be exactly one of
+ * the descriptor types. This code has always violated (or at least
+ * not checked for) that condition.
+ * Instead it uses precedent order app, component, installer, applet
+ * and ignores any other descriptors given.
+ */
+ if (XMLUtils.isElementPath(root, "<application-desc>")) {
+ buildApplicationDesc(source, root, jnlpd);
+ } else if (XMLUtils.isElementPath(root, "<component-desc>")) {
+ jnlpd.setIsLibrary(true);
+ } else if (XMLUtils.isElementPath(root, "<installer-desc>")) {
+ Log.warning("<installer-desc> is not supported and will be ignored in " + jnlp);
+ jnlpd.setIsInstaller(true);
+ } else if (XMLUtils.isElementPath(root, "<applet-desc>")) {
+ isApplet = true;
+ } else {
+ if (!isFXApp) {
+ throw (new MissingFieldException(source,
+ "<jnlp>(<application-desc>|<applet-desc>|" +
+ "<installer-desc>|<component-desc>)"));
+ }
+ }
+
+ if (isApplet && !isFXApp) {
+ Log.error("Applet based applications deployed with <applet-desc> element are not supported.");
+ }
+
+ if (!jnlpd.isLibrary() && !jnlpd.isInstaller()) {
+ buildInformationDesc(source, codebase, root, jnlpd);
+ }
+
+ if (!jnlpd.isInstaller()) {
+ buildResourcesDesc(source, codebase, root, false, jnlpd);
+ }
+
+ if (!jnlpd.isLibrary() && !jnlpd.isInstaller()) {
+ jnlpd.parseResourceDesc();
+ }
+
+ if (!jnlpd.isInstaller()) {
+ if (jnlpd.isSandbox()) {
+ if (jnlpd.isLibrary()) {
+ Log.warning(jnlp + " is sandbox extension. JNLPConverter does not support sandbox environment and converted application will run without security manager.");
+ } else {
+ Log.warning("This is sandbox Web-Start application. JNLPConverter does not support sandbox environment and converted application will run without security manager.");
+ }
+ }
+ }
+
+ return jnlpd;
+ }
+
+ /**
+ * Create a combine informationDesc in the two informationDesc.
+ * The information present in id1 overwrite the information present in id2
+ */
+ private static InformationDesc combineInformationDesc(
+ InformationDesc id1, InformationDesc id2) {
+ if (id1 == null) {
+ return id2;
+ }
+ if (id2 == null) {
+ return id1;
+ }
+
+ String t1 = id1.getTitle();
+ String title = (t1 != null && t1.length() > 0) ?
+ t1 : id2.getTitle();
+ String v1 = id1.getVendor();
+ String vendor = (v1 != null && v1.length() > 0) ?
+ v1 : id2.getVendor();
+
+ /** Copy descriptions */
+ String[] descriptions = new String[InformationDesc.NOF_DESC];
+ for (int i = 0; i < descriptions.length; i++) {
+ descriptions[i] = (id1.getDescription(i) != null)
+ ? id1.getDescription(i) : id2.getDescription(i);
+ }
+
+ /** Icons */
+ ArrayList<IconDesc> iconList = new ArrayList<>();
+ if (id2.getIcons() != null) {
+ iconList.addAll(Arrays.asList(id2.getIcons()));
+ }
+ if (id1.getIcons() != null) {
+ iconList.addAll(Arrays.asList(id1.getIcons()));
+ }
+ IconDesc[] icons = new IconDesc[iconList.size()];
+ icons = iconList.toArray(icons);
+
+ ShortcutDesc hints = (id1.getShortcut() != null) ?
+ id1.getShortcut() : id2.getShortcut();
+
+ AssociationDesc[] asd = ( AssociationDesc[] ) addArrays(
+ (Object[])id1.getAssociations(), (Object[])id2.getAssociations());
+
+ return new InformationDesc(title,
+ vendor,
+ descriptions,
+ icons,
+ hints,
+ asd);
+ }
+
+ /** Extract data from <information> tag */
+ private static void buildInformationDesc(final String source, final URL codebase, XMLNode root, JNLPDesc jnlpd)
+ throws MissingFieldException, BadFieldException {
+ final ArrayList<InformationDesc> list = new ArrayList<>();
+
+ // Iterates over all <information> nodes ignoring the type
+ XMLUtils.visitElements(root,
+ "<information>", new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e) throws
+ BadFieldException, MissingFieldException {
+
+ // Check for right os, arch, and locale
+ String[] os = GeneralUtil.getStringList(
+ XMLUtils.getAttribute(e, "", "os", null));
+ String[] arch = GeneralUtil.getStringList(
+ XMLUtils.getAttribute(e, "", "arch", null));
+ String[] locale = GeneralUtil.getStringList(
+ XMLUtils.getAttribute(e, "", "locale", null));
+ if (GeneralUtil.prefixMatchStringList(
+ os, GeneralUtil.getOSFullName()) &&
+ GeneralUtil.prefixMatchArch(arch) &&
+ matchDefaultLocale(locale))
+ {
+ // Title, vendor
+ String title = XMLUtils.getElementContents(e, "<title>");
+ String vendor = XMLUtils.getElementContents(e, "<vendor>");
+
+ // Descriptions
+ String[] descriptions =
+ new String[InformationDesc.NOF_DESC];
+ descriptions[InformationDesc.DESC_DEFAULT] =
+ XMLUtils.getElementContentsWithAttribute(
+ e, "<description>", "kind", "", null);
+ descriptions[InformationDesc.DESC_ONELINE] =
+ XMLUtils.getElementContentsWithAttribute(
+ e, "<description>", "kind", "one-line", null);
+ descriptions[InformationDesc.DESC_SHORT] =
+ XMLUtils.getElementContentsWithAttribute(
+ e, "<description>", "kind", "short", null);
+ descriptions[InformationDesc.DESC_TOOLTIP] =
+ XMLUtils.getElementContentsWithAttribute(
+ e, "<description>", "kind", "tooltip", null);
+
+ // Icons
+ IconDesc[] icons = getIconDescs(source, codebase, e);
+
+ // Shortcut hints
+ ShortcutDesc shortcuts = getShortcutDesc(e);
+
+ // Association hints
+ AssociationDesc[] associations = getAssociationDesc(
+ source, codebase, e);
+
+ list.add(new InformationDesc(
+ title, vendor, descriptions, icons,
+ shortcuts, associations));
+ }
+ }
+ });
+
+ /* Combine all information desc. information in a single one for
+ * the current locale using the following priorities:
+ * 1. locale == language_country_variant
+ * 2. locale == lauguage_country
+ * 3. locale == lauguage
+ * 4. no or empty locale
+ */
+ InformationDesc normId = new InformationDesc(null, null, null, null, null, null);
+ for (InformationDesc id : list) {
+ normId = combineInformationDesc(id, normId);
+ }
+
+ jnlpd.setTitle(normId.getTitle());
+ jnlpd.setVendor(normId.getVendor());
+ jnlpd.setDescriptions(normId.getDescription());
+ jnlpd.setIcons(normId.getIcons());
+ jnlpd.setShortcuts(normId.getShortcut());
+ jnlpd.setAssociations(normId.getAssociations());
+ }
+
+ private static Object[] addArrays (Object[] a1, Object[] a2) {
+ if (a1 == null) {
+ return a2;
+ }
+ if (a2 == null) {
+ return a1;
+ }
+ ArrayList<Object> list = new ArrayList<>();
+ int i;
+ for (i=0; i<a1.length; list.add(a1[i++]));
+ for (i=0; i<a2.length; list.add(a2[i++]));
+ return list.toArray(a1);
+ }
+
+ public static boolean matchDefaultLocale(String[] localeStr) {
+ return GeneralUtil.matchLocale(localeStr, GeneralUtil.getDefaultLocale());
+ }
+
+ /** Extract data from <resources> tag. There is only one. */
+ static void buildResourcesDesc(final String source,
+ final URL codebase, XMLNode root, final boolean ignoreJres, JNLPDesc jnlpd)
+ throws MissingFieldException, BadFieldException {
+ // Extract classpath directives
+ final ResourcesDesc rdesc = new ResourcesDesc();
+
+ // Iterate over all entries
+ XMLUtils.visitElements(root, "<resources>",
+ new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e)
+ throws MissingFieldException, BadFieldException {
+ // Check for right os, archictecture, and locale
+ String[] os = GeneralUtil.getStringList(
+ XMLUtils.getAttribute(e, "", "os", null));
+ final String arch = XMLUtils.getAttribute(e, "", "arch", null);
+ String[] locale = GeneralUtil.getStringList(
+ XMLUtils.getAttribute(e, "", "locale", null));
+ if (GeneralUtil.prefixMatchStringList(
+ os, GeneralUtil.getOSFullName())
+ && matchDefaultLocale(locale)) {
+ // Now visit all children in this node
+ XMLUtils.visitChildrenElements(e,
+ new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e2)
+ throws MissingFieldException, BadFieldException {
+ handleResourceElement(source, codebase,
+ e2, rdesc, ignoreJres, arch, jnlpd);
+ }
+ });
+ }
+ }
+ });
+
+ if (!rdesc.isEmpty()) {
+ jnlpd.setResourcesDesc(rdesc);
+ }
+ }
+
+ private static IconDesc[] getIconDescs(final String source,
+ final URL codebase, XMLNode e)
+ throws MissingFieldException, BadFieldException {
+ final ArrayList<IconDesc> answer = new ArrayList<>();
+ XMLUtils.visitElements(e, "<icon>", new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode icon) throws
+ MissingFieldException, BadFieldException {
+ String kindStr = XMLUtils.getAttribute(icon, "", "kind", "");
+ URL href = XMLUtils.getRequiredURL(source, codebase, icon, "", "href");
+
+ if (href != null) {
+ if (!JNLPConverter.isIconSupported(href.toExternalForm())) {
+ return;
+ }
+ }
+
+ int kind;
+ if (kindStr == null || kindStr.isEmpty() || kindStr.equals("default")) {
+ kind = IconDesc.ICON_KIND_DEFAULT;
+ } else if (kindStr.equals("shortcut")) {
+ kind = IconDesc.ICON_KIND_SHORTCUT;
+ } else {
+ Log.warning("Ignoring unsupported icon \"" + href + "\" with kind \"" + kindStr + "\".");
+ return;
+ }
+
+ answer.add(new IconDesc(href, kind));
+ }
+ });
+ return answer.toArray(new IconDesc[answer.size()]);
+ }
+
+ private static ShortcutDesc getShortcutDesc(XMLNode e)
+ throws MissingFieldException, BadFieldException {
+ final ArrayList<ShortcutDesc> shortcuts = new ArrayList<>();
+
+ XMLUtils.visitElements(e, "<shortcut>", new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode shortcutNode)
+ throws MissingFieldException, BadFieldException {
+ boolean desktopHinted =
+ XMLUtils.isElementPath(shortcutNode, "<desktop>");
+ boolean menuHinted =
+ XMLUtils.isElementPath(shortcutNode, "<menu>");
+ String submenuHinted =
+ XMLUtils.getAttribute(shortcutNode, "<menu>", "submenu");
+ shortcuts.add(new ShortcutDesc(desktopHinted, menuHinted, submenuHinted));
+ }
+ });
+
+ if (shortcuts.size() > 0) {
+ return shortcuts.get(0);
+ }
+ return null;
+ }
+
+ private static AssociationDesc[] getAssociationDesc(final String source,
+ final URL codebase, XMLNode e)
+ throws MissingFieldException, BadFieldException {
+ final ArrayList<AssociationDesc> answer = new ArrayList<>();
+ XMLUtils.visitElements(e, "<association>",
+ new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode node)
+ throws MissingFieldException, BadFieldException {
+
+ String extensions = XMLUtils.getAttribute(
+ node, "", "extensions");
+
+ String mimeType = XMLUtils.getAttribute(
+ node, "", "mime-type");
+ String description = XMLUtils.getElementContents(
+ node, "<description>");
+
+ URL icon = XMLUtils.getAttributeURL(
+ source, codebase, node, "<icon>", "href");
+
+ if (!JNLPConverter.isIconSupported(icon.toExternalForm())) {
+ icon = null;
+ }
+
+ if (extensions == null && mimeType == null) {
+ throw new MissingFieldException(source,
+ "<association>(<extensions><mime-type>)");
+ } else if (extensions == null) {
+ throw new MissingFieldException(source,
+ "<association><extensions>");
+ } else if (mimeType == null) {
+ throw new MissingFieldException(source,
+ "<association><mime-type>");
+ }
+
+ // don't support uppercase extension and mime-type on gnome.
+ if ("gnome".equals(System.getProperty("sun.desktop"))) {
+ extensions = extensions.toLowerCase();
+ mimeType = mimeType.toLowerCase();
+ }
+
+ answer.add(new AssociationDesc(extensions, mimeType,
+ description, icon));
+ }
+ });
+ return answer.toArray(
+ new AssociationDesc[answer.size()]);
+ }
+
+ /** Handle the individual entries in a resource desc */
+ private static void handleResourceElement(String source, URL codebase,
+ XMLNode e, ResourcesDesc rdesc, boolean ignoreJres, String arch, JNLPDesc jnlpd)
+ throws MissingFieldException, BadFieldException {
+
+ String tag = e.getName();
+
+ boolean matchArch = GeneralUtil.prefixMatchArch(
+ GeneralUtil.getStringList(arch));
+
+
+ if (matchArch && (tag.equals("jar") || tag.equals("nativelib"))) {
+ /*
+ * jar/nativelib elements
+ */
+ URL href = XMLUtils.getRequiredURL(source, codebase, e, "", "href");
+ String version = XMLUtils.getAttribute(e, "", "version", null);
+
+ String mainStr = XMLUtils.getAttribute(e, "", "main");
+ boolean isNativeLib = tag.equals("nativelib");
+
+ boolean isMain = "true".equalsIgnoreCase(mainStr);
+
+ JARDesc jd = new JARDesc(href, version, isMain, isNativeLib, rdesc);
+ rdesc.addResource(jd);
+ } else if (matchArch && tag.equals("property")) {
+ /*
+ * property tag
+ */
+ String name = XMLUtils.getRequiredAttribute(source, e, "", "name");
+ String value = XMLUtils.getRequiredAttributeEmptyOK(
+ source, e, "", "value");
+
+ rdesc.addResource(new PropertyDesc(name, value));
+ } else if (matchArch && tag.equals("extension")) {
+ URL href = XMLUtils.getRequiredURL(source, codebase, e, "", "href");
+ String version = XMLUtils.getAttribute(e, "", "version", null);
+ rdesc.addResource(new ExtensionDesc(href, version));
+ } else if ((tag.equals("java") || tag.equals("j2se")) && !ignoreJres) {
+ /*
+ * j2se element
+ */
+ String version =
+ XMLUtils.getRequiredAttribute(source, e, "", "version");
+ String minheapstr =
+ XMLUtils.getAttribute(e, "", "initial-heap-size");
+ String maxheapstr =
+ XMLUtils.getAttribute(e, "", "max-heap-size");
+
+ String vmargs =
+ XMLUtils.getAttribute(e, "", "java-vm-args");
+
+ if (jnlpd.isJRESet()) {
+ if (vmargs == null) {
+ vmargs = "none";
+ }
+ Log.warning("Ignoring repeated element <" + tag + "> with version " + version +
+ " and java-vm-args: " + vmargs);
+ return;
+ }
+
+ long minheap = GeneralUtil.heapValToLong(minheapstr);
+ long maxheap = GeneralUtil.heapValToLong(maxheapstr);
+
+ ResourcesDesc cbs = null;
+ buildResourcesDesc(source, codebase, e, true, null);
+
+ // JRE
+ JREDesc jreDesc = new JREDesc(
+ version,
+ minheap,
+ maxheap,
+ vmargs,
+ cbs,
+ arch);
+
+ rdesc.addResource(jreDesc);
+
+ jnlpd.setIsJRESet(true);
+ }
+ }
+
+ /** Extract data from the application-desc tag */
+ private static void buildApplicationDesc(final String source,
+ XMLNode root, JNLPDesc jnlpd) throws MissingFieldException, BadFieldException {
+
+ String mainclass = XMLUtils.getClassName(source, root,
+ "<application-desc>", "main-class", false);
+ String appType = XMLUtils.getAttribute(root, "<application-desc>",
+ "type", "Java");
+ String progressclass = XMLUtils.getClassName(source, root,
+ "<application-desc>", "progress-class", false);
+ if (progressclass != null && !progressclass.isEmpty()) {
+ Log.warning("JNLPConverter does not support progress indication. \"" + progressclass + "\" will not be loaded and will be ignored.");
+ }
+
+ if (!("Java".equalsIgnoreCase(appType) ||
+ "JavaFx".equalsIgnoreCase(appType))) {
+ throw new BadFieldException(source, XMLUtils.getPathString(root) +
+ "<application-desc>type", appType);
+ }
+
+ if ("JavaFx".equalsIgnoreCase(appType)) {
+ jnlpd.setIsFXApp(true);
+ }
+
+ XMLUtils.visitElements(root, "<application-desc><argument>", new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e) throws MissingFieldException, BadFieldException {
+ String arg = XMLUtils.getElementContents(e, "", null);
+ if (arg == null) {
+ throw new BadFieldException(source, XMLUtils.getPathString(e), "");
+ }
+ jnlpd.addArguments(arg);
+ }
+ });
+
+ XMLUtils.visitElements(root, "<application-desc><param>",
+ new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e) throws MissingFieldException,
+ BadFieldException {
+ String pn = XMLUtils.getRequiredAttribute(
+ source, e, "", "name");
+ String pv = XMLUtils.getRequiredAttributeEmptyOK(
+ source, e, "", "value");
+ jnlpd.setProperty(pn, pv);
+ }
+ });
+ jnlpd.setMainClass(mainclass, false);
+ }
+
+ /** Extract data from the javafx-desc tag */
+ private static void buildFXAppDesc(final String source,
+ XMLNode root, String element, JNLPDesc jnlpd)
+ throws MissingFieldException, BadFieldException {
+ String mainclass = XMLUtils.getClassName(source, root, element,
+ "main-class", true);
+ String name = XMLUtils.getRequiredAttribute(source, root,
+ "<javafx-desc>", "name");
+
+ /* extract arguments */
+ XMLUtils.visitElements(root, "<javafx-desc><argument>", new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e) throws MissingFieldException, BadFieldException {
+ String arg = XMLUtils.getElementContents(e, "", null);
+ if (arg == null) {
+ throw new BadFieldException(source, XMLUtils.getPathString(e), "");
+ }
+ jnlpd.addArguments(arg);
+ }
+ });
+
+ /* extract parameters */
+ XMLUtils.visitElements(root, "<javafx-desc><param>",
+ new XMLUtils.ElementVisitor() {
+ @Override
+ public void visitElement(XMLNode e) throws MissingFieldException,
+ BadFieldException {
+ String pn = XMLUtils.getRequiredAttribute(
+ source, e, "", "name");
+ String pv = XMLUtils.getRequiredAttributeEmptyOK(
+ source, e, "", "value");
+ jnlpd.setProperty(pn, pv);
+ }
+ });
+
+ jnlpd.setMainClass(mainclass, true);
+ jnlpd.setName(name);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/XMLUtils.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser;
+
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import jnlp.converter.parser.exception.BadFieldException;
+import jnlp.converter.parser.exception.MissingFieldException;
+import jnlp.converter.parser.xml.XMLNode;
+
+/** Contains handy methods for looking up information
+ * stored in XMLNodes.
+ */
+public class XMLUtils {
+
+ /** Returns the value of an integer attribute */
+ public static int getIntAttribute(String source, XMLNode root, String path, String name, int defaultvalue)
+ throws BadFieldException {
+ String value = getAttribute(root, path, name);
+ if (value == null) {
+ return defaultvalue;
+ }
+
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException nfe) {
+ throw new BadFieldException(source, getPathString(root) + path + name, value);
+ }
+ }
+
+ /** Returns the value of a given attribute, or null if not set */
+ public static String getAttribute(XMLNode root, String path, String name)
+ throws BadFieldException {
+ return getAttribute(root, path, name, null);
+ }
+
+ /** Returns the value of a given attribute */
+ public static String getRequiredAttributeEmptyOK(String source,
+ XMLNode root, String path, String name) throws MissingFieldException {
+ String value = null;
+ XMLNode elem = findElementPath(root, path);
+ if (elem != null) {
+ value = elem.getAttribute(name);
+ }
+ if (value == null) {
+ throw new MissingFieldException(source,
+ getPathString(root)+ path + name);
+ }
+ return value;
+ }
+
+ /*** Returns the value of an attribute, which must be a valid class name */
+ public static String getClassName(String source, XMLNode root,
+ String path, String name, boolean required)
+ throws BadFieldException, MissingFieldException {
+
+ String className;
+ if (required) {
+ className = getRequiredAttribute(source, root, path, name);
+ } else {
+ className = getAttribute(root, path, name);
+ }
+ if (className != null && className.endsWith(".class")) {
+ int i = className.lastIndexOf(".class");
+ String cname = className.substring(0, i);
+ return cname;
+ }
+ return className;
+ }
+
+ /** Returns the value of a given attribute, or null if not set */
+ public static String getRequiredAttribute(String source, XMLNode root,
+ String path, String name) throws MissingFieldException, BadFieldException {
+ String s = getAttribute(root, path, name, null);
+ if (s == null) {
+ throw new MissingFieldException(source, getPathString(root) + path + name);
+ }
+ s = s.trim();
+ return (s.length() == 0) ? null : s;
+ }
+
+ /** Returns the value of a given attribute, or the default value 'def' if not set */
+ public static String getAttribute(XMLNode root, String path, String name,
+ String def) throws BadFieldException {
+ XMLNode elem = findElementPath(root, path);
+ if (elem == null) {
+ return def;
+ }
+ String value = elem.getAttribute(name);
+ return (value == null || value.length() == 0) ? def : value;
+ }
+
+ /** Expands a URL into an absolute URL from a relative URL */
+ public static URL getAttributeURL(String source, URL base, XMLNode root, String path, String name) throws BadFieldException {
+ String value = getAttribute(root, path, name);
+ if (value == null) return null;
+ try {
+ if (value.startsWith("jar:")) {
+ int bang = value.indexOf("!/");
+ if (bang > 0) {
+ String entry = value.substring(bang);
+ String urlString = value.substring(4, bang);
+ URL url = (base == null) ?
+ new URL(urlString) : new URL(base, urlString);
+ return new URL("jar:" + url.toString() + entry);
+ }
+ }
+ return (base == null) ? new URL(value) : new URL(base, value);
+ } catch(MalformedURLException mue) {
+ if (mue.getMessage().contains("https")) {
+ throw new BadFieldException(source, "<jnlp>", "https");
+ }
+ throw new BadFieldException(source, getPathString(root) + path + name, value);
+ }
+ }
+
+ /** Returns the value of an attribute as a URL or null if not set */
+ public static URL getAttributeURL(String source, XMLNode root, String path, String name) throws BadFieldException {
+ return getAttributeURL(source, null, root, path, name);
+ }
+
+ public static URL getRequiredURL(String source, URL base, XMLNode root, String path, String name) throws BadFieldException, MissingFieldException {
+ URL url = getAttributeURL(source, base, root, path, name);
+ if (url == null) {
+ throw new MissingFieldException(source, getPathString(root) + path + name);
+ }
+ return url;
+ }
+
+ /** Returns the value of an attribute as a URL. Throws a MissingFieldException if the
+ * attribute is not defined
+ */
+ public static URL getRequiredURL(String source, XMLNode root, String path, String name) throws BadFieldException, MissingFieldException {
+ return getRequiredURL(source, null, root, path, name);
+ }
+
+ /** Returns true if the path exists in the document, otherwise false */
+ public static boolean isElementPath(XMLNode root, String path) {
+ return findElementPath(root, path) != null;
+ }
+
+ public static URL getElementURL(String source, XMLNode root, String path) throws BadFieldException {
+ String value = getElementContents(root, path);
+ try {
+ return new URL(value);
+ } catch(MalformedURLException mue) {
+ throw new BadFieldException(source, getPathString(root) + path, value);
+ }
+ }
+
+ /** Returns a string describing the current location in the DOM */
+ public static String getPathString(XMLNode e) {
+ return (e == null || !(e.isElement())) ? "" : getPathString(e.getParent()) + "<" + e.getName() + ">";
+ }
+
+ /** Returns the contents of an element with the given path and an attribute matching a specific value. Returns
+ * NULL if not found
+ */
+ public static String getElementContentsWithAttribute(XMLNode root, String path, String attr, String val, String defaultvalue)
+ throws BadFieldException, MissingFieldException {
+ XMLNode e = getElementWithAttribute(root, path, attr, val);
+ if (e == null) {
+ return defaultvalue;
+ }
+ return getElementContents(e, "", defaultvalue);
+ }
+
+ public static URL getAttributeURLWithAttribute(String source, XMLNode root, String path, String attrcond, String val,
+ String name, URL defaultvalue)
+ throws BadFieldException, MissingFieldException {
+ XMLNode e = getElementWithAttribute(root, path, attrcond, val);
+ if (e == null) {
+ return defaultvalue;
+ }
+ URL url = getAttributeURL(source, e, "", name);
+ if (url == null) {
+ return defaultvalue;
+ }
+ return url;
+ }
+
+ /** Returns an element with the given path and an attribute matching a specific value. Returns
+ * NULL if not found
+ */
+ public static XMLNode getElementWithAttribute(XMLNode root, String path, final String attr, final String val)
+ throws BadFieldException, MissingFieldException {
+ final XMLNode[] result = {null};
+ visitElements(root, path, new ElementVisitor() {
+ public void visitElement(XMLNode e) throws BadFieldException, MissingFieldException {
+ if (result[0] == null && e.getAttribute(attr).equals(val)) {
+ result[0] = e;
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /** Like getElementContents(...) but with a defaultValue of null */
+ public static String getElementContents(XMLNode root, String path) {
+ return getElementContents(root, path, null);
+ }
+
+ /** Returns the value of the last element tag in the path, e.g., <..><tag>value</tag>. The DOM is assumes
+ * to be normalized. If no value is found, the defaultvalue is returned
+ */
+ public static String getElementContents(XMLNode root, String path, String defaultvalue) {
+ XMLNode e = findElementPath(root, path);
+ if (e == null) {
+ return defaultvalue;
+ }
+ XMLNode n = e.getNested();
+ if (n != null && !n.isElement()) {
+ return n.getName();
+ }
+ return defaultvalue;
+ }
+
+ /** Parses a path string of the form <tag1><tag2><tag3> and returns the specific Element
+ * node for that tag, or null if it does not exist. If multiple elements exists with same
+ * path the first is returned
+ */
+ public static XMLNode findElementPath(XMLNode elem, String path) {
+ // End condition. Root null -> path does not exist
+ if (elem == null) {
+ return null;
+ }
+
+ // End condition. String empty, return current root
+ if (path == null || path.length() == 0) {
+ return elem;
+ }
+
+ // Strip of first tag
+ int idx = path.indexOf('>');
+ if (!(path.charAt(0) == '<')) {
+ throw new IllegalArgumentException("bad path. Missing begin tag");
+ }
+ if (idx == -1) {
+ throw new IllegalArgumentException("bad path. Missing end tag");
+ }
+ String head = path.substring(1, idx);
+ String tail = path.substring(idx + 1);
+ return findElementPath(findChildElement(elem, head), tail);
+ }
+
+ /** Returns an child element with the current tag name or null. */
+ public static XMLNode findChildElement(XMLNode elem, String tag) {
+ XMLNode n = elem.getNested();
+ while (n != null) {
+ if (n.isElement() && n.getName().equals(tag)) {
+ return n;
+ }
+ n = n.getNext();
+ }
+ return null;
+ }
+
+ /** Iterator class */
+ public abstract static class ElementVisitor {
+ abstract public void visitElement(XMLNode e) throws BadFieldException, MissingFieldException;
+ }
+
+ /** Visits all elements which matches the <path>. The iteration is only
+ * done on the last element in the path.
+ */
+ public static void visitElements(XMLNode root, String path, ElementVisitor ev)
+ throws BadFieldException, MissingFieldException {
+ // Get last element in path
+ int idx = path.lastIndexOf('<');
+ if (idx == -1) {
+ throw new IllegalArgumentException(
+ "bad path. Must contain atleast one tag");
+ }
+ if (path.length() == 0 || path.charAt(path.length() - 1) != '>') {
+ throw new IllegalArgumentException("bad path. Must end with a >");
+ }
+ String head = path.substring(0, idx);
+ String tag = path.substring(idx + 1, path.length() - 1);
+
+ XMLNode elem = findElementPath(root, head);
+ if (elem == null) {
+ return;
+ }
+
+ // Iterate through all child nodes
+ XMLNode n = elem.getNested();
+ while (n != null) {
+ if (n.isElement() && n.getName().equals(tag)) {
+ ev.visitElement(n);
+ }
+ n = n.getNext();
+ }
+ }
+
+ public static void visitChildrenElements(XMLNode elem, ElementVisitor ev)
+ throws BadFieldException, MissingFieldException {
+ // Iterate through all child nodes
+ XMLNode n = elem.getNested();
+ while (n != null) {
+ if (n.isElement()) {
+ ev.visitElement(n);
+ }
+ n = n.getNext();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/exception/BadFieldException.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.exception;
+
+public class BadFieldException extends Exception {
+
+ private final String _field;
+ private final String _value;
+
+ public BadFieldException(String source, String field, String value) {
+ super();
+ _value = value;
+ _field = field;
+ }
+
+ /**
+ * Returns the name of the offending field
+ */
+ public String getField() {
+ return _field;
+ }
+
+ /**
+ * Returns the value of the offending field
+ */
+ public String getValue() {
+ return _value;
+ }
+
+ /**
+ * toString implementation
+ */
+ @Override
+ public String toString() {
+ return "BadFieldException[ " + getField() + "," + getValue() + "]";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/exception/JNLParseException.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.exception;
+
+/**
+ * Exception thrown if a parse error occurred when interpreting
+ * the launch descriptor
+ */
+
+public class JNLParseException extends Exception {
+
+ private final String _msg;
+ private final int _line;
+
+ public JNLParseException(Exception exception, String msg, int line) {
+ super(exception);
+ _msg = msg;
+ _line = line;
+ }
+
+ @Override
+ public String getMessage() {
+ return _msg;
+ }
+
+ private int getLine() {
+ return _line;
+ }
+
+ @Override
+ public String toString() {
+ return "JNLParseException[ " + getMessage() + "] at " + getLine();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/exception/MissingFieldException.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.exception;
+
+public class MissingFieldException extends Exception {
+
+ private final String _field;
+
+ public MissingFieldException(String source, String field) {
+ super();
+ _field = field;
+ }
+
+ /**
+ * Returns the name of the offending field
+ */
+ private String getField() {
+ return _field;
+ }
+
+ /**
+ * toString implementation
+ */
+ @Override
+ public String toString() {
+ return "MissingFieldException[ " + getField() + "]";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/xml/XMLAttribute.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.xml;
+
+/**
+ * Class that contains information about a specific attribute
+ */
+public class XMLAttribute {
+
+ private final String _name;
+ private final String _value;
+ private XMLAttribute _next;
+
+ public XMLAttribute(String name, String value) {
+ _name = XMLNode.stripNameSpace(name);
+ _value = value;
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public String getValue() {
+ return _value;
+ }
+
+ public XMLAttribute getNext() {
+ return _next;
+ }
+
+ public void setNext(XMLAttribute next) {
+ _next = next;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/xml/XMLEncoding.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+public class XMLEncoding {
+ /**
+ * Decodes a byte stream into a String by testing for a Byte Order Mark
+ * (BOM) or an XML declaration.
+ * <br />
+ * Detection begins by examining the first four octets of the stream for a
+ * BOM. If a BOM is not found, then an encoding declaration is looked for
+ * at the beginning of the stream. If the encoding still can not be
+ * determined at this point, then UTF-8 is assumed.
+ *
+ * @param data an array of bytes containing an encoded XML document.
+ *
+ * @return A string containing the decoded XML document.
+ */
+ public static String decodeXML(byte [] data) throws IOException {
+ int start = 0;
+ String encoding;
+
+ if (data.length < BOM_LENGTH) {
+ throw (new EOFException("encoding.error.not.xml"));
+ }
+ // no else required; successfully read stream
+ int firstFour = ((0xff000000 & ((int) data[0] << 24)) |
+ (0x00ff0000 & ((int) data[1] << 16)) |
+ (0x0000ff00 & ((int) data[2] << 8)) |
+ (0x000000ff & (int) data[3]));
+
+ // start by examining the first four bytes for a BOM
+ switch (firstFour) {
+ case EBCDIC:
+ // examine the encoding declaration
+ encoding = examineEncodingDeclaration(data, IBM037_ENC);
+ break;
+
+ case XML_DECLARATION:
+ // assume UTF-8, but examine the encoding declaration
+ encoding = examineEncodingDeclaration(data, UTF_8_ENC);
+ break;
+
+ case UTF_16BE:
+ encoding = UTF_16BE_ENC;
+ break;
+
+ case UTF_16LE:
+ encoding = UTF_16LE_ENC;
+ break;
+
+ case UNUSUAL_OCTET_1:
+ case UNUSUAL_OCTET_2:
+ throw (new UnsupportedEncodingException("encoding.error.unusual.octet"));
+
+ case UTF_32_BE_BOM:
+ case UTF_32_LE_BOM:
+ encoding = UTF_32_ENC;
+ break;
+
+ default:
+ int firstThree = firstFour & 0xffffff00;
+
+ switch (firstThree) {
+ case UTF_8_BOM:
+ // the InputStreamReader class doen't properly handle
+ // the Byte Order Mark (BOM) in UTF-8 streams, so don't
+ // putback those 3 bytes.
+ start = 3;
+ encoding = UTF_8_ENC;
+ break;
+
+ default:
+ int firstTwo = firstFour & 0xffff0000;
+
+ switch (firstTwo) {
+ case UTF_16_BE_BOM:
+ case UTF_16_LE_BOM:
+ encoding = UTF_16_ENC;
+ break;
+
+ default:
+ // this is probably UTF-8 without the encoding
+ // declaration
+ encoding = UTF_8_ENC;
+ break;
+ }
+ break;
+ }
+ break;
+ }
+
+ return (new String(data, start, data.length - start, encoding));
+ }
+
+ /**
+ * [3] S ::= ( #x20 | #x09 | #x0d | #x0a )
+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+ * [24] VersionInfo ::= S 'version' Eq ( '"' VersionNum '"' |
+ * "'" VersionNum "'" )
+ * [25] Eq ::= S? '=' S?
+ * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
+ * [80] EncodingDecl ::= S 'encoding' Eq ( '"' EncName '"' |
+ * "'" EncName "'" )
+ * [81] EncName ::= [a-zA-Z] ([a-zA-Z0-9_.] | '-')*
+ */
+ private static String examineEncodingDeclaration(byte [] data,
+ String encoding) throws IOException {
+ boolean loop = false;
+ boolean recognized = false;
+ boolean almost = false;
+ boolean question = false;
+ boolean done = false;
+ boolean found = false;
+ int pos = 0;
+ int ch = -1;
+ Reader reader = null;
+ String result = ((encoding != null) ? encoding : UTF_8_ENC);
+
+ reader = new InputStreamReader(new ByteArrayInputStream(data), result);
+ ch = reader.read();
+
+ // if this is an XML declaration, it will start with the text '<?xml'
+ for (int i = 0; ((i < XML_DECL_START.length()) && (done == false)); i++) {
+ if (ch != XML_DECL_START.charAt(i)) {
+ // This doesn't look like an XML declaration. This method
+ // should only be called if the stream contains an XML
+ // declaration in the encoding that is passed into the method.
+ done = true;
+ break;
+ }
+ // no else required; still matches
+ ch = reader.read();
+ }
+
+ // there must be at least one whitespace character next.
+ loop = true;
+ while ((loop == true) && (done == false)) {
+ switch (ch) {
+ case SPACE:
+ case TAB: // intentional
+ case LINEFEED: // fall
+ case RETURN: // through
+ ch = reader.read();
+ break;
+
+ case -1:
+ // unexpected EOF
+ done = true;
+ break;
+
+ default:
+ // non-whitespace
+ loop = false;
+ break;
+ }
+ }
+
+ // now look for the text 'encoding', but if the end of the XML
+ // declaration (signified by the text '?>') comes first, then
+ // assume the encoding is UTF-8
+ loop = true;
+ while ((loop == true) && (done == false)) {
+ if (ch == -1) {
+ // unexpected EOF
+ done = true;
+ break;
+ } else if (recognized == true) {
+ // this is the encoding declaration as long as the next few
+ // characters are whitespace and/or the equals ('=') sign
+ switch (ch) {
+ case SPACE: // intentional
+ case TAB: // fall
+ case LINEFEED: // through
+ case RETURN:
+ // don't need to do anything
+ break;
+
+ case EQUAL:
+ if (almost == false) {
+ // got the equal, now find a quote
+ almost = true;
+ } else {
+ // this is not valid XML, so punt
+ recognized = false;
+ done = true;
+ }
+ break;
+
+ case DOUBLE_QUOTE: // intentional
+ case SINGLE_QUOTE: // fall through
+ if (almost == true) {
+ // got the quote, so move on to get the value
+ loop = false;
+ } else {
+ // got a quote before the equal; this is not valid
+ // XML, so punt
+ recognized = false;
+ done = true;
+ }
+ break;
+
+ default:
+ // non-whitespace
+ recognized = false;
+ if (almost == true) {
+ // this is not valid XML, so punt
+ done = true;
+ }
+ // no else required; this wasn't the encoding
+ // declaration
+ break;
+ }
+
+ if (recognized == false) {
+ // this isn't the encoding declaration, so go back to the
+ // top without reading the next character
+ pos = 0;
+ continue;
+ }
+ // no else required; still looking good
+ } else if (ch == ENCODING_DECL.charAt(pos++)) {
+ if (ENCODING_DECL.length() == pos) {
+ // this looks like the encoding declaration
+ recognized = true;
+ }
+ // no else required; this might be the encoding declaration
+ } else if (ch == '?') {
+ question = true;
+ pos = 0;
+ } else if ((ch == '>') && (question == true)) {
+ // there is no encoding declaration, so assume that the initial
+ // encoding guess was correct
+ done = true;
+ continue;
+ } else {
+ // still searching for the encoding declaration
+ pos = 0;
+ }
+
+ ch = reader.read();
+ }
+
+ if (done == false) {
+ StringBuilder buffer = new StringBuilder(MAX_ENC_NAME);
+
+ if (((ch >= 'a') && (ch <= 'z')) |
+ ((ch >= 'A') && (ch <= 'Z'))) {
+ // add the character to the result
+ buffer.append((char) ch);
+
+ loop = true;
+ while ((loop == true) && (done == false)) {
+ ch = reader.read();
+
+ if (((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= 'A') && (ch <= 'Z')) ||
+ ((ch >= '0') && (ch <= '9')) ||
+ (ch == '_') || (ch == '.') || (ch == '-')) {
+ // add the character to the result
+ buffer.append((char) ch);
+ } else if ((ch == DOUBLE_QUOTE) || (ch == SINGLE_QUOTE)) {
+ // finished!
+ found = true;
+ done = true;
+ result = buffer.toString();
+ } else {
+ // this is not a valid encoding name, so punt
+ done = true;
+ }
+ }
+ } else {
+ // this is not a valid encoding name, so punt
+ done = true;
+ }
+ }
+ // no else required; already failed to find the encoding somewhere else
+
+ return (result);
+ }
+
+ private static final int BOM_LENGTH = 4;
+ private static final int MAX_ENC_NAME = 512;
+
+ private static final int SPACE = 0x00000020;
+ private static final int TAB = 0x00000009;
+ private static final int LINEFEED = 0x0000000a;
+ private static final int RETURN = 0x0000000d;
+ private static final int EQUAL = '=';
+ private static final int DOUBLE_QUOTE = '\"';
+ private static final int SINGLE_QUOTE = '\'';
+
+ private static final int UTF_32_BE_BOM = 0x0000feff;
+ private static final int UTF_32_LE_BOM = 0xfffe0000;
+ private static final int UTF_16_BE_BOM = 0xfeff0000;
+ private static final int UTF_16_LE_BOM = 0xfffe0000;
+ private static final int UTF_8_BOM = 0xefbbbf00;
+ private static final int UNUSUAL_OCTET_1 = 0x00003c00;
+ private static final int UNUSUAL_OCTET_2 = 0x003c0000;
+ private static final int UTF_16BE = 0x003c003f;
+ private static final int UTF_16LE = 0x3c003f00;
+ private static final int EBCDIC = 0x4c6fa794;
+ private static final int XML_DECLARATION = 0x3c3f786d;
+
+ private static final String UTF_32_ENC = "UTF-32";
+ private static final String UTF_16_ENC = "UTF-16";
+ private static final String UTF_16BE_ENC = "UTF-16BE";
+ private static final String UTF_16LE_ENC = "UTF-16LE";
+ private static final String UTF_8_ENC = "UTF-8";
+ private static final String IBM037_ENC = "IBM037";
+
+ private static final String XML_DECL_START = "<?xml";
+ private static final String ENCODING_DECL = "encoding";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/xml/XMLNode.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2006, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.xml;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Class that contains information about an XML Node
+ */
+public class XMLNode {
+ private final boolean _isElement; // Element/PCTEXT
+ private final String _name;
+ private final XMLAttribute _attr;
+ private XMLNode _parent; // Parent Node
+ private XMLNode _nested; // Nested XML tags
+ private XMLNode _next; // Following XML tag on the same level
+
+ public final static String WILDCARD = "*";
+
+ /** Creates a PCTEXT node */
+ public XMLNode(String name) {
+ _isElement = false;
+ _name = name;
+ _attr = null;
+ _nested = null;
+ _next = null;
+ _parent = null;
+ }
+
+ /** Creates a ELEMENT node */
+ public XMLNode(String name, XMLAttribute attr) {
+ _isElement = true;
+ _name = stripNameSpace(name);
+ _attr = attr;
+ _nested = null;
+ _next = null;
+ _parent = null;
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public XMLAttribute getAttributes() {
+ return _attr;
+ }
+
+ public XMLNode getNested() {
+ return _nested;
+ }
+
+ public XMLNode getNext() {
+ return _next;
+ }
+
+ public boolean isElement() {
+ return _isElement;
+ }
+
+ public void setParent(XMLNode parent) {
+ _parent = parent;
+ }
+
+ public XMLNode getParent() {
+ return _parent;
+ }
+
+ public void setNext(XMLNode next) {
+ _next = next;
+ }
+
+ public void setNested(XMLNode nested) {
+ _nested = nested;
+ }
+
+ public static String stripNameSpace(String name) {
+ if (name != null && !name.startsWith("xmlns:")) {
+ int i = name.lastIndexOf(":");
+ if (i >= 0 && i < name.length()) {
+ return name.substring(i+1);
+ }
+ }
+ return name;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 83 * hash + (this._name != null ? this._name.hashCode() : 0);
+ hash = 83 * hash + (this._attr != null ? this._attr.hashCode() : 0);
+ hash = 83 * hash + (this._nested != null ? this._nested.hashCode() : 0);
+ hash = 83 * hash + (this._next != null ? this._next.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof XMLNode)) return false;
+ XMLNode other = (XMLNode)o;
+ boolean result =
+ match(_name, other._name) &&
+ match(_attr, other._attr) &&
+ match(_nested, other._nested) &&
+ match(_next, other._next);
+ return result;
+ }
+
+ public String getAttribute(String name) {
+ XMLAttribute cur = _attr;
+ while(cur != null) {
+ if (name.equals(cur.getName())) return cur.getValue();
+ cur = cur.getNext();
+ }
+ return "";
+ }
+
+ private static boolean match(Object o1, Object o2) {
+ if (o1 == null) {
+ return (o2 == null);
+ }
+ return o1.equals(o2);
+ }
+
+ public void printToStream(PrintWriter out) {
+ printToStream(out, false);
+ }
+
+ public void printToStream(PrintWriter out, boolean trim) {
+ printToStream(out, 0, trim);
+ }
+
+ public void printToStream(PrintWriter out, int n, boolean trim) {
+ if (!isElement()) {
+ String value = _name; // value node (where name is data of parent)
+ if (trim && value.length() > 512) {
+ value = "...";
+ }
+ out.print(value);
+ } else {
+ if (_nested == null) {
+ String attrString = (_attr == null) ? "" : (" " + _attr.toString());
+ lineln(out, n, "<" + _name + attrString + "/>");
+ } else {
+ String attrString = (_attr == null) ? "" : (" " + _attr.toString());
+ lineln(out, n, "<" + _name + attrString + ">");
+ _nested.printToStream(out, n + 1, trim);
+ if (_nested.isElement()) {
+ lineln(out, n, "</" + _name + ">");
+ } else {
+ out.print("</" + _name + ">");
+ }
+ }
+ }
+ if (_next != null) {
+ _next.printToStream(out, n, trim);
+ }
+ }
+
+ private static void lineln(PrintWriter out, int indent, String s) {
+ out.println("");
+ for(int i = 0; i < indent; i++) {
+ out.print(" ");
+ }
+ out.print(s);
+ }
+
+ @Override
+ public String toString() {
+ return toString(false);
+ }
+
+ public String toString(boolean hideLongElementValue) {
+ StringWriter sw = new StringWriter(1000);
+ PrintWriter pw = new PrintWriter(sw);
+ printToStream(pw, hideLongElementValue);
+ pw.close();
+ return sw.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/jpackager/JNLPConverter/src/jnlp/converter/parser/xml/XMLParser.java Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, 2018, 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.
+ *
+ * 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 jnlp.converter.parser.xml;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.StringReader;
+import java.io.IOException;
+import java.util.Stack;
+
+public class XMLParser extends DefaultHandler {
+
+ private XMLNode _root;
+ private final String _source;
+ private Stack<XMLNode> _inProgress;
+ private String _characters;
+
+ // although defined in com.sun.org.apache.xerces.internal.impl.Constants,
+ // we should not be able to access that, so defined here
+ private final static String DTD_DOWNLOAD =
+ "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+
+ private static final SAXParserFactory SPF = SAXParserFactory.newInstance();
+
+ /*
+ * Construct an <code>XMLParser</code>.
+ *
+ * @param source - the source text to parse.
+ */
+ public XMLParser(String source) {
+ _source = source.trim();
+ }
+
+ public XMLNode parse() throws SAXException {
+ // normally we parse without validating, but leave option to parse
+ // with validation, possibly controlled by config option.
+ return parse(false);
+ }
+
+ public XMLNode parse(boolean validating) throws SAXException {
+ _root = null;
+ _inProgress = new Stack<>();
+
+ try {
+ InputSource is = new InputSource(new StringReader(_source));
+ SPF.setValidating(validating);
+ // only download dtd file from DOCTYPE if we are doing validation
+ try {
+ SPF.setFeature(DTD_DOWNLOAD, validating);
+ } catch (Exception e) {
+ }
+ SAXParser sp = SPF.newSAXParser();
+ sp.parse(is, this);
+ } catch (ParserConfigurationException | IOException pce) {
+ throw new SAXException(pce);
+ }
+
+ return _root;
+ }
+
+ @Override
+ public void startElement(String uri, String localeName, String qName,
+ Attributes attributes) throws SAXException {
+
+ XMLAttribute first = null;
+ XMLAttribute last = null;
+ int len = attributes.getLength();
+
+ for (int i = 0; i < len; i++) {
+ XMLAttribute att = new XMLAttribute(
+ // in old implementation attribute names and values were trimmed
+ attributes.getQName(i).trim(), attributes.getValue(i).trim());
+ if (first == null) {
+ first = att;
+ }
+ if (last != null) {
+ last.setNext(att);
+ }
+ last = att;
+ }
+ _inProgress.push(new XMLNode(qName, first));
+ _characters = null;
+ }
+
+ @Override
+ public void endElement(String uri, String localeName, String elementName)
+ throws SAXException {
+ XMLNode node = _inProgress.pop();
+ // <information>
+ // <title>Title</title>
+ // <vendor>Vendor</vendor> "Some whitespaces"
+ // </information>
+ // In example above when we receive end of <information> we will
+ // have _characters set to whitespace and new line and it will be
+ // added as child node to <information>. This will break our cache code
+ // which will think that JNLP file changed on server even if it is not
+ // and thus we might not load properly.
+ //
+ // <application-desc name="HelloWorld" main-class="HelloWorld">
+ // <argument> test with whitespaces </argument>
+ // </application-desc>
+ // From example above we want to include whitespaces for <argument>.
+ //
+ // <node1>
+ // <node2>abc</node2>
+ // xyz (might be whitespaces)
+ // </node1>
+ // In JNLP spec we do not have cases when node have nested nodes as
+ // well as text which is whitespaces only.
+ //
+ // So to fix it lets check if ending node have nested nodes, then do
+ // not add whitespaces only node.
+ if (node != null && node.getNested() != null && _characters != null) {
+ String trimCharacters = _characters.trim();
+ if ((trimCharacters == null) || (trimCharacters.length() == 0)) {
+ _characters = null; // No need to add whitespaces only
+ }
+ }
+ if ((_characters != null) && (_characters.trim().length() > 0)) {
+ addChild(node, new XMLNode(_characters));
+ }
+
+ if (_inProgress.isEmpty()) {
+ _root = node;
+ } else {
+ addChild(_inProgress.peek(), node);
+ }
+ _characters = null;
+ }
+
+ @Override
+ public void ignorableWhitespace(char[] chars, int start, int length)
+ throws SAXException {
+ String s = new String(chars, start, length);
+ _characters = ((_characters == null) ? s : _characters + s);
+ }
+
+ private void addChild(XMLNode parent, XMLNode child) {
+ child.setParent(parent);
+
+ XMLNode sibling = parent.getNested();
+ if (sibling == null) {
+ parent.setNested(child); // set us as only child
+ } else {
+ while (sibling.getNext() != null) {
+ sibling = sibling.getNext();
+ }
+ sibling.setNext(child); // sets us as youngest child
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/nbproject/jpackager/JNLPConverter/build.xml Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="JNLPConverter" default="default" basedir=".">
+ <description>Builds, tests, and runs the project JNLPConverter.</description>
+ <import file="nbproject/build-impl.xml"/>
+ <!--
+
+ There exist several targets which are by default empty and which can be
+ used for execution of your tasks. These targets are usually executed
+ before and after some main targets. They are:
+
+ -pre-init: called before initialization of project properties
+ -post-init: called after initialization of project properties
+ -pre-compile: called before javac compilation
+ -post-compile: called after javac compilation
+ -pre-compile-single: called before javac compilation of single file
+ -post-compile-single: called after javac compilation of single file
+ -pre-compile-test: called before javac compilation of JUnit tests
+ -post-compile-test: called after javac compilation of JUnit tests
+ -pre-compile-test-single: called before javac compilation of single JUnit test
+ -post-compile-test-single: called after javac compilation of single JUunit test
+ -pre-jar: called before JAR building
+ -post-jar: called after JAR building
+ -post-clean: called after cleaning build products
+
+ (Targets beginning with '-' are not intended to be called on their own.)
+
+ Example of inserting an obfuscator after compilation could look like this:
+
+ <target name="-post-compile">
+ <obfuscate>
+ <fileset dir="${build.classes.dir}"/>
+ </obfuscate>
+ </target>
+
+ For list of available properties check the imported
+ nbproject/build-impl.xml file.
+
+
+ Another way to customize the build is by overriding existing main targets.
+ The targets of interest are:
+
+ -init-macrodef-javac: defines macro for javac compilation
+ -init-macrodef-junit: defines macro for junit execution
+ -init-macrodef-debug: defines macro for class debugging
+ -init-macrodef-java: defines macro for class execution
+ -do-jar: JAR building
+ run: execution of project
+ -javadoc-build: Javadoc generation
+ test-report: JUnit report generation
+
+ An example of overriding the target for project execution could look like this:
+
+ <target name="run" depends="JNLPConverter-impl.jar">
+ <exec dir="bin" executable="launcher.exe">
+ <arg file="${dist.jar}"/>
+ </exec>
+ </target>
+
+ Notice that the overridden target depends on the jar target and not only on
+ the compile target as the regular run target does. Again, for a list of available
+ properties which you can use, check the target you are overriding in the
+ nbproject/build-impl.xml file.
+
+ -->
+ <target name="-post-jar">
+ <copy file="${dist.jar}" todir="../../../jpackager/jnlpconverter"/>
+ </target>
+
+ <target name="-post-clean">
+ <delete file="../../../jpackager/jnlpconverter/JNLPConverter.jar"/>
+ </target>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/nbproject/jpackager/JNLPConverter/manifest.mf Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/nbproject/jpackager/JNLPConverter/nbproject/build-impl.xml Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,1403 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+ - initialization
+ - compilation
+ - jar
+ - execution
+ - debugging
+ - javadoc
+ - test compilation
+ - test execution
+ - test debugging
+ - applet
+ - cleanup
+
+ -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="JNLPConverter-impl">
+ <fail message="Please build using Ant 1.8.0 or higher.">
+ <condition>
+ <not>
+ <antversion atleast="1.8.0"/>
+ </not>
+ </condition>
+ </fail>
+ <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+ <!--
+ ======================
+ INITIALIZATION SECTION
+ ======================
+ -->
+ <target name="-pre-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="-pre-init" name="-init-private">
+ <property file="nbproject/private/config.properties"/>
+ <property file="nbproject/private/configs/${config}.properties"/>
+ <property file="nbproject/private/private.properties"/>
+ </target>
+ <target depends="-pre-init,-init-private" name="-init-user">
+ <property file="${user.properties.file}"/>
+ <!-- The two properties below are usually overridden -->
+ <!-- by the active platform. Just a fallback. -->
+ <property name="default.javac.source" value="1.6"/>
+ <property name="default.javac.target" value="1.6"/>
+ </target>
+ <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+ <property file="nbproject/configs/${config}.properties"/>
+ <property file="nbproject/project.properties"/>
+ </target>
+ <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+ <property name="platform.java" value="${java.home}/bin/java"/>
+ <available file="${manifest.file}" property="manifest.available"/>
+ <condition property="splashscreen.available">
+ <and>
+ <not>
+ <equals arg1="${application.splash}" arg2="" trim="true"/>
+ </not>
+ <available file="${application.splash}"/>
+ </and>
+ </condition>
+ <condition property="main.class.available">
+ <and>
+ <isset property="main.class"/>
+ <not>
+ <equals arg1="${main.class}" arg2="" trim="true"/>
+ </not>
+ </and>
+ </condition>
+ <condition property="profile.available">
+ <and>
+ <isset property="javac.profile"/>
+ <length length="0" string="${javac.profile}" when="greater"/>
+ <matches pattern="((1\.[89])|9)(\..*)?" string="${javac.source}"/>
+ </and>
+ </condition>
+ <condition property="do.archive">
+ <or>
+ <not>
+ <istrue value="${jar.archive.disabled}"/>
+ </not>
+ <istrue value="${not.archive.disabled}"/>
+ </or>
+ </condition>
+ <condition property="do.mkdist">
+ <and>
+ <isset property="do.archive"/>
+ <isset property="libs.CopyLibs.classpath"/>
+ <not>
+ <istrue value="${mkdist.disabled}"/>
+ </not>
+ </and>
+ </condition>
+ <condition property="do.archive+manifest.available">
+ <and>
+ <isset property="manifest.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+main.class.available">
+ <and>
+ <isset property="main.class.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+splashscreen.available">
+ <and>
+ <isset property="splashscreen.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+profile.available">
+ <and>
+ <isset property="profile.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="have.tests">
+ <or/>
+ </condition>
+ <condition property="have.sources">
+ <or>
+ <available file="${src.src.dir}"/>
+ </or>
+ </condition>
+ <condition property="netbeans.home+have.tests">
+ <and>
+ <isset property="netbeans.home"/>
+ <isset property="have.tests"/>
+ </and>
+ </condition>
+ <condition property="no.javadoc.preview">
+ <and>
+ <isset property="javadoc.preview"/>
+ <isfalse value="${javadoc.preview}"/>
+ </and>
+ </condition>
+ <property name="run.jvmargs" value=""/>
+ <property name="run.jvmargs.ide" value=""/>
+ <property name="javac.compilerargs" value=""/>
+ <property name="work.dir" value="${basedir}"/>
+ <condition property="no.deps">
+ <and>
+ <istrue value="${no.dependencies}"/>
+ </and>
+ </condition>
+ <property name="javac.debug" value="true"/>
+ <property name="javadoc.preview" value="true"/>
+ <property name="application.args" value=""/>
+ <property name="source.encoding" value="${file.encoding}"/>
+ <property name="runtime.encoding" value="${source.encoding}"/>
+ <property name="manifest.encoding" value="${source.encoding}"/>
+ <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+ <and>
+ <isset property="javadoc.encoding"/>
+ <not>
+ <equals arg1="${javadoc.encoding}" arg2=""/>
+ </not>
+ </and>
+ </condition>
+ <property name="javadoc.encoding.used" value="${source.encoding}"/>
+ <property name="includes" value="**"/>
+ <property name="excludes" value=""/>
+ <property name="do.depend" value="false"/>
+ <condition property="do.depend.true">
+ <istrue value="${do.depend}"/>
+ </condition>
+ <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+ <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+ <and>
+ <isset property="endorsed.classpath"/>
+ <not>
+ <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
+ </not>
+ </and>
+ </condition>
+ <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
+ <isset property="profile.available"/>
+ </condition>
+ <condition else="false" property="jdkBug6558476">
+ <and>
+ <matches pattern="1\.[56]" string="${java.specification.version}"/>
+ <not>
+ <os family="unix"/>
+ </not>
+ </and>
+ </condition>
+ <condition else="false" property="javac.fork">
+ <or>
+ <istrue value="${jdkBug6558476}"/>
+ <istrue value="${javac.external.vm}"/>
+ </or>
+ </condition>
+ <property name="jar.index" value="false"/>
+ <property name="jar.index.metainf" value="${jar.index}"/>
+ <property name="copylibs.rebase" value="true"/>
+ <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+ <condition property="junit.available">
+ <or>
+ <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+ <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+ </or>
+ </condition>
+ <condition property="testng.available">
+ <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+ </condition>
+ <condition property="junit+testng.available">
+ <and>
+ <istrue value="${junit.available}"/>
+ <istrue value="${testng.available}"/>
+ </and>
+ </condition>
+ <condition else="testng" property="testng.mode" value="mixed">
+ <istrue value="${junit+testng.available}"/>
+ </condition>
+ <condition else="" property="testng.debug.mode" value="-mixed">
+ <istrue value="${junit+testng.available}"/>
+ </condition>
+ <property name="java.failonerror" value="true"/>
+ </target>
+ <target name="-post-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+ <fail unless="src.src.dir">Must set src.src.dir</fail>
+ <fail unless="build.dir">Must set build.dir</fail>
+ <fail unless="dist.dir">Must set dist.dir</fail>
+ <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+ <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+ <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+ <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+ <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+ <fail unless="dist.jar">Must set dist.jar</fail>
+ </target>
+ <target name="-init-macrodef-property">
+ <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${@{value}}"/>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.src.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <attribute default="${javac.processorpath}" name="processorpath"/>
+ <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="${javac.debug}" name="debug"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
+ <mkdir dir="@{apgeneratedsrcdir}"/>
+ <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.profile.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
+ <compilerarg value="-processorpath"/>
+ <compilerarg path="@{processorpath}:${empty.dir}"/>
+ <compilerarg line="${ap.processors.internal}"/>
+ <compilerarg line="${annotation.processing.processor.options}"/>
+ <compilerarg value="-s"/>
+ <compilerarg path="@{apgeneratedsrcdir}"/>
+ <compilerarg line="${ap.proc.none.internal}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.src.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <attribute default="${javac.processorpath}" name="processorpath"/>
+ <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="${javac.debug}" name="debug"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
+ <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.profile.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+ <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.src.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <sequential>
+ <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </depend>
+ </sequential>
+ </macrodef>
+ <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <sequential>
+ <fail unless="javac.includes">Must set javac.includes</fail>
+ <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+ <path>
+ <filelist dir="@{destdir}" files="${javac.includes}"/>
+ </path>
+ <globmapper from="*.java" to="*.class"/>
+ </pathconvert>
+ <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+ <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+ <delete>
+ <files includesfile="${javac.includesfile.binary}"/>
+ </delete>
+ <delete>
+ <fileset file="${javac.includesfile.binary}"/>
+ </delete>
+ </sequential>
+ </macrodef>
+ </target>
+ <target if="${junit.available}" name="-init-macrodef-junit-init">
+ <condition else="false" property="nb.junit.batch" value="true">
+ <and>
+ <istrue value="${junit.available}"/>
+ <not>
+ <isset property="test.method"/>
+ </not>
+ </and>
+ </condition>
+ <condition else="false" property="nb.junit.single" value="true">
+ <and>
+ <istrue value="${junit.available}"/>
+ <isset property="test.method"/>
+ </and>
+ </condition>
+ </target>
+ <target name="-init-test-properties">
+ <property name="test.binaryincludes" value="<nothing>"/>
+ <property name="test.binarytestincludes" value=""/>
+ <property name="test.binaryexcludes" value=""/>
+ </target>
+ <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+ <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property name="junit.forkmode" value="perTest"/>
+ <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+ <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ <jvmarg value="-ea"/>
+ <customize/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+ <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property name="junit.forkmode" value="perTest"/>
+ <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+ <batchtest todir="${build.test.results.dir}">
+ <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+ <filename name="${test.binarytestincludes}"/>
+ </fileset>
+ </batchtest>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ <jvmarg value="-ea"/>
+ <customize/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+ <target if="${testng.available}" name="-init-macrodef-testng">
+ <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+ <isset property="test.method"/>
+ </condition>
+ <union id="test.set"/>
+ <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+ <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="JNLPConverter" testname="TestNG tests" workingDir="${work.dir}">
+ <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+ <propertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </propertyset>
+ <customize/>
+ </testng>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-test-impl">
+ <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element implicit="true" name="customize" optional="true"/>
+ <sequential>
+ <echo>No tests executed.</echo>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+ <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element implicit="true" name="customize" optional="true"/>
+ <sequential>
+ <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+ <customize/>
+ </j2seproject3:junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+ <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element implicit="true" name="customize" optional="true"/>
+ <sequential>
+ <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+ <customize/>
+ </j2seproject3:testng>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+ <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <sequential>
+ <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+ <customize>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <jvmarg line="${run.jvmargs.ide}"/>
+ </customize>
+ </j2seproject3:test-impl>
+ </sequential>
+ </macrodef>
+ </target>
+ <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+ <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property name="junit.forkmode" value="perTest"/>
+ <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+ <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ <jvmarg value="-ea"/>
+ <jvmarg line="${debug-args-line}"/>
+ <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+ <customize/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+ <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property name="junit.forkmode" value="perTest"/>
+ <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+ <batchtest todir="${build.test.results.dir}">
+ <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+ <filename name="${test.binarytestincludes}"/>
+ </fileset>
+ </batchtest>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ <jvmarg value="-ea"/>
+ <jvmarg line="${debug-args-line}"/>
+ <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+ <customize/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+ <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <element implicit="true" name="customize" optional="true"/>
+ <sequential>
+ <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+ <customize/>
+ </j2seproject3:junit-debug>
+ </sequential>
+ </macrodef>
+ </target>
+ <target if="${testng.available}" name="-init-macrodef-testng-debug">
+ <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${main.class}" name="testClass"/>
+ <attribute default="" name="testMethod"/>
+ <element name="customize2" optional="true"/>
+ <sequential>
+ <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+ <isset property="test.method"/>
+ </condition>
+ <condition else="-suitename JNLPConverter -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+ <matches pattern=".*\.xml" string="@{testClass}"/>
+ </condition>
+ <delete dir="${build.test.results.dir}" quiet="true"/>
+ <mkdir dir="${build.test.results.dir}"/>
+ <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+ <customize>
+ <customize2/>
+ <jvmarg value="-ea"/>
+ <arg line="${testng.debug.mode}"/>
+ <arg line="-d ${build.test.results.dir}"/>
+ <arg line="-listener org.testng.reporters.VerboseReporter"/>
+ <arg line="${testng.cmd.args}"/>
+ </customize>
+ </j2seproject3:debug>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+ <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${main.class}" name="testClass"/>
+ <attribute default="" name="testMethod"/>
+ <element implicit="true" name="customize2" optional="true"/>
+ <sequential>
+ <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+ <customize2/>
+ </j2seproject3:testng-debug>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+ <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <attribute default="${main.class}" name="testClass"/>
+ <attribute default="" name="testMethod"/>
+ <sequential>
+ <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+ <customize>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <jvmarg line="${run.jvmargs.ide}"/>
+ </customize>
+ </j2seproject3:test-debug-impl>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+ <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <attribute default="" name="testmethods"/>
+ <attribute default="${main.class}" name="testClass"/>
+ <attribute default="" name="testMethod"/>
+ <sequential>
+ <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+ <customize2>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ </customize2>
+ </j2seproject3:testng-debug-impl>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+ <!--
+ pre NB7.2 profiling section; consider it deprecated
+ -->
+ <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+ <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
+ <macrodef name="resolve">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${env.@{value}}"/>
+ </sequential>
+ </macrodef>
+ <macrodef name="profile">
+ <attribute default="${main.class}" name="classname"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property environment="env"/>
+ <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+ <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg value="${profiler.info.jvmargs.agent}"/>
+ <jvmarg line="${profiler.info.jvmargs}"/>
+ <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+ <arg line="${application.args}"/>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+ <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+ <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+ </target>
+ <!--
+ end of pre NB7.2 profiling section
+ -->
+ <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+ <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${main.class}" name="name"/>
+ <attribute default="${debug.classpath}" name="classpath"/>
+ <attribute default="" name="stopclassname"/>
+ <sequential>
+ <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </nbjpdastart>
+ </sequential>
+ </macrodef>
+ <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${build.classes.dir}" name="dir"/>
+ <sequential>
+ <nbjpdareload>
+ <fileset dir="@{dir}" includes="${fix.classes}">
+ <include name="${fix.includes}*.class"/>
+ </fileset>
+ </nbjpdareload>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-debug-args">
+ <property name="version-output" value="java version "${ant.java.version}"/>
+ <condition property="have-jdk-older-than-1.4">
+ <or>
+ <contains string="${version-output}" substring="java version "1.0"/>
+ <contains string="${version-output}" substring="java version "1.1"/>
+ <contains string="${version-output}" substring="java version "1.2"/>
+ <contains string="${version-output}" substring="java version "1.3"/>
+ </or>
+ </condition>
+ <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+ <istrue value="${have-jdk-older-than-1.4}"/>
+ </condition>
+ <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+ <os family="windows"/>
+ </condition>
+ <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+ <isset property="debug.transport"/>
+ </condition>
+ </target>
+ <target depends="-init-debug-args" name="-init-macrodef-debug">
+ <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${main.class}" name="classname"/>
+ <attribute default="${debug.classpath}" name="classpath"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg line="${debug-args-line}"/>
+ <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <jvmarg line="${run.jvmargs.ide}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-java">
+ <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${main.class}" name="classname"/>
+ <attribute default="${run.classpath}" name="classpath"/>
+ <attribute default="jvm" name="jvm"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <jvmarg line="${run.jvmargs.ide}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-copylibs">
+ <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${manifest.file}" name="manifest"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <pathconvert property="run.classpath.without.build.classes.dir">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to=""/>
+ </pathconvert>
+ <pathconvert pathsep=" " property="jar.classpath">
+ <path path="${run.classpath.without.build.classes.dir}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <filtermapper>
+ <replacestring from=" " to="%20"/>
+ </filtermapper>
+ <globmapper from="*" to="lib/*"/>
+ </chainedmapper>
+ </pathconvert>
+ <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+ <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" manifestencoding="UTF-8" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+ <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+ <manifest>
+ <attribute name="Class-Path" value="${jar.classpath}"/>
+ <customize/>
+ </manifest>
+ </copylibs>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-presetdef-jar">
+ <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifestencoding="UTF-8">
+ <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+ </jar>
+ </presetdef>
+ </target>
+ <target name="-init-ap-cmdline-properties">
+ <property name="annotation.processing.enabled" value="true"/>
+ <property name="annotation.processing.processors.list" value=""/>
+ <property name="annotation.processing.processor.options" value=""/>
+ <property name="annotation.processing.run.all.processors" value="true"/>
+ <property name="javac.processorpath" value="${javac.classpath}"/>
+ <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+ <condition property="ap.supported.internal" value="true">
+ <not>
+ <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+ </not>
+ </condition>
+ </target>
+ <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+ <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+ <isfalse value="${annotation.processing.run.all.processors}"/>
+ </condition>
+ <condition else="" property="ap.proc.none.internal" value="-proc:none">
+ <isfalse value="${annotation.processing.enabled}"/>
+ </condition>
+ </target>
+ <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+ <property name="ap.cmd.line.internal" value=""/>
+ </target>
+ <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+ <!--
+ ===================
+ COMPILATION SECTION
+ ===================
+ -->
+ <target name="-deps-jar-init" unless="built-jar.properties">
+ <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+ <delete file="${built-jar.properties}" quiet="true"/>
+ </target>
+ <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+ <echo level="warn" message="Cycle detected: JNLPConverter was already built"/>
+ </target>
+ <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-jar.properties}" verbose="false"/>
+ <property file="${built-jar.properties}" prefix="already.built.jar."/>
+ <antcall target="-warn-already-built-jar"/>
+ <propertyfile file="${built-jar.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ </target>
+ <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+ <target depends="init" name="-check-automatic-build">
+ <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+ </target>
+ <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+ <antcall target="clean"/>
+ </target>
+ <target depends="init,deps-jar" name="-pre-pre-compile">
+ <mkdir dir="${build.classes.dir}"/>
+ </target>
+ <target name="-pre-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="do.depend.true" name="-compile-depend">
+ <pathconvert property="build.generated.subdirs">
+ <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </pathconvert>
+ <j2seproject3:depend srcdir="${src.src.dir}:${build.generated.subdirs}"/>
+ </target>
+ <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+ <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+ <copy todir="${build.classes.dir}">
+ <fileset dir="${src.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+ </copy>
+ </target>
+ <target if="has.persistence.xml" name="-copy-persistence-xml">
+ <mkdir dir="${build.classes.dir}/META-INF"/>
+ <copy todir="${build.classes.dir}/META-INF">
+ <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
+ </copy>
+ </target>
+ <target name="-post-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+ <target name="-pre-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+ <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+ <j2seproject3:force-recompile/>
+ <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.src.dir}"/>
+ </target>
+ <target name="-post-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+ <!--
+ ====================
+ JAR BUILDING SECTION
+ ====================
+ -->
+ <target depends="init" name="-pre-pre-jar">
+ <dirname file="${dist.jar}" property="dist.jar.dir"/>
+ <mkdir dir="${dist.jar.dir}"/>
+ </target>
+ <target name="-pre-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
+ <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+ <touch file="${tmp.manifest.file}" verbose="false"/>
+ </target>
+ <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
+ <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+ <copy encoding="${manifest.encoding}" file="${manifest.file}" outputencoding="UTF-8" tofile="${tmp.manifest.file}"/>
+ </target>
+ <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
+ <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+ <attribute name="Main-Class" value="${main.class}"/>
+ </manifest>
+ </target>
+ <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
+ <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+ <attribute name="Profile" value="${javac.profile}"/>
+ </manifest>
+ </target>
+ <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
+ <basename file="${application.splash}" property="splashscreen.basename"/>
+ <mkdir dir="${build.classes.dir}/META-INF"/>
+ <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+ <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+ <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+ </manifest>
+ </target>
+ <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
+ <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+ <echo level="info">To run this application from the command line without Ant, try:</echo>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <echo level="info">java -jar "${dist.jar.resolved}"</echo>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+ <j2seproject1:jar manifest="${tmp.manifest.file}"/>
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <pathconvert property="run.classpath.with.dist.jar">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+ </pathconvert>
+ <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
+ <isset property="main.class.available"/>
+ </condition>
+ <condition else="debug" property="jar.usage.level" value="info">
+ <isset property="main.class.available"/>
+ </condition>
+ <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
+ </target>
+ <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
+ <delete>
+ <fileset file="${tmp.manifest.file}"/>
+ </delete>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
+ <target name="-post-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+ <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
+ <!--
+ =================
+ EXECUTION SECTION
+ =================
+ -->
+ <target depends="init,compile" description="Run a main class." name="run">
+ <j2seproject1:java>
+ <customize>
+ <arg line="${application.args}"/>
+ </customize>
+ </j2seproject1:java>
+ </target>
+ <target name="-do-not-recompile">
+ <property name="javac.includes.binary" value=""/>
+ </target>
+ <target depends="init,compile-single" name="run-single">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <j2seproject1:java classname="${run.class}"/>
+ </target>
+ <target depends="init,compile-test-single" name="run-test-with-main">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+ </target>
+ <!--
+ =================
+ DEBUGGING SECTION
+ =================
+ -->
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+ <j2seproject1:nbjpdastart name="${debug.class}"/>
+ </target>
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+ <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+ </target>
+ <target depends="init,compile" name="-debug-start-debuggee">
+ <j2seproject3:debug>
+ <customize>
+ <arg line="${application.args}"/>
+ </customize>
+ </j2seproject3:debug>
+ </target>
+ <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+ <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+ </target>
+ <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+ <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+ <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+ <j2seproject3:debug classname="${debug.class}"/>
+ </target>
+ <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+ <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+ <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+ <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+ </target>
+ <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+ <target depends="init" name="-pre-debug-fix">
+ <fail unless="fix.includes">Must set fix.includes</fail>
+ <property name="javac.includes" value="${fix.includes}.java"/>
+ </target>
+ <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+ <j2seproject1:nbjpdareload/>
+ </target>
+ <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+ <!--
+ =================
+ PROFILING SECTION
+ =================
+ -->
+ <!--
+ pre NB7.2 profiler integration
+ -->
+ <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+ <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <profile/>
+ </target>
+ <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
+ <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+ <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <profile classname="${profile.class}"/>
+ </target>
+ <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+ <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <profile classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </profile>
+ </target>
+ <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+ <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+ <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+ <jvmarg value="${profiler.info.jvmargs.agent}"/>
+ <jvmarg line="${profiler.info.jvmargs}"/>
+ <test name="${profile.class}"/>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ </junit>
+ </target>
+ <!--
+ end of pre NB72 profiling section
+ -->
+ <target if="netbeans.home" name="-profile-check">
+ <condition property="profiler.configured">
+ <or>
+ <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+ <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+ </or>
+ </condition>
+ </target>
+ <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+ <startprofiler/>
+ <antcall target="run"/>
+ </target>
+ <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <startprofiler/>
+ <antcall target="run-single"/>
+ </target>
+ <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+ <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+ <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+ <startprofiler/>
+ <antcall target="test-single"/>
+ </target>
+ <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <startprofiler/>
+ <antcall target="run-test-with-main"/>
+ </target>
+ <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+ <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+ <startprofiler/>
+ <antcall target="run-applet"/>
+ </target>
+ <!--
+ ===============
+ JAVADOC SECTION
+ ===============
+ -->
+ <target depends="init" if="have.sources" name="-javadoc-build">
+ <mkdir dir="${dist.javadoc.dir}"/>
+ <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
+ <and>
+ <isset property="endorsed.classpath.cmd.line.arg"/>
+ <not>
+ <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
+ </not>
+ </and>
+ </condition>
+ <condition else="" property="bug5101868workaround" value="*.java">
+ <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
+ </condition>
+ <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+ <classpath>
+ <path path="${javac.classpath}"/>
+ </classpath>
+ <fileset dir="${src.src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+ <filename name="**/*.java"/>
+ </fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/*.java"/>
+ <exclude name="*.java"/>
+ </fileset>
+ <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+ </javadoc>
+ <copy todir="${dist.javadoc.dir}">
+ <fileset dir="${src.src.dir}" excludes="${excludes}" includes="${includes}">
+ <filename name="**/doc-files/**"/>
+ </fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/doc-files/**"/>
+ </fileset>
+ </copy>
+ </target>
+ <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+ <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+ </target>
+ <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+ <!--
+ =========================
+ TEST COMPILATION SECTION
+ =========================
+ -->
+ <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+ <mkdir dir="${build.test.classes.dir}"/>
+ </target>
+ <target name="-pre-compile-test">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="do.depend.true" name="-compile-test-depend">
+ <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
+ </target>
+ <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+ <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir=""/>
+ <copy todir="${build.test.classes.dir}"/>
+ </target>
+ <target name="-post-compile-test">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+ <target name="-pre-compile-test-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+ <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+ <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+ <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir=""/>
+ <copy todir="${build.test.classes.dir}"/>
+ </target>
+ <target name="-post-compile-test-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+ <!--
+ =======================
+ TEST EXECUTION SECTION
+ =======================
+ -->
+ <target depends="init" if="have.tests" name="-pre-test-run">
+ <mkdir dir="${build.test.results.dir}"/>
+ </target>
+ <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+ <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
+ </target>
+ <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+ </target>
+ <target depends="init" if="have.tests" name="test-report"/>
+ <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+ <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+ <target depends="init" if="have.tests" name="-pre-test-run-single">
+ <mkdir dir="${build.test.results.dir}"/>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+ <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+ <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+ <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+ <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+ <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+ <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+ <!--
+ =======================
+ TEST DEBUGGING SECTION
+ =======================
+ -->
+ <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+ <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+ <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+ <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+ <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+ <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+ </target>
+ <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+ <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+ </target>
+ <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+ <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+ <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+ <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+ </target>
+ <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+ <!--
+ =========================
+ APPLET EXECUTION SECTION
+ =========================
+ -->
+ <target depends="init,compile-single" name="run-applet">
+ <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+ <j2seproject1:java classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </j2seproject1:java>
+ </target>
+ <!--
+ =========================
+ APPLET DEBUGGING SECTION
+ =========================
+ -->
+ <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+ <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+ <j2seproject3:debug classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </j2seproject3:debug>
+ </target>
+ <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+ <!--
+ ===============
+ CLEANUP SECTION
+ ===============
+ -->
+ <target name="-deps-clean-init" unless="built-clean.properties">
+ <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+ <delete file="${built-clean.properties}" quiet="true"/>
+ </target>
+ <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+ <echo level="warn" message="Cycle detected: JNLPConverter was already built"/>
+ </target>
+ <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-clean.properties}" verbose="false"/>
+ <property file="${built-clean.properties}" prefix="already.built.clean."/>
+ <antcall target="-warn-already-built-clean"/>
+ <propertyfile file="${built-clean.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ </target>
+ <target depends="init" name="-do-clean">
+ <delete dir="${build.dir}"/>
+ <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+ </target>
+ <target name="-post-clean">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+ <target name="-check-call-dep">
+ <property file="${call.built.properties}" prefix="already.built."/>
+ <condition property="should.call.dep">
+ <and>
+ <not>
+ <isset property="already.built.${call.subproject}"/>
+ </not>
+ <available file="${call.script}"/>
+ </and>
+ </condition>
+ </target>
+ <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+ <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+ <propertyset>
+ <propertyref prefix="transfer."/>
+ <mapper from="transfer.*" to="*" type="glob"/>
+ </propertyset>
+ </ant>
+ </target>
+</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/nbproject/jpackager/JNLPConverter/nbproject/genfiles.properties Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=9017e41e
+build.xml.script.CRC32=5cf818d6
+build.xml.stylesheet.CRC32=8064a381@1.80.1.48
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=9017e41e
+nbproject/build-impl.xml.script.CRC32=d0290d6d
+nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/nbproject/jpackager/JNLPConverter/nbproject/project.properties Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,96 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=JNLPConverter
+application.vendor=
+auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/JNLPConverter.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+file.reference.jnlpconverter-src=../../../jpackager/jnlpconverter/src
+includes=**
+jar.archive.disabled=${jnlp.enabled}
+jar.compress=false
+jar.index=${jnlp.enabled}
+javac.classpath=
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.external.vm=true
+javac.processorpath=\
+ ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+javac.test.processorpath=\
+ ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+jnlp.codebase.type=no.codebase
+jnlp.descriptor=application
+jnlp.enabled=false
+jnlp.mixed.code=default
+jnlp.offline-allowed=false
+jnlp.signed=false
+jnlp.signing=
+jnlp.signing.alias=
+jnlp.signing.keystore=
+main.class=jnlp.converter.Main
+# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found.
+manifest.custom.application.library.allowable.codebase=
+# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts.
+manifest.custom.caller.allowable.codebase=
+# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed
+manifest.custom.codebase=
+# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
+manifest.custom.permissions=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project.
+# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
+# To set system properties for unit tests define test-sys-prop.name=value:
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.src.dir=${file.reference.jnlpconverter-src}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/demo/share/nbproject/jpackager/JNLPConverter/nbproject/project.xml Fri Oct 12 19:00:51 2018 -0400
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.java.j2seproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+ <name>JNLPConverter</name>
+ <source-roots>
+ <root id="src.src.dir" name="Source Packages"/>
+ </source-roots>
+ <test-roots/>
+ </data>
+ </configuration>
+</project>