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