view netx/net/sourceforge/jnlp/JNLPFile.java @ 1842:31b0ba36a6b7

Completely restructure the building and inclusion of netx and plugin code. We were relying on the binary plugs process (and thus importing unneeded SNMP classes). We now use the same method as jaxws, jaxp, langtools and corba, and the binary plugs process is turned off (the default, we were turning it on by setting ALT_BINARY_PLUGS_PATH). 2009-05-27 Andrew John Hughes <ahughes@redhat.com> * overlays/openjdk/jdk/src/share/classes/javax/jnlp/BasicService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ClipboardService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/DownloadService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/DownloadServiceListener.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ExtensionInstallerService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/FileContents.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/FileOpenService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/FileSaveService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/JNLPRandomAccessFile.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/PersistenceService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/PrintService.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ServiceManager.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/ServiceManagerStub.java, * overlays/openjdk/jdk/src/share/classes/javax/jnlp/UnavailableServiceException.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/AppletDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ApplicationDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ComponentDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/DefaultLaunchHandler.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ExtensionDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/IconDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/InformationDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/InstallerDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JARDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JNLPFile.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JNLPSplashScreen.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JREDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/LaunchException.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/LaunchHandler.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Launcher.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Node.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/PackageDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ParseException.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Parser.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/PluginBridge.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/PropertyDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/ResourcesDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/SecurityDesc.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/Version.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/CacheEntry.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/CacheUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/DefaultDownloadIndicator.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/DownloadIndicator.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/Resource.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/ResourceTracker.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/UpdatePolicy.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/cache/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/ApplicationEvent.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/ApplicationListener.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/DownloadEvent.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/DownloadListener.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/event/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/Manifest.mf, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/Messages.properties, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/about.jnlp, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/resources/default.jnlp, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppThreadGroup.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppletAudioClip.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppletEnvironment.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/AppletInstance.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/ApplicationInstance.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/Boot.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/Boot13.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPRuntime.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AppletWarningPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/CertVerifier.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/CertWarningPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/CertsInfoPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/HttpsCertVerifier.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/MoreInfoPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SecurityDialogUI.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SecurityUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SecurityWarningDialog.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/SingleCertInfoPane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/VariableX509TrustManager.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/viewer/CertificatePane.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/viewer/CertificateViewer.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/ServiceUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XBasicService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XClipboardService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XDownloadService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XExtensionInstallerService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XFileContents.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XFileOpenService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XFileSaveService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XJNLPRandomAccessFile.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XPersistenceService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XPrintService.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/XServiceManagerStub.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/services/package.html, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/CharacterEncoder.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/HexDumpEncoder.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarRunner.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSignerResources.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/KeyStoreUtil.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/KeyTool.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/util/PropertiesFile.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/util/Reflect.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/util/WeakList.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/nanoxml/XMLElement.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/nanoxml/XMLParseException.java: Moved to... * Makefile.am: Remove use of ALT_BINARY_PLUGS_PATH (and thus turn off the binary plugs build), add a INITIAL_BOOTSTRAP_LINK_STAMP target which allows us to depend on $(ICEDTEA_BOOT_DIR) for both types of build, output to lib/tools.jar not jre/lib/tools.jar, add targets for building netx and liveconnect classes and make icedtea targets dependent on this. * netx/javax/jnlp/BasicService.java, * netx/javax/jnlp/ClipboardService.java, * netx/javax/jnlp/DownloadService.java, * netx/javax/jnlp/DownloadServiceListener.java, * netx/javax/jnlp/ExtensionInstallerService.java, * netx/javax/jnlp/FileContents.java, * netx/javax/jnlp/FileOpenService.java, * netx/javax/jnlp/FileSaveService.java, * netx/javax/jnlp/JNLPRandomAccessFile.java, * netx/javax/jnlp/PersistenceService.java, * netx/javax/jnlp/PrintService.java, * netx/javax/jnlp/ServiceManager.java, * netx/javax/jnlp/ServiceManagerStub.java, * netx/javax/jnlp/UnavailableServiceException.java, * netx/net/sourceforge/jnlp/AppletDesc.java, * netx/net/sourceforge/jnlp/ApplicationDesc.java, * netx/net/sourceforge/jnlp/ComponentDesc.java, * netx/net/sourceforge/jnlp/DefaultLaunchHandler.java, * netx/net/sourceforge/jnlp/ExtensionDesc.java, * netx/net/sourceforge/jnlp/IconDesc.java, * netx/net/sourceforge/jnlp/InformationDesc.java, * netx/net/sourceforge/jnlp/InstallerDesc.java, * netx/net/sourceforge/jnlp/JARDesc.java, * netx/net/sourceforge/jnlp/JNLPFile.java, * netx/net/sourceforge/jnlp/JNLPSplashScreen.java, * netx/net/sourceforge/jnlp/JREDesc.java, * netx/net/sourceforge/jnlp/LaunchException.java, * netx/net/sourceforge/jnlp/LaunchHandler.java, * netx/net/sourceforge/jnlp/Launcher.java, * netx/net/sourceforge/jnlp/NetxPanel.java, * netx/net/sourceforge/jnlp/Node.java, * netx/net/sourceforge/jnlp/PackageDesc.java, * netx/net/sourceforge/jnlp/ParseException.java, * netx/net/sourceforge/jnlp/Parser.java, * netx/net/sourceforge/jnlp/PluginBridge.java, * netx/net/sourceforge/jnlp/PropertyDesc.java, * netx/net/sourceforge/jnlp/ResourcesDesc.java, * netx/net/sourceforge/jnlp/SecurityDesc.java, * netx/net/sourceforge/jnlp/Version.java, * netx/net/sourceforge/jnlp/cache/CacheEntry.java, * netx/net/sourceforge/jnlp/cache/CacheUtil.java, * netx/net/sourceforge/jnlp/cache/DefaultDownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/DownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/Resource.java, * netx/net/sourceforge/jnlp/cache/ResourceTracker.java, * netx/net/sourceforge/jnlp/cache/UpdatePolicy.java, * netx/net/sourceforge/jnlp/cache/package.html, * netx/net/sourceforge/jnlp/event/ApplicationEvent.java, * netx/net/sourceforge/jnlp/event/ApplicationListener.java, * netx/net/sourceforge/jnlp/event/DownloadEvent.java, * netx/net/sourceforge/jnlp/event/DownloadListener.java, * netx/net/sourceforge/jnlp/event/package.html, * netx/net/sourceforge/jnlp/package.html, * netx/net/sourceforge/jnlp/resources/Manifest.mf, * netx/net/sourceforge/jnlp/resources/Messages.properties, * netx/net/sourceforge/jnlp/resources/about.jnlp, * netx/net/sourceforge/jnlp/resources/default.jnlp, * netx/net/sourceforge/jnlp/runtime/AppThreadGroup.java, * netx/net/sourceforge/jnlp/runtime/AppletAudioClip.java, * netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java, * netx/net/sourceforge/jnlp/runtime/AppletInstance.java, * netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java, * netx/net/sourceforge/jnlp/runtime/Boot.java, * netx/net/sourceforge/jnlp/runtime/Boot13.java, * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * netx/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java, * netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, * netx/net/sourceforge/jnlp/runtime/package.html, * netx/net/sourceforge/jnlp/security/AccessWarningPane.java, * netx/net/sourceforge/jnlp/security/AppletWarningPane.java, * netx/net/sourceforge/jnlp/security/CertVerifier.java, * netx/net/sourceforge/jnlp/security/CertWarningPane.java, * netx/net/sourceforge/jnlp/security/CertsInfoPane.java, * netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java, * netx/net/sourceforge/jnlp/security/MoreInfoPane.java, * netx/net/sourceforge/jnlp/security/SecurityDialogUI.java, * netx/net/sourceforge/jnlp/security/SecurityUtil.java, * netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java, * netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java, * netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java, * netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java, * netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java, * netx/net/sourceforge/jnlp/services/ServiceUtil.java, * netx/net/sourceforge/jnlp/services/XBasicService.java, * netx/net/sourceforge/jnlp/services/XClipboardService.java, * netx/net/sourceforge/jnlp/services/XDownloadService.java, * netx/net/sourceforge/jnlp/services/XExtensionInstallerService.java, * netx/net/sourceforge/jnlp/services/XFileContents.java, * netx/net/sourceforge/jnlp/services/XFileOpenService.java, * netx/net/sourceforge/jnlp/services/XFileSaveService.java, * netx/net/sourceforge/jnlp/services/XJNLPRandomAccessFile.java, * netx/net/sourceforge/jnlp/services/XPersistenceService.java, * netx/net/sourceforge/jnlp/services/XPrintService.java, * netx/net/sourceforge/jnlp/services/XServiceManagerStub.java, * netx/net/sourceforge/jnlp/services/package.html, * netx/net/sourceforge/jnlp/tools/CharacterEncoder.java, * netx/net/sourceforge/jnlp/tools/HexDumpEncoder.java, * netx/net/sourceforge/jnlp/tools/JarRunner.java, * netx/net/sourceforge/jnlp/tools/JarSigner.java, * netx/net/sourceforge/jnlp/tools/JarSignerResources.java, * netx/net/sourceforge/jnlp/tools/KeyStoreUtil.java, * netx/net/sourceforge/jnlp/tools/KeyTool.java, * netx/net/sourceforge/jnlp/util/PropertiesFile.java, * netx/net/sourceforge/jnlp/util/Reflect.java, * netx/net/sourceforge/jnlp/util/WeakList.java, * netx/net/sourceforge/nanoxml/XMLElement.java, * netx/net/sourceforge/nanoxml/XMLParseException.java: to here. * patches/ecj/icedtea.patch: Recreated. * patches/icedtea-ant.patch: Remove hack to jaxws which uses plugs directory (now undefined). * patches/icedtea-javac-debuginfo.patch: Recreated. * patches/icedtea-netx.patch: Include netx and netscape classes via the same import mechanism as jaxws, jaxp, corba and langtools (extracting a classes.zip).
author Andrew John Hughes <ahughes@redhat.com>
date Thu, 28 May 2009 10:18:19 +0100
parents overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/JNLPFile.java@8dc304404e01
children
line wrap: on
line source

