emul/mini/src/main/java/java/net/URL.java
brancharithmetic
changeset 774 42bc1e89134d
parent 755 5652acd48509
parent 773 406faa8bc64f
child 778 6f8683517f1f
     1.1 --- a/emul/mini/src/main/java/java/net/URL.java	Mon Feb 25 19:00:08 2013 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1090 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.  Oracle designates this
    1.11 - * particular file as subject to the "Classpath" exception as provided
    1.12 - * by Oracle in the LICENSE file that accompanied this code.
    1.13 - *
    1.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 - * version 2 for more details (a copy is included in the LICENSE file that
    1.18 - * accompanied this code).
    1.19 - *
    1.20 - * You should have received a copy of the GNU General Public License version
    1.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 - *
    1.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 - * or visit www.oracle.com if you need additional information or have any
    1.26 - * questions.
    1.27 - */
    1.28 -
    1.29 -package java.net;
    1.30 -
    1.31 -import java.io.ByteArrayInputStream;
    1.32 -import java.io.IOException;
    1.33 -import java.io.InputStream;
    1.34 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
    1.35 -
    1.36 -
    1.37 -/**
    1.38 - * Class <code>URL</code> represents a Uniform Resource
    1.39 - * Locator, a pointer to a "resource" on the World
    1.40 - * Wide Web. A resource can be something as simple as a file or a
    1.41 - * directory, or it can be a reference to a more complicated object,
    1.42 - * such as a query to a database or to a search engine. More
    1.43 - * information on the types of URLs and their formats can be found at:
    1.44 - * <blockquote>
    1.45 - *     <a href="http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html">
    1.46 - *    <i>http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html</i></a>
    1.47 - * </blockquote>
    1.48 - * <p>
    1.49 - * In general, a URL can be broken into several parts. The previous
    1.50 - * example of a URL indicates that the protocol to use is
    1.51 - * <code>http</code> (HyperText Transfer Protocol) and that the
    1.52 - * information resides on a host machine named
    1.53 - * <code>www.socs.uts.edu.au</code>. The information on that host
    1.54 - * machine is named <code>/MosaicDocs-old/url-primer.html</code>. The exact
    1.55 - * meaning of this name on the host machine is both protocol
    1.56 - * dependent and host dependent. The information normally resides in
    1.57 - * a file, but it could be generated on the fly. This component of
    1.58 - * the URL is called the <i>path</i> component.
    1.59 - * <p>
    1.60 - * A URL can optionally specify a "port", which is the
    1.61 - * port number to which the TCP connection is made on the remote host
    1.62 - * machine. If the port is not specified, the default port for
    1.63 - * the protocol is used instead. For example, the default port for
    1.64 - * <code>http</code> is <code>80</code>. An alternative port could be
    1.65 - * specified as:
    1.66 - * <blockquote><pre>
    1.67 - *     http://www.socs.uts.edu.au:80/MosaicDocs-old/url-primer.html
    1.68 - * </pre></blockquote>
    1.69 - * <p>
    1.70 - * The syntax of <code>URL</code> is defined by  <a
    1.71 - * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform
    1.72 - * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a
    1.73 - * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for
    1.74 - * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format
    1.75 - * also supports scope_ids. The syntax and usage of scope_ids is described
    1.76 - * <a href="Inet6Address.html#scoped">here</a>.
    1.77 - * <p>
    1.78 - * A URL may have appended to it a "fragment", also known
    1.79 - * as a "ref" or a "reference". The fragment is indicated by the sharp
    1.80 - * sign character "#" followed by more characters. For example,
    1.81 - * <blockquote><pre>
    1.82 - *     http://java.sun.com/index.html#chapter1
    1.83 - * </pre></blockquote>
    1.84 - * <p>
    1.85 - * This fragment is not technically part of the URL. Rather, it
    1.86 - * indicates that after the specified resource is retrieved, the
    1.87 - * application is specifically interested in that part of the
    1.88 - * document that has the tag <code>chapter1</code> attached to it. The
    1.89 - * meaning of a tag is resource specific.
    1.90 - * <p>
    1.91 - * An application can also specify a "relative URL",
    1.92 - * which contains only enough information to reach the resource
    1.93 - * relative to another URL. Relative URLs are frequently used within
    1.94 - * HTML pages. For example, if the contents of the URL:
    1.95 - * <blockquote><pre>
    1.96 - *     http://java.sun.com/index.html
    1.97 - * </pre></blockquote>
    1.98 - * contained within it the relative URL:
    1.99 - * <blockquote><pre>
   1.100 - *     FAQ.html
   1.101 - * </pre></blockquote>
   1.102 - * it would be a shorthand for:
   1.103 - * <blockquote><pre>
   1.104 - *     http://java.sun.com/FAQ.html
   1.105 - * </pre></blockquote>
   1.106 - * <p>
   1.107 - * The relative URL need not specify all the components of a URL. If
   1.108 - * the protocol, host name, or port number is missing, the value is
   1.109 - * inherited from the fully specified URL. The file component must be
   1.110 - * specified. The optional fragment is not inherited.
   1.111 - * <p>
   1.112 - * The URL class does not itself encode or decode any URL components
   1.113 - * according to the escaping mechanism defined in RFC2396. It is the
   1.114 - * responsibility of the caller to encode any fields, which need to be
   1.115 - * escaped prior to calling URL, and also to decode any escaped fields,
   1.116 - * that are returned from URL. Furthermore, because URL has no knowledge
   1.117 - * of URL escaping, it does not recognise equivalence between the encoded
   1.118 - * or decoded form of the same URL. For example, the two URLs:<br>
   1.119 - * <pre>    http://foo.com/hello world/ and http://foo.com/hello%20world</pre>
   1.120 - * would be considered not equal to each other.
   1.121 - * <p>
   1.122 - * Note, the {@link java.net.URI} class does perform escaping of its
   1.123 - * component fields in certain circumstances. The recommended way
   1.124 - * to manage the encoding and decoding of URLs is to use {@link java.net.URI},
   1.125 - * and to convert between these two classes using {@link #toURI()} and
   1.126 - * {@link URI#toURL()}.
   1.127 - * <p>
   1.128 - * The {@link URLEncoder} and {@link URLDecoder} classes can also be
   1.129 - * used, but only for HTML form encoding, which is not the same
   1.130 - * as the encoding scheme defined in RFC2396.
   1.131 - *
   1.132 - * @author  James Gosling
   1.133 - * @since JDK1.0
   1.134 - */
   1.135 -public final class URL implements java.io.Serializable {
   1.136 -
   1.137 -    static final long serialVersionUID = -7627629688361524110L;
   1.138 -
   1.139 -    /**
   1.140 -     * The property which specifies the package prefix list to be scanned
   1.141 -     * for protocol handlers.  The value of this property (if any) should
   1.142 -     * be a vertical bar delimited list of package names to search through
   1.143 -     * for a protocol handler to load.  The policy of this class is that
   1.144 -     * all protocol handlers will be in a class called <protocolname>.Handler,
   1.145 -     * and each package in the list is examined in turn for a matching
   1.146 -     * handler.  If none are found (or the property is not specified), the
   1.147 -     * default package prefix, sun.net.www.protocol, is used.  The search
   1.148 -     * proceeds from the first package in the list to the last and stops
   1.149 -     * when a match is found.
   1.150 -     */
   1.151 -    private static final String protocolPathProp = "java.protocol.handler.pkgs";
   1.152 -
   1.153 -    /**
   1.154 -     * The protocol to use (ftp, http, nntp, ... etc.) .
   1.155 -     * @serial
   1.156 -     */
   1.157 -    private String protocol;
   1.158 -
   1.159 -    /**
   1.160 -     * The host name to connect to.
   1.161 -     * @serial
   1.162 -     */
   1.163 -    private String host;
   1.164 -
   1.165 -    /**
   1.166 -     * The protocol port to connect to.
   1.167 -     * @serial
   1.168 -     */
   1.169 -    private int port = -1;
   1.170 -
   1.171 -    /**
   1.172 -     * The specified file name on that host. <code>file</code> is
   1.173 -     * defined as <code>path[?query]</code>
   1.174 -     * @serial
   1.175 -     */
   1.176 -    private String file;
   1.177 -
   1.178 -    /**
   1.179 -     * The query part of this URL.
   1.180 -     */
   1.181 -    private transient String query;
   1.182 -
   1.183 -    /**
   1.184 -     * The authority part of this URL.
   1.185 -     * @serial
   1.186 -     */
   1.187 -    private String authority;
   1.188 -
   1.189 -    /**
   1.190 -     * The path part of this URL.
   1.191 -     */
   1.192 -    private transient String path;
   1.193 -
   1.194 -    /**
   1.195 -     * The userinfo part of this URL.
   1.196 -     */
   1.197 -    private transient String userInfo;
   1.198 -
   1.199 -    /**
   1.200 -     * # reference.
   1.201 -     * @serial
   1.202 -     */
   1.203 -    private String ref;
   1.204 -
   1.205 -    /**
   1.206 -     * The host's IP address, used in equals and hashCode.
   1.207 -     * Computed on demand. An uninitialized or unknown hostAddress is null.
   1.208 -     */
   1.209 -    transient Object hostAddress;
   1.210 -
   1.211 -    /**
   1.212 -     * The URLStreamHandler for this URL.
   1.213 -     */
   1.214 -    transient URLStreamHandler handler;
   1.215 -
   1.216 -    /* Our hash code.
   1.217 -     * @serial
   1.218 -     */
   1.219 -    private int hashCode = -1;
   1.220 -    
   1.221 -    /** input stream associated with the URL */
   1.222 -    private InputStream is;
   1.223 -
   1.224 -    /**
   1.225 -     * Creates a <code>URL</code> object from the specified
   1.226 -     * <code>protocol</code>, <code>host</code>, <code>port</code>
   1.227 -     * number, and <code>file</code>.<p>
   1.228 -     *
   1.229 -     * <code>host</code> can be expressed as a host name or a literal
   1.230 -     * IP address. If IPv6 literal address is used, it should be
   1.231 -     * enclosed in square brackets (<tt>'['</tt> and <tt>']'</tt>), as
   1.232 -     * specified by <a
   1.233 -     * href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>;
   1.234 -     * However, the literal IPv6 address format defined in <a
   1.235 -     * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IP
   1.236 -     * Version 6 Addressing Architecture</i></a> is also accepted.<p>
   1.237 -     *
   1.238 -     * Specifying a <code>port</code> number of <code>-1</code>
   1.239 -     * indicates that the URL should use the default port for the
   1.240 -     * protocol.<p>
   1.241 -     *
   1.242 -     * If this is the first URL object being created with the specified
   1.243 -     * protocol, a <i>stream protocol handler</i> object, an instance of
   1.244 -     * class <code>URLStreamHandler</code>, is created for that protocol:
   1.245 -     * <ol>
   1.246 -     * <li>If the application has previously set up an instance of
   1.247 -     *     <code>URLStreamHandlerFactory</code> as the stream handler factory,
   1.248 -     *     then the <code>createURLStreamHandler</code> method of that instance
   1.249 -     *     is called with the protocol string as an argument to create the
   1.250 -     *     stream protocol handler.
   1.251 -     * <li>If no <code>URLStreamHandlerFactory</code> has yet been set up,
   1.252 -     *     or if the factory's <code>createURLStreamHandler</code> method
   1.253 -     *     returns <code>null</code>, then the constructor finds the
   1.254 -     *     value of the system property:
   1.255 -     *     <blockquote><pre>
   1.256 -     *         java.protocol.handler.pkgs
   1.257 -     *     </pre></blockquote>
   1.258 -     *     If the value of that system property is not <code>null</code>,
   1.259 -     *     it is interpreted as a list of packages separated by a vertical
   1.260 -     *     slash character '<code>|</code>'. The constructor tries to load
   1.261 -     *     the class named:
   1.262 -     *     <blockquote><pre>
   1.263 -     *         &lt;<i>package</i>&gt;.&lt;<i>protocol</i>&gt;.Handler
   1.264 -     *     </pre></blockquote>
   1.265 -     *     where &lt;<i>package</i>&gt; is replaced by the name of the package
   1.266 -     *     and &lt;<i>protocol</i>&gt; is replaced by the name of the protocol.
   1.267 -     *     If this class does not exist, or if the class exists but it is not
   1.268 -     *     a subclass of <code>URLStreamHandler</code>, then the next package
   1.269 -     *     in the list is tried.
   1.270 -     * <li>If the previous step fails to find a protocol handler, then the
   1.271 -     *     constructor tries to load from a system default package.
   1.272 -     *     <blockquote><pre>
   1.273 -     *         &lt;<i>system default package</i>&gt;.&lt;<i>protocol</i>&gt;.Handler
   1.274 -     *     </pre></blockquote>
   1.275 -     *     If this class does not exist, or if the class exists but it is not a
   1.276 -     *     subclass of <code>URLStreamHandler</code>, then a
   1.277 -     *     <code>MalformedURLException</code> is thrown.
   1.278 -     * </ol>
   1.279 -     *
   1.280 -     * <p>Protocol handlers for the following protocols are guaranteed
   1.281 -     * to exist on the search path :-
   1.282 -     * <blockquote><pre>
   1.283 -     *     http, https, ftp, file, and jar
   1.284 -     * </pre></blockquote>
   1.285 -     * Protocol handlers for additional protocols may also be
   1.286 -     * available.
   1.287 -     *
   1.288 -     * <p>No validation of the inputs is performed by this constructor.
   1.289 -     *
   1.290 -     * @param      protocol   the name of the protocol to use.
   1.291 -     * @param      host       the name of the host.
   1.292 -     * @param      port       the port number on the host.
   1.293 -     * @param      file       the file on the host
   1.294 -     * @exception  MalformedURLException  if an unknown protocol is specified.
   1.295 -     * @see        java.lang.System#getProperty(java.lang.String)
   1.296 -     * @see        java.net.URL#setURLStreamHandlerFactory(
   1.297 -     *                  java.net.URLStreamHandlerFactory)
   1.298 -     * @see        java.net.URLStreamHandler
   1.299 -     * @see        java.net.URLStreamHandlerFactory#createURLStreamHandler(
   1.300 -     *                  java.lang.String)
   1.301 -     */
   1.302 -    public URL(String protocol, String host, int port, String file)
   1.303 -        throws MalformedURLException
   1.304 -    {
   1.305 -        this(protocol, host, port, file, null);
   1.306 -    }
   1.307 -
   1.308 -    /**
   1.309 -     * Creates a URL from the specified <code>protocol</code>
   1.310 -     * name, <code>host</code> name, and <code>file</code> name. The
   1.311 -     * default port for the specified protocol is used.
   1.312 -     * <p>
   1.313 -     * This method is equivalent to calling the four-argument
   1.314 -     * constructor with the arguments being <code>protocol</code>,
   1.315 -     * <code>host</code>, <code>-1</code>, and <code>file</code>.
   1.316 -     *
   1.317 -     * No validation of the inputs is performed by this constructor.
   1.318 -     *
   1.319 -     * @param      protocol   the name of the protocol to use.
   1.320 -     * @param      host       the name of the host.
   1.321 -     * @param      file       the file on the host.
   1.322 -     * @exception  MalformedURLException  if an unknown protocol is specified.
   1.323 -     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   1.324 -     *                  int, java.lang.String)
   1.325 -     */
   1.326 -    public URL(String protocol, String host, String file)
   1.327 -            throws MalformedURLException {
   1.328 -        this(protocol, host, -1, file);
   1.329 -    }
   1.330 -
   1.331 -    /**
   1.332 -     * Creates a <code>URL</code> object from the specified
   1.333 -     * <code>protocol</code>, <code>host</code>, <code>port</code>
   1.334 -     * number, <code>file</code>, and <code>handler</code>. Specifying
   1.335 -     * a <code>port</code> number of <code>-1</code> indicates that
   1.336 -     * the URL should use the default port for the protocol. Specifying
   1.337 -     * a <code>handler</code> of <code>null</code> indicates that the URL
   1.338 -     * should use a default stream handler for the protocol, as outlined
   1.339 -     * for:
   1.340 -     *     java.net.URL#URL(java.lang.String, java.lang.String, int,
   1.341 -     *                      java.lang.String)
   1.342 -     *
   1.343 -     * <p>If the handler is not null and there is a security manager,
   1.344 -     * the security manager's <code>checkPermission</code>
   1.345 -     * method is called with a
   1.346 -     * <code>NetPermission("specifyStreamHandler")</code> permission.
   1.347 -     * This may result in a SecurityException.
   1.348 -     *
   1.349 -     * No validation of the inputs is performed by this constructor.
   1.350 -     *
   1.351 -     * @param      protocol   the name of the protocol to use.
   1.352 -     * @param      host       the name of the host.
   1.353 -     * @param      port       the port number on the host.
   1.354 -     * @param      file       the file on the host
   1.355 -     * @param      handler    the stream handler for the URL.
   1.356 -     * @exception  MalformedURLException  if an unknown protocol is specified.
   1.357 -     * @exception  SecurityException
   1.358 -     *        if a security manager exists and its
   1.359 -     *        <code>checkPermission</code> method doesn't allow
   1.360 -     *        specifying a stream handler explicitly.
   1.361 -     * @see        java.lang.System#getProperty(java.lang.String)
   1.362 -     * @see        java.net.URL#setURLStreamHandlerFactory(
   1.363 -     *                  java.net.URLStreamHandlerFactory)
   1.364 -     * @see        java.net.URLStreamHandler
   1.365 -     * @see        java.net.URLStreamHandlerFactory#createURLStreamHandler(
   1.366 -     *                  java.lang.String)
   1.367 -     * @see        SecurityManager#checkPermission
   1.368 -     * @see        java.net.NetPermission
   1.369 -     */
   1.370 -    public URL(String protocol, String host, int port, String file,
   1.371 -               URLStreamHandler handler) throws MalformedURLException {
   1.372 -        if (handler != null) {
   1.373 -            throw new SecurityException();
   1.374 -        }
   1.375 -
   1.376 -        protocol = protocol.toLowerCase();
   1.377 -        this.protocol = protocol;
   1.378 -        if (host != null) {
   1.379 -
   1.380 -            /**
   1.381 -             * if host is a literal IPv6 address,
   1.382 -             * we will make it conform to RFC 2732
   1.383 -             */
   1.384 -            if (host.indexOf(':') >= 0 && !host.startsWith("[")) {
   1.385 -                host = "["+host+"]";
   1.386 -            }
   1.387 -            this.host = host;
   1.388 -
   1.389 -            if (port < -1) {
   1.390 -                throw new MalformedURLException("Invalid port number :" +
   1.391 -                                                    port);
   1.392 -            }
   1.393 -            this.port = port;
   1.394 -            authority = (port == -1) ? host : host + ":" + port;
   1.395 -        }
   1.396 -
   1.397 -        Parts parts = new Parts(file);
   1.398 -        path = parts.getPath();
   1.399 -        query = parts.getQuery();
   1.400 -
   1.401 -        if (query != null) {
   1.402 -            this.file = path + "?" + query;
   1.403 -        } else {
   1.404 -            this.file = path;
   1.405 -        }
   1.406 -        ref = parts.getRef();
   1.407 -
   1.408 -        // Note: we don't do validation of the URL here. Too risky to change
   1.409 -        // right now, but worth considering for future reference. -br
   1.410 -        if (handler == null &&
   1.411 -            (handler = getURLStreamHandler(protocol)) == null) {
   1.412 -            throw new MalformedURLException("unknown protocol: " + protocol);
   1.413 -        }
   1.414 -        this.handler = handler;
   1.415 -    }
   1.416 -
   1.417 -    /**
   1.418 -     * Creates a <code>URL</code> object from the <code>String</code>
   1.419 -     * representation.
   1.420 -     * <p>
   1.421 -     * This constructor is equivalent to a call to the two-argument
   1.422 -     * constructor with a <code>null</code> first argument.
   1.423 -     *
   1.424 -     * @param      spec   the <code>String</code> to parse as a URL.
   1.425 -     * @exception  MalformedURLException  if no protocol is specified, or an
   1.426 -     *               unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>.
   1.427 -     * @see        java.net.URL#URL(java.net.URL, java.lang.String)
   1.428 -     */
   1.429 -    public URL(String spec) throws MalformedURLException {
   1.430 -        this(null, spec);
   1.431 -    }
   1.432 -    
   1.433 -    private URL(String spec, InputStream is) throws MalformedURLException {
   1.434 -        this(null, spec);
   1.435 -        this.is = is;
   1.436 -    }
   1.437 -
   1.438 -    /**
   1.439 -     * Creates a URL by parsing the given spec within a specified context.
   1.440 -     *
   1.441 -     * The new URL is created from the given context URL and the spec
   1.442 -     * argument as described in
   1.443 -     * RFC2396 &quot;Uniform Resource Identifiers : Generic * Syntax&quot; :
   1.444 -     * <blockquote><pre>
   1.445 -     *          &lt;scheme&gt;://&lt;authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt;
   1.446 -     * </pre></blockquote>
   1.447 -     * The reference is parsed into the scheme, authority, path, query and
   1.448 -     * fragment parts. If the path component is empty and the scheme,
   1.449 -     * authority, and query components are undefined, then the new URL is a
   1.450 -     * reference to the current document. Otherwise, the fragment and query
   1.451 -     * parts present in the spec are used in the new URL.
   1.452 -     * <p>
   1.453 -     * If the scheme component is defined in the given spec and does not match
   1.454 -     * the scheme of the context, then the new URL is created as an absolute
   1.455 -     * URL based on the spec alone. Otherwise the scheme component is inherited
   1.456 -     * from the context URL.
   1.457 -     * <p>
   1.458 -     * If the authority component is present in the spec then the spec is
   1.459 -     * treated as absolute and the spec authority and path will replace the
   1.460 -     * context authority and path. If the authority component is absent in the
   1.461 -     * spec then the authority of the new URL will be inherited from the
   1.462 -     * context.
   1.463 -     * <p>
   1.464 -     * If the spec's path component begins with a slash character
   1.465 -     * &quot;/&quot; then the
   1.466 -     * path is treated as absolute and the spec path replaces the context path.
   1.467 -     * <p>
   1.468 -     * Otherwise, the path is treated as a relative path and is appended to the
   1.469 -     * context path, as described in RFC2396. Also, in this case,
   1.470 -     * the path is canonicalized through the removal of directory
   1.471 -     * changes made by occurences of &quot;..&quot; and &quot;.&quot;.
   1.472 -     * <p>
   1.473 -     * For a more detailed description of URL parsing, refer to RFC2396.
   1.474 -     *
   1.475 -     * @param      context   the context in which to parse the specification.
   1.476 -     * @param      spec      the <code>String</code> to parse as a URL.
   1.477 -     * @exception  MalformedURLException  if no protocol is specified, or an
   1.478 -     *               unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>.
   1.479 -     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   1.480 -     *                  int, java.lang.String)
   1.481 -     * @see        java.net.URLStreamHandler
   1.482 -     * @see        java.net.URLStreamHandler#parseURL(java.net.URL,
   1.483 -     *                  java.lang.String, int, int)
   1.484 -     */
   1.485 -    public URL(URL context, String spec) throws MalformedURLException {
   1.486 -        this(context, spec, null);
   1.487 -    }
   1.488 -
   1.489 -    /**
   1.490 -     * Creates a URL by parsing the given spec with the specified handler
   1.491 -     * within a specified context. If the handler is null, the parsing
   1.492 -     * occurs as with the two argument constructor.
   1.493 -     *
   1.494 -     * @param      context   the context in which to parse the specification.
   1.495 -     * @param      spec      the <code>String</code> to parse as a URL.
   1.496 -     * @param      handler   the stream handler for the URL.
   1.497 -     * @exception  MalformedURLException  if no protocol is specified, or an
   1.498 -     *               unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>.
   1.499 -     * @exception  SecurityException
   1.500 -     *        if a security manager exists and its
   1.501 -     *        <code>checkPermission</code> method doesn't allow
   1.502 -     *        specifying a stream handler.
   1.503 -     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   1.504 -     *                  int, java.lang.String)
   1.505 -     * @see        java.net.URLStreamHandler
   1.506 -     * @see        java.net.URLStreamHandler#parseURL(java.net.URL,
   1.507 -     *                  java.lang.String, int, int)
   1.508 -     */
   1.509 -    public URL(URL context, String spec, URLStreamHandler handler)
   1.510 -        throws MalformedURLException
   1.511 -    {
   1.512 -        this(findContext(context), spec, handler != null);
   1.513 -    }
   1.514 -    
   1.515 -    private URL(URL context, String spec, boolean ishandler)
   1.516 -    throws MalformedURLException {
   1.517 -        // Check for permission to specify a handler
   1.518 -        if (ishandler) {
   1.519 -            throw new SecurityException();
   1.520 -        }
   1.521 -        URLStreamHandler handler = null;
   1.522 -        
   1.523 -        String original = spec;
   1.524 -        int i, limit, c;
   1.525 -        int start = 0;
   1.526 -        String newProtocol = null;
   1.527 -        boolean aRef=false;
   1.528 -        boolean isRelative = false;
   1.529 -
   1.530 -
   1.531 -        try {
   1.532 -            limit = spec.length();
   1.533 -            while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) {
   1.534 -                limit--;        //eliminate trailing whitespace
   1.535 -            }
   1.536 -            while ((start < limit) && (spec.charAt(start) <= ' ')) {
   1.537 -                start++;        // eliminate leading whitespace
   1.538 -            }
   1.539 -
   1.540 -            if (spec.regionMatches(true, start, "url:", 0, 4)) {
   1.541 -                start += 4;
   1.542 -            }
   1.543 -            if (start < spec.length() && spec.charAt(start) == '#') {
   1.544 -                /* we're assuming this is a ref relative to the context URL.
   1.545 -                 * This means protocols cannot start w/ '#', but we must parse
   1.546 -                 * ref URL's like: "hello:there" w/ a ':' in them.
   1.547 -                 */
   1.548 -                aRef=true;
   1.549 -            }
   1.550 -            for (i = start ; !aRef && (i < limit) &&
   1.551 -                     ((c = spec.charAt(i)) != '/') ; i++) {
   1.552 -                if (c == ':') {
   1.553 -
   1.554 -                    String s = spec.substring(start, i).toLowerCase();
   1.555 -                    if (isValidProtocol(s)) {
   1.556 -                        newProtocol = s;
   1.557 -                        start = i + 1;
   1.558 -                    }
   1.559 -                    break;
   1.560 -                }
   1.561 -            }
   1.562 -
   1.563 -            // Only use our context if the protocols match.
   1.564 -            protocol = newProtocol;
   1.565 -            if ((context != null) && ((newProtocol == null) ||
   1.566 -                            newProtocol.equalsIgnoreCase(context.protocol))) {
   1.567 -                // inherit the protocol handler from the context
   1.568 -                // if not specified to the constructor
   1.569 -                if (handler == null) {
   1.570 -                    handler = context.handler;
   1.571 -                }
   1.572 -
   1.573 -                // If the context is a hierarchical URL scheme and the spec
   1.574 -                // contains a matching scheme then maintain backwards
   1.575 -                // compatibility and treat it as if the spec didn't contain
   1.576 -                // the scheme; see 5.2.3 of RFC2396
   1.577 -                if (context.path != null && context.path.startsWith("/"))
   1.578 -                    newProtocol = null;
   1.579 -
   1.580 -                if (newProtocol == null) {
   1.581 -                    protocol = context.protocol;
   1.582 -                    authority = context.authority;
   1.583 -                    userInfo = context.userInfo;
   1.584 -                    host = context.host;
   1.585 -                    port = context.port;
   1.586 -                    file = context.file;
   1.587 -                    path = context.path;
   1.588 -                    isRelative = true;
   1.589 -                }
   1.590 -            }
   1.591 -
   1.592 -            if (protocol == null) {
   1.593 -                throw new MalformedURLException("no protocol: "+original);
   1.594 -            }
   1.595 -
   1.596 -            // Get the protocol handler if not specified or the protocol
   1.597 -            // of the context could not be used
   1.598 -            if (handler == null &&
   1.599 -                (handler = getURLStreamHandler(protocol)) == null) {
   1.600 -                throw new MalformedURLException("unknown protocol: "+protocol);
   1.601 -            }
   1.602 -            this.handler = handler;
   1.603 -
   1.604 -            i = spec.indexOf('#', start);
   1.605 -            if (i >= 0) {
   1.606 -//thrw(protocol + " hnd: " + handler.getClass().getName() + " i: " + i);
   1.607 -                ref = spec.substring(i + 1, limit);
   1.608 -                limit = i;
   1.609 -            }
   1.610 -
   1.611 -            /*
   1.612 -             * Handle special case inheritance of query and fragment
   1.613 -             * implied by RFC2396 section 5.2.2.
   1.614 -             */
   1.615 -            if (isRelative && start == limit) {
   1.616 -                query = context.query;
   1.617 -                if (ref == null) {
   1.618 -                    ref = context.ref;
   1.619 -                }
   1.620 -            }
   1.621 -
   1.622 -            handler.parseURL(this, spec, start, limit);
   1.623 -
   1.624 -        } catch(MalformedURLException e) {
   1.625 -            throw e;
   1.626 -        } catch(Exception e) {
   1.627 -            MalformedURLException exception = new MalformedURLException(e.getMessage());
   1.628 -            exception.initCause(e);
   1.629 -            throw exception;
   1.630 -        }
   1.631 -    }
   1.632 -    
   1.633 -    /*
   1.634 -     * Returns true if specified string is a valid protocol name.
   1.635 -     */
   1.636 -    private boolean isValidProtocol(String protocol) {
   1.637 -        int len = protocol.length();
   1.638 -        if (len < 1)
   1.639 -            return false;
   1.640 -        char c = protocol.charAt(0);
   1.641 -        if (!Character.isLetter(c))
   1.642 -            return false;
   1.643 -        for (int i = 1; i < len; i++) {
   1.644 -            c = protocol.charAt(i);
   1.645 -            if (!Character.isLetterOrDigit(c) && c != '.' && c != '+' &&
   1.646 -                c != '-') {
   1.647 -                return false;
   1.648 -            }
   1.649 -        }
   1.650 -        return true;
   1.651 -    }
   1.652 -
   1.653 -    /**
   1.654 -     * Sets the fields of the URL. This is not a public method so that
   1.655 -     * only URLStreamHandlers can modify URL fields. URLs are
   1.656 -     * otherwise constant.
   1.657 -     *
   1.658 -     * @param protocol the name of the protocol to use
   1.659 -     * @param host the name of the host
   1.660 -       @param port the port number on the host
   1.661 -     * @param file the file on the host
   1.662 -     * @param ref the internal reference in the URL
   1.663 -     */
   1.664 -    protected void set(String protocol, String host,
   1.665 -                       int port, String file, String ref) {
   1.666 -        synchronized (this) {
   1.667 -            this.protocol = protocol;
   1.668 -            this.host = host;
   1.669 -            authority = port == -1 ? host : host + ":" + port;
   1.670 -            this.port = port;
   1.671 -            this.file = file;
   1.672 -            this.ref = ref;
   1.673 -            /* This is very important. We must recompute this after the
   1.674 -             * URL has been changed. */
   1.675 -            hashCode = -1;
   1.676 -            hostAddress = null;
   1.677 -            int q = file.lastIndexOf('?');
   1.678 -            if (q != -1) {
   1.679 -                query = file.substring(q+1);
   1.680 -                path = file.substring(0, q);
   1.681 -            } else
   1.682 -                path = file;
   1.683 -        }
   1.684 -    }
   1.685 -
   1.686 -    /**
   1.687 -     * Sets the specified 8 fields of the URL. This is not a public method so
   1.688 -     * that only URLStreamHandlers can modify URL fields. URLs are otherwise
   1.689 -     * constant.
   1.690 -     *
   1.691 -     * @param protocol the name of the protocol to use
   1.692 -     * @param host the name of the host
   1.693 -     * @param port the port number on the host
   1.694 -     * @param authority the authority part for the url
   1.695 -     * @param userInfo the username and password
   1.696 -     * @param path the file on the host
   1.697 -     * @param ref the internal reference in the URL
   1.698 -     * @param query the query part of this URL
   1.699 -     * @since 1.3
   1.700 -     */
   1.701 -    protected void set(String protocol, String host, int port,
   1.702 -                       String authority, String userInfo, String path,
   1.703 -                       String query, String ref) {
   1.704 -        synchronized (this) {
   1.705 -            this.protocol = protocol;
   1.706 -            this.host = host;
   1.707 -            this.port = port;
   1.708 -            this.file = query == null ? path : path + "?" + query;
   1.709 -            this.userInfo = userInfo;
   1.710 -            this.path = path;
   1.711 -            this.ref = ref;
   1.712 -            /* This is very important. We must recompute this after the
   1.713 -             * URL has been changed. */
   1.714 -            hashCode = -1;
   1.715 -            hostAddress = null;
   1.716 -            this.query = query;
   1.717 -            this.authority = authority;
   1.718 -        }
   1.719 -    }
   1.720 -
   1.721 -    /**
   1.722 -     * Gets the query part of this <code>URL</code>.
   1.723 -     *
   1.724 -     * @return  the query part of this <code>URL</code>,
   1.725 -     * or <CODE>null</CODE> if one does not exist
   1.726 -     * @since 1.3
   1.727 -     */
   1.728 -    public String getQuery() {
   1.729 -        return query;
   1.730 -    }
   1.731 -
   1.732 -    /**
   1.733 -     * Gets the path part of this <code>URL</code>.
   1.734 -     *
   1.735 -     * @return  the path part of this <code>URL</code>, or an
   1.736 -     * empty string if one does not exist
   1.737 -     * @since 1.3
   1.738 -     */
   1.739 -    public String getPath() {
   1.740 -        return path;
   1.741 -    }
   1.742 -
   1.743 -    /**
   1.744 -     * Gets the userInfo part of this <code>URL</code>.
   1.745 -     *
   1.746 -     * @return  the userInfo part of this <code>URL</code>, or
   1.747 -     * <CODE>null</CODE> if one does not exist
   1.748 -     * @since 1.3
   1.749 -     */
   1.750 -    public String getUserInfo() {
   1.751 -        return userInfo;
   1.752 -    }
   1.753 -
   1.754 -    /**
   1.755 -     * Gets the authority part of this <code>URL</code>.
   1.756 -     *
   1.757 -     * @return  the authority part of this <code>URL</code>
   1.758 -     * @since 1.3
   1.759 -     */
   1.760 -    public String getAuthority() {
   1.761 -        return authority;
   1.762 -    }
   1.763 -
   1.764 -    /**
   1.765 -     * Gets the port number of this <code>URL</code>.
   1.766 -     *
   1.767 -     * @return  the port number, or -1 if the port is not set
   1.768 -     */
   1.769 -    public int getPort() {
   1.770 -        return port;
   1.771 -    }
   1.772 -
   1.773 -    /**
   1.774 -     * Gets the default port number of the protocol associated
   1.775 -     * with this <code>URL</code>. If the URL scheme or the URLStreamHandler
   1.776 -     * for the URL do not define a default port number,
   1.777 -     * then -1 is returned.
   1.778 -     *
   1.779 -     * @return  the port number
   1.780 -     * @since 1.4
   1.781 -     */
   1.782 -    public int getDefaultPort() {
   1.783 -        return handler.getDefaultPort();
   1.784 -    }
   1.785 -
   1.786 -    /**
   1.787 -     * Gets the protocol name of this <code>URL</code>.
   1.788 -     *
   1.789 -     * @return  the protocol of this <code>URL</code>.
   1.790 -     */
   1.791 -    public String getProtocol() {
   1.792 -        return protocol;
   1.793 -    }
   1.794 -
   1.795 -    /**
   1.796 -     * Gets the host name of this <code>URL</code>, if applicable.
   1.797 -     * The format of the host conforms to RFC 2732, i.e. for a
   1.798 -     * literal IPv6 address, this method will return the IPv6 address
   1.799 -     * enclosed in square brackets (<tt>'['</tt> and <tt>']'</tt>).
   1.800 -     *
   1.801 -     * @return  the host name of this <code>URL</code>.
   1.802 -     */
   1.803 -    public String getHost() {
   1.804 -        return host;
   1.805 -    }
   1.806 -
   1.807 -    /**
   1.808 -     * Gets the file name of this <code>URL</code>.
   1.809 -     * The returned file portion will be
   1.810 -     * the same as <CODE>getPath()</CODE>, plus the concatenation of
   1.811 -     * the value of <CODE>getQuery()</CODE>, if any. If there is
   1.812 -     * no query portion, this method and <CODE>getPath()</CODE> will
   1.813 -     * return identical results.
   1.814 -     *
   1.815 -     * @return  the file name of this <code>URL</code>,
   1.816 -     * or an empty string if one does not exist
   1.817 -     */
   1.818 -    public String getFile() {
   1.819 -        return file;
   1.820 -    }
   1.821 -
   1.822 -    /**
   1.823 -     * Gets the anchor (also known as the "reference") of this
   1.824 -     * <code>URL</code>.
   1.825 -     *
   1.826 -     * @return  the anchor (also known as the "reference") of this
   1.827 -     *          <code>URL</code>, or <CODE>null</CODE> if one does not exist
   1.828 -     */
   1.829 -    public String getRef() {
   1.830 -        return ref;
   1.831 -    }
   1.832 -
   1.833 -    /**
   1.834 -     * Compares this URL for equality with another object.<p>
   1.835 -     *
   1.836 -     * If the given object is not a URL then this method immediately returns
   1.837 -     * <code>false</code>.<p>
   1.838 -     *
   1.839 -     * Two URL objects are equal if they have the same protocol, reference
   1.840 -     * equivalent hosts, have the same port number on the host, and the same
   1.841 -     * file and fragment of the file.<p>
   1.842 -     *
   1.843 -     * Two hosts are considered equivalent if both host names can be resolved
   1.844 -     * into the same IP addresses; else if either host name can't be
   1.845 -     * resolved, the host names must be equal without regard to case; or both
   1.846 -     * host names equal to null.<p>
   1.847 -     *
   1.848 -     * Since hosts comparison requires name resolution, this operation is a
   1.849 -     * blocking operation. <p>
   1.850 -     *
   1.851 -     * Note: The defined behavior for <code>equals</code> is known to
   1.852 -     * be inconsistent with virtual hosting in HTTP.
   1.853 -     *
   1.854 -     * @param   obj   the URL to compare against.
   1.855 -     * @return  <code>true</code> if the objects are the same;
   1.856 -     *          <code>false</code> otherwise.
   1.857 -     */
   1.858 -    public boolean equals(Object obj) {
   1.859 -        if (!(obj instanceof URL))
   1.860 -            return false;
   1.861 -        URL u2 = (URL)obj;
   1.862 -
   1.863 -        return handler.equals(this, u2);
   1.864 -    }
   1.865 -
   1.866 -    /**
   1.867 -     * Creates an integer suitable for hash table indexing.<p>
   1.868 -     *
   1.869 -     * The hash code is based upon all the URL components relevant for URL
   1.870 -     * comparison. As such, this operation is a blocking operation.<p>
   1.871 -     *
   1.872 -     * @return  a hash code for this <code>URL</code>.
   1.873 -     */
   1.874 -    public synchronized int hashCode() {
   1.875 -        if (hashCode != -1)
   1.876 -            return hashCode;
   1.877 -
   1.878 -        hashCode = handler.hashCode(this);
   1.879 -        return hashCode;
   1.880 -    }
   1.881 -
   1.882 -    /**
   1.883 -     * Compares two URLs, excluding the fragment component.<p>
   1.884 -     *
   1.885 -     * Returns <code>true</code> if this <code>URL</code> and the
   1.886 -     * <code>other</code> argument are equal without taking the
   1.887 -     * fragment component into consideration.
   1.888 -     *
   1.889 -     * @param   other   the <code>URL</code> to compare against.
   1.890 -     * @return  <code>true</code> if they reference the same remote object;
   1.891 -     *          <code>false</code> otherwise.
   1.892 -     */
   1.893 -    public boolean sameFile(URL other) {
   1.894 -        return handler.sameFile(this, other);
   1.895 -    }
   1.896 -
   1.897 -    /**
   1.898 -     * Constructs a string representation of this <code>URL</code>. The
   1.899 -     * string is created by calling the <code>toExternalForm</code>
   1.900 -     * method of the stream protocol handler for this object.
   1.901 -     *
   1.902 -     * @return  a string representation of this object.
   1.903 -     * @see     java.net.URL#URL(java.lang.String, java.lang.String, int,
   1.904 -     *                  java.lang.String)
   1.905 -     * @see     java.net.URLStreamHandler#toExternalForm(java.net.URL)
   1.906 -     */
   1.907 -    public String toString() {
   1.908 -        return toExternalForm();
   1.909 -    }
   1.910 -
   1.911 -    /**
   1.912 -     * Constructs a string representation of this <code>URL</code>. The
   1.913 -     * string is created by calling the <code>toExternalForm</code>
   1.914 -     * method of the stream protocol handler for this object.
   1.915 -     *
   1.916 -     * @return  a string representation of this object.
   1.917 -     * @see     java.net.URL#URL(java.lang.String, java.lang.String,
   1.918 -     *                  int, java.lang.String)
   1.919 -     * @see     java.net.URLStreamHandler#toExternalForm(java.net.URL)
   1.920 -     */
   1.921 -    public String toExternalForm() {
   1.922 -        return handler.toExternalForm(this);
   1.923 -    }
   1.924 -
   1.925 -    /**
   1.926 -     * Returns a {@link java.net.URLConnection URLConnection} instance that
   1.927 -     * represents a connection to the remote object referred to by the
   1.928 -     * {@code URL}.
   1.929 -     *
   1.930 -     * <P>A new instance of {@linkplain java.net.URLConnection URLConnection} is
   1.931 -     * created every time when invoking the
   1.932 -     * {@linkplain java.net.URLStreamHandler#openConnection(URL)
   1.933 -     * URLStreamHandler.openConnection(URL)} method of the protocol handler for
   1.934 -     * this URL.</P>
   1.935 -     *
   1.936 -     * <P>It should be noted that a URLConnection instance does not establish
   1.937 -     * the actual network connection on creation. This will happen only when
   1.938 -     * calling {@linkplain java.net.URLConnection#connect() URLConnection.connect()}.</P>
   1.939 -     *
   1.940 -     * <P>If for the URL's protocol (such as HTTP or JAR), there
   1.941 -     * exists a public, specialized URLConnection subclass belonging
   1.942 -     * to one of the following packages or one of their subpackages:
   1.943 -     * java.lang, java.io, java.util, java.net, the connection
   1.944 -     * returned will be of that subclass. For example, for HTTP an
   1.945 -     * HttpURLConnection will be returned, and for JAR a
   1.946 -     * JarURLConnection will be returned.</P>
   1.947 -     *
   1.948 -     * @return     a {@link java.net.URLConnection URLConnection} linking
   1.949 -     *             to the URL.
   1.950 -     * @exception  IOException  if an I/O exception occurs.
   1.951 -     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
   1.952 -     *             int, java.lang.String)
   1.953 -     */
   1.954 -//    public URLConnection openConnection() throws java.io.IOException {
   1.955 -//        return handler.openConnection(this);
   1.956 -//    }
   1.957 -
   1.958 -
   1.959 -    /**
   1.960 -     * Opens a connection to this <code>URL</code> and returns an
   1.961 -     * <code>InputStream</code> for reading from that connection. This
   1.962 -     * method is a shorthand for:
   1.963 -     * <blockquote><pre>
   1.964 -     *     openConnection().getInputStream()
   1.965 -     * </pre></blockquote>
   1.966 -     *
   1.967 -     * @return     an input stream for reading from the URL connection.
   1.968 -     * @exception  IOException  if an I/O exception occurs.
   1.969 -     * @see        java.net.URL#openConnection()
   1.970 -     * @see        java.net.URLConnection#getInputStream()
   1.971 -     */
   1.972 -    public final InputStream openStream() throws java.io.IOException {
   1.973 -        if (is != null) {
   1.974 -            return is;
   1.975 -        }
   1.976 -        byte[] arr = (byte[]) getContent(new Class[] { byte[].class });
   1.977 -        if (arr == null) {
   1.978 -            throw new IOException();
   1.979 -        }
   1.980 -        return new ByteArrayInputStream(arr);
   1.981 -    }
   1.982 -
   1.983 -    /**
   1.984 -     * Gets the contents of this URL. This method is a shorthand for:
   1.985 -     * <blockquote><pre>
   1.986 -     *     openConnection().getContent()
   1.987 -     * </pre></blockquote>
   1.988 -     *
   1.989 -     * @return     the contents of this URL.
   1.990 -     * @exception  IOException  if an I/O exception occurs.
   1.991 -     * @see        java.net.URLConnection#getContent()
   1.992 -     */
   1.993 -    public final Object getContent() throws java.io.IOException {
   1.994 -        return loadText(toExternalForm());
   1.995 -    }
   1.996 -    
   1.997 -    @JavaScriptBody(args = "url", body = ""
   1.998 -        + "var request = new XMLHttpRequest();\n"
   1.999 -        + "request.open('GET', url, false);\n"
  1.1000 -        + "request.send();\n"
  1.1001 -        + "return request.responseText;\n"
  1.1002 -    )
  1.1003 -    private static native String loadText(String url) throws IOException;
  1.1004 -
  1.1005 -    @JavaScriptBody(args = { "url", "arr" }, body = ""
  1.1006 -        + "var request = new XMLHttpRequest();\n"
  1.1007 -        + "request.open('GET', url, false);\n"
  1.1008 -        + "request.overrideMimeType('text\\/plain; charset=x-user-defined');\n"
  1.1009 -        + "request.send();\n"
  1.1010 -        + "var t = request.responseText;\n"
  1.1011 -        + "for (var i = 0; i < t.length; i++) arr.push(t.charCodeAt(i) & 0xff);\n"
  1.1012 -        + "return arr;\n"
  1.1013 -    )
  1.1014 -    private static native Object loadBytes(String url, byte[] arr) throws IOException;
  1.1015 -
  1.1016 -    /**
  1.1017 -     * Gets the contents of this URL. This method is a shorthand for:
  1.1018 -     * <blockquote><pre>
  1.1019 -     *     openConnection().getContent(Class[])
  1.1020 -     * </pre></blockquote>
  1.1021 -     *
  1.1022 -     * @param classes an array of Java types
  1.1023 -     * @return     the content object of this URL that is the first match of
  1.1024 -     *               the types specified in the classes array.
  1.1025 -     *               null if none of the requested types are supported.
  1.1026 -     * @exception  IOException  if an I/O exception occurs.
  1.1027 -     * @see        java.net.URLConnection#getContent(Class[])
  1.1028 -     * @since 1.3
  1.1029 -     */
  1.1030 -    public final Object getContent(Class[] classes)
  1.1031 -    throws java.io.IOException {
  1.1032 -        for (Class<?> c : classes) {
  1.1033 -            if (c == String.class) {
  1.1034 -                return loadText(toExternalForm());
  1.1035 -            }
  1.1036 -            if (c == byte[].class) {
  1.1037 -                return loadBytes(toExternalForm(), new byte[0]);
  1.1038 -            }
  1.1039 -        }
  1.1040 -        return null;
  1.1041 -    }
  1.1042 -
  1.1043 -    static URLStreamHandler getURLStreamHandler(String protocol) {
  1.1044 -        URLStreamHandler universal = new URLStreamHandler() {};
  1.1045 -        return universal;
  1.1046 -    }
  1.1047 -
  1.1048 -    private static URL findContext(URL context) throws MalformedURLException {
  1.1049 -        if (context == null) {
  1.1050 -            String base = findBaseURL();
  1.1051 -            if (base != null) {
  1.1052 -                context = new URL(null, base, false);
  1.1053 -            }
  1.1054 -        }
  1.1055 -        return context;
  1.1056 -    }
  1.1057 -    
  1.1058 -    @JavaScriptBody(args = {}, body = 
  1.1059 -          "if (typeof window !== 'object') return null;\n"
  1.1060 -        + "if (!window.location) return null;\n"
  1.1061 -        + "if (!window.location.href) return null;\n"
  1.1062 -        + "return window.location.href;\n"
  1.1063 -    )
  1.1064 -    private static native String findBaseURL();
  1.1065 -}
  1.1066 -class Parts {
  1.1067 -    String path, query, ref;
  1.1068 -
  1.1069 -    Parts(String file) {
  1.1070 -        int ind = file.indexOf('#');
  1.1071 -        ref = ind < 0 ? null: file.substring(ind + 1);
  1.1072 -        file = ind < 0 ? file: file.substring(0, ind);
  1.1073 -        int q = file.lastIndexOf('?');
  1.1074 -        if (q != -1) {
  1.1075 -            query = file.substring(q+1);
  1.1076 -            path = file.substring(0, q);
  1.1077 -        } else {
  1.1078 -            path = file;
  1.1079 -        }
  1.1080 -    }
  1.1081 -
  1.1082 -    String getPath() {
  1.1083 -        return path;
  1.1084 -    }
  1.1085 -
  1.1086 -    String getQuery() {
  1.1087 -        return query;
  1.1088 -    }
  1.1089 -
  1.1090 -    String getRef() {
  1.1091 -        return ref;
  1.1092 -    }
  1.1093 -}