aboutsummaryrefslogtreecommitdiffstats
path: root/netx/net/sourceforge/jnlp/JNLPFile.java
diff options
context:
space:
mode:
Diffstat (limited to 'netx/net/sourceforge/jnlp/JNLPFile.java')
-rw-r--r--netx/net/sourceforge/jnlp/JNLPFile.java633
1 files changed, 633 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/JNLPFile.java b/netx/net/sourceforge/jnlp/JNLPFile.java
new file mode 100644
index 0000000..a02ca1e
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/JNLPFile.java
@@ -0,0 +1,633 @@
+// Copyright (C) 2001-2003 Jon A. Maxwell (JAM)
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+package net.sourceforge.jnlp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+import net.sourceforge.jnlp.cache.ResourceTracker;
+import net.sourceforge.jnlp.cache.UpdatePolicy;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+/**
+ * Provides methods to access the information in a Java Network
+ * Launching Protocol (JNLP) file. The Java Network Launching
+ * Protocol specifies in an XML file the information needed to
+ * load, cache, and run Java code over the network and in a secure
+ * environment.<p>
+ *
+ * This class represents the overall information about a JNLP file
+ * from the jnlp element. Other information is accessed through
+ * objects that represent the elements of a JNLP file
+ * (information, resources, application-desc, etc). References to
+ * these objects are obtained by calling the getInformation,
+ * getResources, getSecurity, etc methods.<p>
+ *
+ * @author <a href="mailto:[email protected]">Jon A. Maxwell (JAM)</a> - initial author
+ * @version $Revision: 1.21 $
+ */
+public class JNLPFile {
+
+ // todo: save the update policy, then if file was not updated
+ // then do not check resources for being updated.
+ //
+ // todo: make getLaunchInfo return a superclass that all the
+ // launch types implement (can get codebase from it).
+ //
+ // todo: currently does not filter resources by jvm version.
+ //
+
+ private static String R(String key) { return JNLPRuntime.getMessage(key); }
+
+ /** the location this JNLP file was created from */
+ protected URL sourceLocation = null;
+
+ /** the network location of this JNLP file */
+ protected URL fileLocation;
+
+ /** A key that uniquely identifies connected instances (main jnlp+ext) */
+ protected String uniqueKey = null;
+
+ /** the URL used to resolve relative URLs in the file */
+ protected URL codeBase;
+
+ /** file version */
+ protected Version fileVersion;
+
+ /** spec version */
+ protected Version specVersion;
+
+ /** information */
+ protected List info;
+
+ protected UpdateDesc update;
+
+ /** resources */
+ protected List resources;
+
+ /** additional resources not in JNLP file (from command line) */
+ protected ResourcesDesc sharedResources = new ResourcesDesc(this, null, null, null);
+
+ /** the application description */
+ protected Object launchType;
+
+ /** the security descriptor */
+ protected SecurityDesc security;
+
+ /** the default OS */
+ protected Locale defaultLocale = null;
+
+ /** the default arch */
+ protected String defaultOS = null;
+
+ /** the default jvm */
+ protected String defaultArch = null;
+
+ { // initialize defaults if security allows
+ try {
+ defaultLocale = Locale.getDefault();
+ defaultOS = System.getProperty("os.name");
+ defaultArch = System.getProperty("os.arch");
+ }
+ catch (SecurityException ex) {
+ // null values will still work, and app can set defaults later
+ }
+ }
+
+ /**
+ * Empty stub, allowing child classes to override the constructor
+ */
+ protected JNLPFile() {
+ }
+
+ /**
+ * Create a JNLPFile from a URL.
+ *
+ * @param location the location of the JNLP file
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ public JNLPFile(URL location) throws IOException, ParseException {
+ this(location, false); // not strict
+ }
+
+ /**
+ * Create a JNLPFile from a URL checking for updates using the
+ * default policy.
+ *
+ * @param location the location of the JNLP file
+ * @param strict whether to enforce the spec when
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ public JNLPFile(URL location, boolean strict) throws IOException, ParseException {
+ this(location, (Version) null, strict);
+ }
+
+ /**
+ * Create a JNLPFile from a URL and a Version checking for updates using
+ * the default policy.
+ *
+ * @param location the location of the JNLP file
+ * @param version the version of the JNLP file
+ * @param strict whether to enforce the spec when
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ public JNLPFile(URL location, Version version, boolean strict) throws IOException, ParseException {
+ this(location, version, strict, JNLPRuntime.getDefaultUpdatePolicy());
+ }
+
+ /**
+ * Create a JNLPFile from a URL and a version, checking for updates
+ * using the specified policy.
+ *
+ * @param location the location of the JNLP file
+ * @param version the version of the JNLP file
+ * @param strict whether to enforce the spec when
+ * @param policy the update policy
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ public JNLPFile(URL location, Version version, boolean strict, UpdatePolicy policy) throws IOException, ParseException {
+ Node root = Parser.getRootNode(openURL(location, version, policy));
+ parse(root, strict, location);
+
+ //Downloads the original jnlp file into the cache if possible
+ //(i.e. If the jnlp file being launched exist locally, but it
+ //originated from a website, then download the one from the website
+ //into the cache).
+ if (sourceLocation != null && location.getProtocol() == "file") {
+ openURL(sourceLocation, version, policy);
+ }
+
+ this.fileLocation = location;
+
+ this.uniqueKey = Calendar.getInstance().getTimeInMillis() + "-" +
+ Math.abs(((new java.util.Random()).nextInt())) + "-" +
+ location;
+
+ if (JNLPRuntime.isDebug())
+ System.err.println("UNIQUEKEY=" + this.uniqueKey);
+ }
+
+ /**
+ * Create a JNLPFile from a URL, parent URLm a version and checking for
+ * updates using the specified policy.
+ *
+ * @param location the location of the JNLP file
+ * @param uniqueKey A string that uniquely identifies connected instances
+ * @param version the version of the JNLP file
+ * @param strict whether to enforce the spec when
+ * @param policy the update policy
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ public JNLPFile(URL location, String uniqueKey, Version version, boolean strict, UpdatePolicy policy) throws IOException, ParseException {
+ this(location, version, strict, policy);
+ this.uniqueKey = uniqueKey;
+
+ if (JNLPRuntime.isDebug())
+ System.err.println("UNIQUEKEY (override) =" + this.uniqueKey);
+ }
+
+ /**
+ * Create a JNLPFile from an input stream.
+ *
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ public JNLPFile(InputStream input, boolean strict) throws ParseException {
+ parse(Parser.getRootNode(input), strict, null);
+ }
+
+ /**
+ * Create a JNLPFile from a character stream.
+ *
+ * @param input the stream
+ * @param strict whether to enforce the spec when
+ * @throws IOException if an IO exception occurred
+ * @throws ParseException if the JNLP file was invalid
+ */
+ private JNLPFile(Reader input, boolean strict) throws ParseException {
+ // todo: now that we are using NanoXML we can use a Reader
+ //parse(Parser.getRootNode(input), strict, null);
+ }
+
+
+ /**
+ * Open the jnlp file URL from the cache if there, otherwise
+ * download to the cache. Called from constructor.
+ */
+ private static InputStream openURL(URL location, Version version, UpdatePolicy policy) throws IOException {
+ if (location == null || policy == null)
+ throw new IllegalArgumentException(R("NullParameter"));
+
+ try {
+ ResourceTracker tracker = new ResourceTracker(false); // no prefetch
+ tracker.addResource(location, version , policy);
+
+ return tracker.getInputStream(location);
+ }
+ catch (Exception ex) {
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Returns the JNLP specification versions supported.
+ */
+ public static Version getSupportedVersions() {
+ return Parser.getSupportedVersions();
+ }
+
+ /**
+ * Returns the JNLP file's title. This method returns the same
+ * value as InformationDesc.getTitle().
+ */
+ public String getTitle() {
+ return getInformation().getTitle();
+ }
+
+ /**
+ * Returns the JNLP file's network location as specified in the
+ * JNLP file.
+ */
+ public URL getSourceLocation() {
+ return sourceLocation;
+ }
+
+ /**
+ * Returns the location of the file parsed to create the JNLP
+ * file, or null if it was not created from a URL.
+ */
+ public URL getFileLocation() {
+ return fileLocation;
+ }
+
+ /**
+ * Returns the location of the parent file if it exists, null otherwise
+ */
+ public String getUniqueKey() {
+ return uniqueKey;
+ }
+
+ /**
+ * Returns the JNLP file's version.
+ */
+ public Version getFileVersion() {
+ return fileVersion;
+ }
+
+ /**
+ * Returns the specification version required by the file.
+ */
+ public Version getSpecVersion() {
+ return specVersion;
+ }
+
+ /**
+ * Returns the codebase URL for the JNLP file.
+ */
+ public URL getCodeBase() {
+ return codeBase;
+ }
+
+ /**
+ * Returns the information section of the JNLP file as viewed
+ * through the default locale.
+ */
+ public InformationDesc getInformation() {
+ return getInformation(defaultLocale);
+ }
+
+ /**
+ * Returns the information section of the JNLP file as viewed
+ * through the specified locale.
+ */
+ public InformationDesc getInformation(final Locale locale) {
+ return new InformationDesc(this, new Locale[] {locale}) {
+ protected List getItems(Object key) {
+ List result = new ArrayList();
+
+ for (int i=0; i < info.size(); i++) {
+ InformationDesc infoDesc = (InformationDesc) info.get(i);
+
+ if (localMatches(locale, infoDesc.getLocales()))
+ if (localMatches(locale, infoDesc.getLocales()))
+ result.addAll(infoDesc.getItems(key) );
+ }
+
+ return result;
+ }
+ };
+ }
+
+ /**
+ * Returns the update section of the JNLP file.
+ */
+ public UpdateDesc getUpdate() {
+ return update;
+ }
+
+ /**
+ * Returns the security section of the JNLP file.
+ */
+ public SecurityDesc getSecurity() {
+ return security;
+ }
+
+ /**
+ * Returns the resources section of the JNLP file as viewed
+ * through the default locale and the os.name and os.arch
+ * properties.
+ */
+ public ResourcesDesc getResources() {
+ return getResources(defaultLocale, defaultOS, defaultArch);
+ }
+
+ /**
+ * Returns the information section of the JNLP file for the
+ * specified locale, os, and arch.
+ */
+ public ResourcesDesc getResources(final Locale locale, final String os, final String arch) {
+ return new ResourcesDesc(this, new Locale[] {locale}, new String[] {os}, new String[] {arch}) {
+ public List getResources(Class launchType) {
+ List result = new ArrayList();
+
+ for (int i=0; i < resources.size(); i++) {
+ ResourcesDesc rescDesc = (ResourcesDesc) resources.get(i);
+
+ if (localMatches(locale, rescDesc.getLocales())
+ && stringMatches(os, rescDesc.getOS())
+ && stringMatches(arch, rescDesc.getArch()))
+ result.addAll(rescDesc.getResources(launchType) );
+ }
+
+ result.addAll(sharedResources.getResources(launchType));
+
+ return result;
+ }
+
+ public void addResource(Object resource) {
+ // todo: honor the current locale, os, arch values
+ sharedResources.addResource(resource);
+ }
+ };
+ }
+
+ /**
+ * Returns an object of one of the following types: AppletDesc,
+ * ApplicationDesc, InstallerDesc, and ComponentDesc.
+ */
+ public Object getLaunchInfo() {
+ return launchType;
+ }
+
+ /**
+ * Returns the launch information for an applet.
+ *
+ * @throws UnsupportedOperationException if there is no applet information
+ */
+ public AppletDesc getApplet() {
+ if (!isApplet())
+ throw new UnsupportedOperationException(R("JNotApplet"));
+
+ return (AppletDesc) launchType;
+ }
+
+ /**
+ * Returns the launch information for an application.
+ *
+ * @throws UnsupportedOperationException if there is no application information
+ */
+ public ApplicationDesc getApplication() {
+ if (!isApplication())
+ throw new UnsupportedOperationException(R("JNotApplication"));
+
+ return (ApplicationDesc) launchType;
+ }
+
+ /**
+ * Returns the launch information for a component.
+ *
+ * @throws UnsupportedOperationException if there is no component information
+ */
+ public ComponentDesc getComponent() {
+ if (!isComponent())
+ throw new UnsupportedOperationException(R("JNotComponent"));
+
+ return (ComponentDesc) launchType;
+ }
+
+ /**
+ * Returns the launch information for an installer.
+ *
+ * @throws UnsupportedOperationException if there is no installer information
+ */
+ public InstallerDesc getInstaller() {
+ if (!isInstaller())
+ throw new UnsupportedOperationException(R("NotInstaller"));
+
+ return (InstallerDesc) launchType;
+ }
+
+ /**
+ * Returns whether the lauch descriptor describes an Applet.
+ */
+ public boolean isApplet() {
+ return launchType instanceof AppletDesc;
+ }
+
+ /**
+ * Returns whether the lauch descriptor describes an Application.
+ */
+ public boolean isApplication() {
+ return launchType instanceof ApplicationDesc;
+ }
+
+ /**
+ * Returns whether the lauch descriptor describes a Component.
+ */
+ public boolean isComponent() {
+ return launchType instanceof ComponentDesc;
+ }
+
+ /**
+ * Returns whether the lauch descriptor describes an Installer.
+ */
+ public boolean isInstaller() {
+ return launchType instanceof InstallerDesc;
+ }
+
+ /**
+ * Sets the default view of the JNLP file returned by
+ * getInformation, getResources, etc. If unset, the defaults
+ * are the properties os.name, os.arch, and the locale returned
+ * by Locale.getDefault().
+ */
+ public void setDefaults(String os, String arch, Locale locale) {
+ defaultOS = os;
+ defaultArch = arch;
+ defaultLocale = locale;
+ }
+
+
+ /**
+ * Returns whether a locale is matched by one of more other
+ * locales. Only the non-empty language, country, and variant
+ * codes are compared; for example, a requested locale of
+ * Locale("","","") would always return true.
+ *
+ * @param requested the local
+ * @param available the available locales
+ * @return true if requested matches any of available, or if
+ * available is empty or null.
+ */
+ private boolean localMatches(Locale requested, Locale available[]) {
+ if (available == null || available.length == 0)
+ return true;
+
+ for (int i=0; i < available.length; i++) {
+ String language = requested.getLanguage(); // "" but never null
+ String country = requested.getCountry();
+ String variant = requested.getVariant();
+
+ if (!"".equals(language) && !language.equalsIgnoreCase(available[i].getLanguage()))
+ continue;
+ if (!"".equals(country) && !country.equalsIgnoreCase(available[i].getCountry()))
+ continue;
+ if (!"".equals(variant) && !variant.equalsIgnoreCase(available[i].getVariant()))
+ continue;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether the string is a prefix for any of the strings
+ * in the specified array.
+ *
+ * @param prefixStr the prefix string
+ * @param available the strings to test
+ * @return true if prefixStr is a prefix of any strings in
+ * available, or if available is empty or null.
+ */
+ private boolean stringMatches(String prefixStr, String available[]) {
+ if (available == null || available.length == 0)
+ return true;
+
+ for (int i=0; i < available.length; i++)
+ if (available[i] != null && available[i].startsWith(prefixStr))
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Initialize the JNLPFile fields. Private because it's called
+ * from the constructor.
+ *
+ * @param root the root node
+ * @param strict whether to enforce the spec when
+ * @param location the file location or null
+ */
+ private void parse(Node root, boolean strict, URL location) throws ParseException {
+ try {
+ //if (location != null)
+ // location = new URL(location, "."); // remove filename
+
+ Parser parser = new Parser(this, location, root, strict, true); // true == allow extensions
+
+ // JNLP tag information
+ specVersion = parser.getSpecVersion();
+ fileVersion = parser.getFileVersion();
+ codeBase = parser.getCodeBase();
+ sourceLocation = parser.getFileLocation() != null ? parser.getFileLocation() : location;
+ info = parser.getInfo(root);
+ update = parser.getUpdate(root);
+ resources = parser.getResources(root, false); // false == not a j2se/java resources section
+ launchType = parser.getLauncher(root);
+ security = parser.getSecurity(root);
+ }
+ catch (ParseException ex) {
+ throw ex;
+ }
+ catch (Exception ex) {
+ if (JNLPRuntime.isDebug())
+ ex.printStackTrace();
+
+ throw new RuntimeException(ex.toString());
+ }
+ }
+
+ /**
+ *
+ * @return true if the JNLP file specifies things that can only be
+ * applied on a new vm (eg: different max heap memory)
+ */
+ public boolean needsNewVM() {
+
+ if (getNewVMArgs().size() == 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * @return a list of args to pass to the new
+ * JVM based on this JNLP file
+ */
+ public List<String> getNewVMArgs() {
+
+ List<String> newVMArgs = new LinkedList<String>();
+
+ JREDesc[] jres = getResources().getJREs();
+ for (int jreIndex = 0; jreIndex < jres.length; jreIndex++) {
+ String initialHeapSize = jres[jreIndex].getInitialHeapSize();
+ if (initialHeapSize != null) {
+ newVMArgs.add("-Xms" + initialHeapSize);
+ }
+
+ String maxHeapSize = jres[jreIndex].getMaximumHeapSize();
+ if (maxHeapSize != null) {
+ newVMArgs.add("-Xmx" + maxHeapSize);
+ }
+
+ String vmArgsFromJre = jres[jreIndex].getVMArgs();
+ if (vmArgsFromJre != null) {
+ String[] args = vmArgsFromJre.split(" ");
+ newVMArgs.addAll(Arrays.asList(args));
+ }
+ }
+
+ return newVMArgs;
+ }
+
+}