// 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.*;
import java.net.*;
import java.util.*;

import net.sourceforge.jnlp.cache.*;
import net.sourceforge.jnlp.runtime.*;

/**
 * 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:jmaxwell@users.sourceforge.net">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;

    /** the URL used to resolve relative URLs in the file */
    protected URL codeBase;
    
    /** cookie string to send alongwith resource requests */
    protected String cookieStr;

    /** file version */
    protected Version fileVersion;

    /** spec version */
    protected Version specVersion;

    /** information */
    protected List info;

    /** 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, String cookieStr) throws IOException, ParseException {
        this(location, cookieStr, 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, String cookieStr, boolean strict) throws IOException, ParseException {
        this(location, cookieStr, strict, JNLPRuntime.getDefaultUpdatePolicy());
    }

    /**
     * Create a JNLPFile from a URL checking for updates using the
     * specified policy.
     *
     * @param location the location 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 cookieStr, boolean strict, UpdatePolicy policy) throws IOException, ParseException {
        Node root = Parser.getRootNode(openURL(location, cookieStr, policy));
        parse(root, strict, location);

        this.fileLocation = location;
        this.cookieStr = cookieStr;
    }

    /**
     * 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, String cookieStr, 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, cookieStr, null/*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 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 cookie string that will be send when resources for this file are requested 
     */
    public String getCookieStr() {
        return cookieStr;
    }
    
    /**
     * 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 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();

            info = parser.getInfo(root);
            resources = parser.getResources(root, false); // false == not a j2se 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());
        }
    }

}