--- /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);
+ }
+ }
+}