151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.InputStream; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.OutputStream; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedAction; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Hashtable; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.StringTokenizer; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.SecurityConstants; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Class <code>URL</code> represents a Uniform Resource 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Locator, a pointer to a "resource" on the World 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Wide Web. A resource can be something as simple as a file or a 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * directory, or it can be a reference to a more complicated object, 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * such as a query to a database or to a search engine. More 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * information on the types of URLs and their formats can be found at: 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote> 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html"> 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html</i></a> 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </blockquote> 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In general, a URL can be broken into several parts. The previous 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * example of a URL indicates that the protocol to use is 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>http</code> (HyperText Transfer Protocol) and that the 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * information resides on a host machine named 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>www.socs.uts.edu.au</code>. The information on that host 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * machine is named <code>/MosaicDocs-old/url-primer.html</code>. The exact 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * meaning of this name on the host machine is both protocol 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * dependent and host dependent. The information normally resides in 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a file, but it could be generated on the fly. This component of 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the URL is called the <i>path</i> component. 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A URL can optionally specify a "port", which is the 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * port number to which the TCP connection is made on the remote host 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * machine. If the port is not specified, the default port for 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the protocol is used instead. For example, the default port for 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>http</code> is <code>80</code>. An alternative port could be 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified as: 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * http://www.socs.uts.edu.au:80/MosaicDocs-old/url-primer.html 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The syntax of <code>URL</code> is defined by <a 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC 2396: Uniform 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 2732: Format for 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * also supports scope_ids. The syntax and usage of scope_ids is described 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="Inet6Address.html#scoped">here</a>. 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A URL may have appended to it a "fragment", also known 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as a "ref" or a "reference". The fragment is indicated by the sharp 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sign character "#" followed by more characters. For example, 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * http://java.sun.com/index.html#chapter1 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This fragment is not technically part of the URL. Rather, it 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * indicates that after the specified resource is retrieved, the 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * application is specifically interested in that part of the 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * document that has the tag <code>chapter1</code> attached to it. The 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * meaning of a tag is resource specific. 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An application can also specify a "relative URL", 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * which contains only enough information to reach the resource 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * relative to another URL. Relative URLs are frequently used within 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * HTML pages. For example, if the contents of the URL: 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * http://java.sun.com/index.html 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * contained within it the relative URL: 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FAQ.html 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it would be a shorthand for: 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * http://java.sun.com/FAQ.html 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The relative URL need not specify all the components of a URL. If 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the protocol, host name, or port number is missing, the value is 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * inherited from the fully specified URL. The file component must be 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified. The optional fragment is not inherited. 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The URL class does not itself encode or decode any URL components 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * according to the escaping mechanism defined in RFC2396. It is the 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * responsibility of the caller to encode any fields, which need to be 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * escaped prior to calling URL, and also to decode any escaped fields, 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that are returned from URL. Furthermore, because URL has no knowledge 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of URL escaping, it does not recognise equivalence between the encoded 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or decoded form of the same URL. For example, the two URLs:<br> 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> http://foo.com/hello world/ and http://foo.com/hello%20world</pre> 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * would be considered not equal to each other. 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note, the {@link java.net.URI} class does perform escaping of its 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * component fields in certain circumstances. The recommended way 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to manage the encoding and decoding of URLs is to use {@link java.net.URI}, 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and to convert between these two classes using {@link #toURI()} and 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link URI#toURL()}. 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The {@link URLEncoder} and {@link URLDecoder} classes can also be 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * used, but only for HTML form encoding, which is not the same 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as the encoding scheme defined in RFC2396. 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author James Gosling 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.0 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic final class URL implements java.io.Serializable { 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final long serialVersionUID = -7627629688361524110L; 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The property which specifies the package prefix list to be scanned 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for protocol handlers. The value of this property (if any) should 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be a vertical bar delimited list of package names to search through 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for a protocol handler to load. The policy of this class is that 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * all protocol handlers will be in a class called <protocolname>.Handler, 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and each package in the list is examined in turn for a matching 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * handler. If none are found (or the property is not specified), the 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * default package prefix, sun.net.www.protocol, is used. The search 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * proceeds from the first package in the list to the last and stops 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * when a match is found. 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String protocolPathProp = "java.protocol.handler.pkgs"; 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The protocol to use (ftp, http, nntp, ... etc.) . 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String protocol; 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The host name to connect to. 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String host; 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The protocol port to connect to. 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int port = -1; 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The specified file name on that host. <code>file</code> is 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * defined as <code>path[?query]</code> 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String file; 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The query part of this URL. 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient String query; 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The authority part of this URL. 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String authority; 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The path part of this URL. 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient String path; 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The userinfo part of this URL. 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private transient String userInfo; 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * # reference. 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String ref; 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The host's IP address, used in equals and hashCode. 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Computed on demand. An uninitialized or unknown hostAddress is null. 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient InetAddress hostAddress; 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The URLStreamHandler for this URL. 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient URLStreamHandler handler; 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Our hash code. 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 22006fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak // ----- BEGIN android ----- 22106fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak //private int hashCode = -1; 22206fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak private transient int hashCode = -1; 22306fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak // ----- END android ----- 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a <code>URL</code> object from the specified 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>protocol</code>, <code>host</code>, <code>port</code> 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * number, and <code>file</code>.<p> 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>host</code> can be expressed as a host name or a literal 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IP address. If IPv6 literal address is used, it should be 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * enclosed in square brackets (<tt>'['</tt> and <tt>']'</tt>), as 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified by <a 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * href="http://www.ietf.org/rfc/rfc2732.txt">RFC 2732</a>; 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * However, the literal IPv6 address format defined in <a 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IP 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Version 6 Addressing Architecture</i></a> is also accepted.<p> 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Specifying a <code>port</code> number of <code>-1</code> 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * indicates that the URL should use the default port for the 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * protocol.<p> 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If this is the first URL object being created with the specified 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * protocol, a <i>stream protocol handler</i> object, an instance of 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class <code>URLStreamHandler</code>, is created for that protocol: 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ol> 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>If the application has previously set up an instance of 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>URLStreamHandlerFactory</code> as the stream handler factory, 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then the <code>createURLStreamHandler</code> method of that instance 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is called with the protocol string as an argument to create the 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream protocol handler. 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>If no <code>URLStreamHandlerFactory</code> has yet been set up, 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or if the factory's <code>createURLStreamHandler</code> method 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returns <code>null</code>, then the constructor finds the 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * value of the system property: 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.protocol.handler.pkgs 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the value of that system property is not <code>null</code>, 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is interpreted as a list of packages separated by a vertical 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * slash character '<code>|</code>'. The constructor tries to load 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the class named: 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <<i>package</i>>.<<i>protocol</i>>.Handler 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * where <<i>package</i>> is replaced by the name of the package 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and <<i>protocol</i>> is replaced by the name of the protocol. 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If this class does not exist, or if the class exists but it is not 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a subclass of <code>URLStreamHandler</code>, then the next package 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the list is tried. 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>If the previous step fails to find a protocol handler, then the 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constructor tries to load from a system default package. 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <<i>system default package</i>>.<<i>protocol</i>>.Handler 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If this class does not exist, or if the class exists but it is not a 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * subclass of <code>URLStreamHandler</code>, then a 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>MalformedURLException</code> is thrown. 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ol> 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Protocol handlers for the following protocols are guaranteed 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to exist on the search path :- 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * http, https, ftp, file, and jar 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Protocol handlers for additional protocols may also be 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * available. 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>No validation of the inputs is performed by this constructor. 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param protocol the name of the protocol to use. 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param host the name of the host. 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port the port number on the host. 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the file on the host 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception MalformedURLException if an unknown protocol is specified. 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.System#getProperty(java.lang.String) 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#setURLStreamHandlerFactory( 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.net.URLStreamHandlerFactory) 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandlerFactory#createURLStreamHandler( 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.String) 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URL(String protocol, String host, int port, String file) 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws MalformedURLException 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(protocol, host, port, file, null); 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a URL from the specified <code>protocol</code> 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * name, <code>host</code> name, and <code>file</code> name. The 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * default port for the specified protocol is used. 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method is equivalent to calling the four-argument 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constructor with the arguments being <code>protocol</code>, 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>host</code>, <code>-1</code>, and <code>file</code>. 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * No validation of the inputs is performed by this constructor. 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param protocol the name of the protocol to use. 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param host the name of the host. 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the file on the host. 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception MalformedURLException if an unknown protocol is specified. 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URL(String protocol, String host, String file) 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws MalformedURLException { 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(protocol, host, -1, file); 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a <code>URL</code> object from the specified 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>protocol</code>, <code>host</code>, <code>port</code> 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * number, <code>file</code>, and <code>handler</code>. Specifying 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a <code>port</code> number of <code>-1</code> indicates that 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the URL should use the default port for the protocol. Specifying 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a <code>handler</code> of <code>null</code> indicates that the URL 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * should use a default stream handler for the protocol, as outlined 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for: 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.net.URL#URL(java.lang.String, java.lang.String, int, 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.String) 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If the handler is not null and there is a security manager, 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the security manager's <code>checkPermission</code> 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is called with a 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>NetPermission("specifyStreamHandler")</code> permission. 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This may result in a SecurityException. 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * No validation of the inputs is performed by this constructor. 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param protocol the name of the protocol to use. 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param host the name of the host. 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port the port number on the host. 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the file on the host 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param handler the stream handler for the URL. 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception MalformedURLException if an unknown protocol is specified. 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if a security manager exists and its 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkPermission</code> method doesn't allow 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specifying a stream handler explicitly. 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.System#getProperty(java.lang.String) 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#setURLStreamHandlerFactory( 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.net.URLStreamHandlerFactory) 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandlerFactory#createURLStreamHandler( 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.String) 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkPermission 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.NetPermission 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URL(String protocol, String host, int port, String file, 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URLStreamHandler handler) throws MalformedURLException { 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler != null) { 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check for permission to specify a handler 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkSpecifyHandler(sm); 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protocol = protocol.toLowerCase(); 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.protocol = protocol; 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (host != null) { 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if host is a literal IPv6 address, 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * we will make it conform to RFC 2732 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (host.indexOf(':') >= 0 && !host.startsWith("[")) { 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host = "["+host+"]"; 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.host = host; 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (port < -1) { 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new MalformedURLException("Invalid port number :" + 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski port); 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.port = port; 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski authority = (port == -1) ? host : host + ":" + port; 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40206fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak Parts parts = new Parts(file, host); 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = parts.getPath(); 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski query = parts.getQuery(); 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (query != null) { 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.file = path + "?" + query; 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.file = path; 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ref = parts.getRef(); 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Note: we don't do validation of the URL here. Too risky to change 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // right now, but worth considering for future reference. -br 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler == null && 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (handler = getURLStreamHandler(protocol)) == null) { 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new MalformedURLException("unknown protocol: " + protocol); 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.handler = handler; 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a <code>URL</code> object from the <code>String</code> 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * representation. 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This constructor is equivalent to a call to the two-argument 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constructor with a <code>null</code> first argument. 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param spec the <code>String</code> to parse as a URL. 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception MalformedURLException if no protocol is specified, or an 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>. 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.net.URL, java.lang.String) 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URL(String spec) throws MalformedURLException { 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(null, spec); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a URL by parsing the given spec within a specified context. 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The new URL is created from the given context URL and the spec 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * argument as described in 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * RFC2396 "Uniform Resource Identifiers : Generic * Syntax" : 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <scheme>://<authority><path>?<query>#<fragment> 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The reference is parsed into the scheme, authority, path, query and 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * fragment parts. If the path component is empty and the scheme, 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * authority, and query components are undefined, then the new URL is a 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reference to the current document. Otherwise, the fragment and query 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parts present in the spec are used in the new URL. 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the scheme component is defined in the given spec and does not match 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the scheme of the context, then the new URL is created as an absolute 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * URL based on the spec alone. Otherwise the scheme component is inherited 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * from the context URL. 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the authority component is present in the spec then the spec is 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * treated as absolute and the spec authority and path will replace the 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * context authority and path. If the authority component is absent in the 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * spec then the authority of the new URL will be inherited from the 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * context. 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the spec's path component begins with a slash character 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "/" then the 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * path is treated as absolute and the spec path replaces the context path. 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise, the path is treated as a relative path and is appended to the 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * context path, as described in RFC2396. Also, in this case, 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the path is canonicalized through the removal of directory 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * changes made by occurences of ".." and ".". 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For a more detailed description of URL parsing, refer to RFC2396. 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param context the context in which to parse the specification. 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param spec the <code>String</code> to parse as a URL. 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception MalformedURLException if no protocol is specified, or an 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>. 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler#parseURL(java.net.URL, 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.String, int, int) 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URL(URL context, String spec) throws MalformedURLException { 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(context, spec, null); 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a URL by parsing the given spec with the specified handler 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * within a specified context. If the handler is null, the parsing 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * occurs as with the two argument constructor. 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param context the context in which to parse the specification. 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param spec the <code>String</code> to parse as a URL. 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param handler the stream handler for the URL. 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception MalformedURLException if no protocol is specified, or an 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>. 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if a security manager exists and its 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkPermission</code> method doesn't allow 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specifying a stream handler. 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler#parseURL(java.net.URL, 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.String, int, int) 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URL(URL context, String spec, URLStreamHandler handler) 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws MalformedURLException 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String original = spec; 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i, limit, c; 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int start = 0; 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String newProtocol = null; 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean aRef=false; 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isRelative = false; 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Check for permission to specify a handler 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler != null) { 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkSpecifyHandler(sm); 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski limit = spec.length(); 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) { 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski limit--; //eliminate trailing whitespace 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((start < limit) && (spec.charAt(start) <= ' ')) { 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start++; // eliminate leading whitespace 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (spec.regionMatches(true, start, "url:", 0, 4)) { 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start += 4; 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (start < spec.length() && spec.charAt(start) == '#') { 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* we're assuming this is a ref relative to the context URL. 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This means protocols cannot start w/ '#', but we must parse 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ref URL's like: "hello:there" w/ a ':' in them. 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski aRef=true; 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (i = start ; !aRef && (i < limit) && 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((c = spec.charAt(i)) != '/') ; i++) { 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == ':') { 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String s = spec.substring(start, i).toLowerCase(); 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isValidProtocol(s)) { 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newProtocol = s; 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start = i + 1; 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Only use our context if the protocols match. 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protocol = newProtocol; 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((context != null) && ((newProtocol == null) || 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newProtocol.equalsIgnoreCase(context.protocol))) { 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // inherit the protocol handler from the context 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if not specified to the constructor 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler == null) { 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler = context.handler; 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the context is a hierarchical URL scheme and the spec 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // contains a matching scheme then maintain backwards 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // compatibility and treat it as if the spec didn't contain 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the scheme; see 5.2.3 of RFC2396 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (context.path != null && context.path.startsWith("/")) 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newProtocol = null; 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (newProtocol == null) { 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protocol = context.protocol; 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski authority = context.authority; 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski userInfo = context.userInfo; 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host = context.host; 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski port = context.port; 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski file = context.file; 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = context.path; 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isRelative = true; 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (protocol == null) { 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new MalformedURLException("no protocol: "+original); 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Get the protocol handler if not specified or the protocol 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // of the context could not be used 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler == null && 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (handler = getURLStreamHandler(protocol)) == null) { 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new MalformedURLException("unknown protocol: "+protocol); 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.handler = handler; 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i = spec.indexOf('#', start); 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i >= 0) { 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ref = spec.substring(i + 1, limit); 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski limit = i; 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Handle special case inheritance of query and fragment 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implied by RFC2396 section 5.2.2. 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isRelative && start == limit) { 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski query = context.query; 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ref == null) { 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ref = context.ref; 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler.parseURL(this, spec, start, limit); 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch(MalformedURLException e) { 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw e; 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch(Exception e) { 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MalformedURLException exception = new MalformedURLException(e.getMessage()); 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski exception.initCause(e); 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw exception; 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true if specified string is a valid protocol name. 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isValidProtocol(String protocol) { 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = protocol.length(); 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len < 1) 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = protocol.charAt(0); 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!Character.isLetter(c)) 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 1; i < len; i++) { 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = protocol.charAt(i); 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!Character.isLetterOrDigit(c) && c != '.' && c != '+' && 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c != '-') { 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Checks for permission to specify a stream handler. 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkSpecifyHandler(SecurityManager sm) { 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkPermission(SecurityConstants.SPECIFY_HANDLER_PERMISSION); 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the fields of the URL. This is not a public method so that 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * only URLStreamHandlers can modify URL fields. URLs are 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * otherwise constant. 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param protocol the name of the protocol to use 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param host the name of the host 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @param port the port number on the host 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the file on the host 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ref the internal reference in the URL 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void set(String protocol, String host, 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int port, String file, String ref) { 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (this) { 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.protocol = protocol; 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.host = host; 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski authority = port == -1 ? host : host + ":" + port; 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.port = port; 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.file = file; 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.ref = ref; 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* This is very important. We must recompute this after the 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * URL has been changed. */ 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hashCode = -1; 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hostAddress = null; 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int q = file.lastIndexOf('?'); 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (q != -1) { 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski query = file.substring(q+1); 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = file.substring(0, q); 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = file; 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the specified 8 fields of the URL. This is not a public method so 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that only URLStreamHandlers can modify URL fields. URLs are otherwise 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * constant. 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param protocol the name of the protocol to use 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param host the name of the host 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port the port number on the host 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param authority the authority part for the url 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param userInfo the username and password 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param path the file on the host 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ref the internal reference in the URL 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param query the query part of this URL 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void set(String protocol, String host, int port, 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String authority, String userInfo, String path, 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String query, String ref) { 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (this) { 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.protocol = protocol; 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.host = host; 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.port = port; 71157acf7ac56d7fed06c96a1451fe7d8570dbb2977Przemyslaw Szczepaniak this.file = (query == null || query.isEmpty()) ? path : path + "?" + query; 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.userInfo = userInfo; 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.path = path; 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.ref = ref; 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* This is very important. We must recompute this after the 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * URL has been changed. */ 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hashCode = -1; 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hostAddress = null; 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.query = query; 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.authority = authority; 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the query part of this <code>URL</code>. 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the query part of this <code>URL</code>, 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or <CODE>null</CODE> if one does not exist 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getQuery() { 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return query; 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the path part of this <code>URL</code>. 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the path part of this <code>URL</code>, or an 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * empty string if one does not exist 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getPath() { 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return path; 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the userInfo part of this <code>URL</code>. 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the userInfo part of this <code>URL</code>, or 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <CODE>null</CODE> if one does not exist 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getUserInfo() { 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return userInfo; 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the authority part of this <code>URL</code>. 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the authority part of this <code>URL</code> 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getAuthority() { 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return authority; 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the port number of this <code>URL</code>. 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the port number, or -1 if the port is not set 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getPort() { 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return port; 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the default port number of the protocol associated 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with this <code>URL</code>. If the URL scheme or the URLStreamHandler 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for the URL do not define a default port number, 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then -1 is returned. 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the port number 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getDefaultPort() { 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler.getDefaultPort(); 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the protocol name of this <code>URL</code>. 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the protocol of this <code>URL</code>. 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getProtocol() { 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return protocol; 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the host name of this <code>URL</code>, if applicable. 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The format of the host conforms to RFC 2732, i.e. for a 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * literal IPv6 address, this method will return the IPv6 address 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * enclosed in square brackets (<tt>'['</tt> and <tt>']'</tt>). 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the host name of this <code>URL</code>. 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getHost() { 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return host; 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the file name of this <code>URL</code>. 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The returned file portion will be 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the same as <CODE>getPath()</CODE>, plus the concatenation of 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the value of <CODE>getQuery()</CODE>, if any. If there is 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * no query portion, this method and <CODE>getPath()</CODE> will 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return identical results. 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the file name of this <code>URL</code>, 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or an empty string if one does not exist 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getFile() { 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return file; 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the anchor (also known as the "reference") of this 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>URL</code>. 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the anchor (also known as the "reference") of this 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>URL</code>, or <CODE>null</CODE> if one does not exist 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getRef() { 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ref; 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Compares this URL for equality with another object.<p> 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the given object is not a URL then this method immediately returns 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>false</code>.<p> 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Two URL objects are equal if they have the same protocol, reference 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * equivalent hosts, have the same port number on the host, and the same 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file and fragment of the file.<p> 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 846b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * Returns true if this URL equals {@code o}. URLs are equal if they have 847b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * the same protocol, host, port, file, and reference. 848b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * 849b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <h3>Network I/O Warning</h3> 850b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <p>Some implementations of URL.equals() resolve host names over the 851b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * network. This is problematic: 852b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <ul> 853b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <li><strong>The network may be slow.</strong> Many classes, including 854b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * core collections like {@link java.util.Map Map} and {@link java.util.Set 855b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * Set} expect that {@code equals} and {@code hashCode} will return quickly. 856b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * By violating this assumption, this method posed potential performance 857b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * problems. 858b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <li><strong>Equal IP addresses do not imply equal content.</strong> 859b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * Virtual hosting permits unrelated sites to share an IP address. This 860b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * method could report two otherwise unrelated URLs to be equal because 861b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * they're hosted on the same server.</li> 862b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <li><strong>The network may not be available.</strong> Two URLs could be 863b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * equal when a network is available and unequal otherwise.</li> 864b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <li><strong>The network may change.</strong> The IP address for a given 865b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * host name varies by network and over time. This is problematic for mobile 866b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * devices. Two URLs could be equal on some networks and unequal on 867b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * others.</li> 868b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * </ul> 869b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * <p>This problem is fixed in Android 4.0 (Ice Cream Sandwich). In that 870b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * release, URLs are only equal if their host names are equal (ignoring 871b93dbaedd71dae5c1e4fb2faba863acbde1080c2Narayan Kamath * case). 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param obj the URL to compare against. 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return <code>true</code> if the objects are the same; 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>false</code> otherwise. 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object obj) { 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(obj instanceof URL)) 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URL u2 = (URL)obj; 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler.equals(this, u2); 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an integer suitable for hash table indexing.<p> 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The hash code is based upon all the URL components relevant for URL 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * comparison. As such, this operation is a blocking operation.<p> 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a hash code for this <code>URL</code>. 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized int hashCode() { 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hashCode != -1) 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hashCode; 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hashCode = handler.hashCode(this); 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hashCode; 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Compares two URLs, excluding the fragment component.<p> 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns <code>true</code> if this <code>URL</code> and the 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>other</code> argument are equal without taking the 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * fragment component into consideration. 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param other the <code>URL</code> to compare against. 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return <code>true</code> if they reference the same remote object; 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>false</code> otherwise. 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean sameFile(URL other) { 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler.sameFile(this, other); 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a string representation of this <code>URL</code>. The 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * string is created by calling the <code>toExternalForm</code> 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method of the stream protocol handler for this object. 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a string representation of this object. 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, int, 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.String) 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler#toExternalForm(java.net.URL) 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toString() { 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return toExternalForm(); 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a string representation of this <code>URL</code>. The 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * string is created by calling the <code>toExternalForm</code> 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method of the stream protocol handler for this object. 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a string representation of this object. 93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler#toExternalForm(java.net.URL) 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toExternalForm() { 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler.toExternalForm(this); 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a {@link java.net.URI} equivalent to this URL. 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method functions in the same way as <code>new URI (this.toString())</code>. 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Note, any URL instance that complies with RFC 2396 can be converted 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to a URI. However, some URLs that are not strictly in compliance 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * can not be converted to a URI. 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception URISyntaxException if this URL is not formatted strictly according to 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to RFC2396 and cannot be converted to a URI. 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a URI instance equivalent to this URL. 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.5 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URI toURI() throws URISyntaxException { 95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new URI (toString()); 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a {@link java.net.URLConnection URLConnection} instance that 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * represents a connection to the remote object referred to by the 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code URL}. 96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>A new instance of {@linkplain java.net.URLConnection URLConnection} is 96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * created every time when invoking the 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@linkplain java.net.URLStreamHandler#openConnection(URL) 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * URLStreamHandler.openConnection(URL)} method of the protocol handler for 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this URL.</P> 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>It should be noted that a URLConnection instance does not establish 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the actual network connection on creation. This will happen only when 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calling {@linkplain java.net.URLConnection#connect() URLConnection.connect()}.</P> 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>If for the URL's protocol (such as HTTP or JAR), there 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exists a public, specialized URLConnection subclass belonging 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to one of the following packages or one of their subpackages: 97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang, java.io, java.util, java.net, the connection 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returned will be of that subclass. For example, for HTTP an 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * HttpURLConnection will be returned, and for JAR a 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * JarURLConnection will be returned.</P> 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a {@link java.net.URLConnection URLConnection} linking 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the URL. 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O exception occurs. 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URLConnection openConnection() throws java.io.IOException { 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler.openConnection(this); 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Same as {@link #openConnection()}, except that the connection will be 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * made through the specified proxy; Protocol handlers that do not 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * support proxing will ignore the proxy parameter and make a 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * normal connection. 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Invoking this method preempts the system's default ProxySelector 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * settings. 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param proxy the Proxy through which this connection 100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will be made. If direct connection is desired, 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Proxy.NO_PROXY should be specified. 100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a <code>URLConnection</code> to the URL. 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O exception occurs. 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager is present 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the caller doesn't have permission to connect 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the proxy. 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException will be thrown if proxy is null, 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or proxy has the wrong type 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception UnsupportedOperationException if the subclass that 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implements the protocol handler doesn't support 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this method. 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLConnection 101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandler#openConnection(java.net.URL, 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.net.Proxy) 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.5 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public URLConnection openConnection(Proxy proxy) 102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws java.io.IOException { 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (proxy == null) { 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("proxy can not be null"); 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Create a copy of Proxy as a security measure 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (p.type() != Proxy.Type.DIRECT && sm != null) { 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress epoint = (InetSocketAddress) p.address(); 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (epoint.isUnresolved()) 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkConnect(epoint.getHostName(), epoint.getPort()); 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkConnect(epoint.getAddress().getHostAddress(), 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski epoint.getPort()); 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler.openConnection(this, p); 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Opens a connection to this <code>URL</code> and returns an 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>InputStream</code> for reading from that connection. This 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is a shorthand for: 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * openConnection().getInputStream() 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return an input stream for reading from the URL connection. 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O exception occurs. 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#openConnection() 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLConnection#getInputStream() 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final InputStream openStream() throws java.io.IOException { 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return openConnection().getInputStream(); 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the contents of this URL. This method is a shorthand for: 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * openConnection().getContent() 106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the contents of this URL. 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O exception occurs. 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLConnection#getContent() 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final Object getContent() throws java.io.IOException { 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return openConnection().getContent(); 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the contents of this URL. This method is a shorthand for: 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote><pre> 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * openConnection().getContent(Class[]) 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre></blockquote> 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param classes an array of Java types 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the content object of this URL that is the first match of 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the types specified in the classes array. 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * null if none of the requested types are supported. 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O exception occurs. 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLConnection#getContent(Class[]) 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final Object getContent(Class[] classes) 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws java.io.IOException { 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return openConnection().getContent(classes); 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The URLStreamHandler factory. 109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static URLStreamHandlerFactory factory; 109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets an application's <code>URLStreamHandlerFactory</code>. 110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method can be called at most once in a given Java Virtual 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Machine. 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *<p> The <code>URLStreamHandlerFactory</code> instance is used to 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *construct a stream protocol handler from a protocol name. 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> If there is a security manager, this method first calls 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the security manager's <code>checkSetFactory</code> method 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to ensure the operation is allowed. 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This could result in a SecurityException. 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param fac the desired factory. 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception Error if the application has already set a factory. 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkSetFactory</code> method doesn't allow 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the operation. 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URL#URL(java.lang.String, java.lang.String, 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * int, java.lang.String) 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.URLStreamHandlerFactory 111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkSetFactory 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) { 112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (streamHandlerLock) { 112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (factory != null) { 112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new Error("factory already defined"); 112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (security != null) { 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkSetFactory(); 112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handlers.clear(); 113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski factory = fac; 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A table of protocol handlers. 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static Hashtable handlers = new Hashtable(); 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Object streamHandlerLock = new Object(); 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the Stream Handler. 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param protocol the protocol to use 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static URLStreamHandler getURLStreamHandler(String protocol) { 114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URLStreamHandler handler = (URLStreamHandler)handlers.get(protocol); 114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler == null) { 114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean checkedWithFactory = false; 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Use the factory (if any) 115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (factory != null) { 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler = factory.createURLStreamHandler(protocol); 115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkedWithFactory = true; 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Try java protocol handler 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler == null) { 1160f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath final String packagePrefixList = System.getProperty(protocolPathProp,""); 1161f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath StringTokenizer packagePrefixIter = new StringTokenizer(packagePrefixList, "|"); 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (handler == null && 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski packagePrefixIter.hasMoreTokens()) { 116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1166f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath String packagePrefix = packagePrefixIter.nextToken().trim(); 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 1168f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath String clsName = packagePrefix + "." + protocol + ".Handler"; 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Class cls = null; 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ClassLoader cl = ClassLoader.getSystemClassLoader(); 1172f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath cls = Class.forName(clsName, true, cl); 1173f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath } catch (ClassNotFoundException e) { 1174f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); 1175f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath if (contextLoader != null) { 1176f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath cls = Class.forName(clsName, true, contextLoader); 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cls != null) { 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler = 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (URLStreamHandler)cls.newInstance(); 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1183f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath } catch (ReflectiveOperationException ignored) { 118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1188320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak // Fallback to built-in stream handler. 1189f861f1e3bb6be1cd486079fc240337f84836d21cNarayan Kamath // Makes okhttp the default http/https handler 1190320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak if (handler == null) { 1191320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak try { 1192320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak if (protocol.equals("file")) { 1193320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak handler = (URLStreamHandler)Class. 1194320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak forName("sun.net.www.protocol.file.Handler").newInstance(); 1195320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } else if (protocol.equals("ftp")) { 1196320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak handler = (URLStreamHandler)Class. 1197320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak forName("sun.net.www.protocol.ftp.Handler").newInstance(); 1198320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } else if (protocol.equals("jar")) { 1199320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak handler = (URLStreamHandler)Class. 1200320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak forName("sun.net.www.protocol.jar.Handler").newInstance(); 1201320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } else if (protocol.equals("http")) { 1202320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak handler = (URLStreamHandler)Class. 1203320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak forName("com.android.okhttp.HttpHandler").newInstance(); 1204320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } else if (protocol.equals("https")) { 1205320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak handler = (URLStreamHandler)Class. 1206320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak forName("com.android.okhttp.HttpsHandler").newInstance(); 1207320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } 1208320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } catch (Exception e) { 1209320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak throw new AssertionError(e); 1210320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } 1211320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak } 1212320a3d38fa5a32ceb5e342e439862604b2626807Przemyslaw Szczepaniak 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (streamHandlerLock) { 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URLStreamHandler handler2 = null; 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Check again with hashtable just in case another 121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // thread created a handler since we last checked 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler2 = (URLStreamHandler)handlers.get(protocol); 122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler2 != null) { 122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler2; 122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Check with factory if another thread set a 122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // factory since our last check 122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!checkedWithFactory && factory != null) { 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler2 = factory.createURLStreamHandler(protocol); 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler2 != null) { 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The handler from the factory must be given more 123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // importance. Discard the default handler that 123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this thread created. 123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handler = handler2; 123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Insert this handler into the hashtable 123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (handler != null) { 124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski handlers.put(protocol, handler); 124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return handler; 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * WriteObject is called to save the state of the URL to an 125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ObjectOutputStream. The handler is not saved since it is 125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specific to this system. 125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serialData the default write object value. When read back in, 125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the reader must ensure that calling getURLStreamHandler with 125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the protocol variable returns a valid URLStreamHandler and 125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * throw an IOException if it does not. 125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized void writeObject(java.io.ObjectOutputStream s) 126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.defaultWriteObject(); // write the fields 126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * readObject is called to restore the state of the URL from the 126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream. It reads the components of the URL and finds the local 126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stream handler. 127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized void readObject(java.io.ObjectInputStream s) 127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException 127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.defaultReadObject(); // read the fields 127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((handler = getURLStreamHandler(protocol)) == null) { 127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("unknown protocol: " + protocol); 127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Construct authority part 128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (authority == null && 128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((host != null && host.length() > 0) || port != -1)) { 128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (host == null) 128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host = ""; 128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski authority = (port == -1) ? host : host + ":" + port; 128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Handle hosts with userInfo in them 128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int at = host.lastIndexOf('@'); 128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (at != -1) { 128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski userInfo = host.substring(0, at); 129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host = host.substring(at+1); 129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (authority != null) { 129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Construct user info part 129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ind = authority.indexOf('@'); 129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ind != -1) 129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski userInfo = authority.substring(0, ind); 129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Construct path and query part 130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = null; 130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski query = null; 130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (file != null) { 130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Fix: only do this if hierarchical? 130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int q = file.lastIndexOf('?'); 130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (q != -1) { 130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski query = file.substring(q+1); 130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = file.substring(0, q); 130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = file; 131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 131106fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak hashCode = -1; 131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass Parts { 131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String path, query, ref; 131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 131806fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak Parts(String file, String host) { 131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ind = file.indexOf('#'); 132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ref = ind < 0 ? null: file.substring(ind + 1); 132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski file = ind < 0 ? file: file.substring(0, ind); 132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int q = file.lastIndexOf('?'); 132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (q != -1) { 132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski query = file.substring(q+1); 132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = file.substring(0, q); 132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski path = file; 132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 132906fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak if (path != null && path.length() > 0 && path.charAt(0) != '/' && 133006fc5c380e77f61adcf02305c5bbea9eac129583Przemyslaw Szczepaniak host != null && !host.isEmpty()) { 1331a53c889dff2031f9eb20594c1a172c6a228c0298Przemyslaw Szczepaniak path = '/' + path; 1332a53c889dff2031f9eb20594c1a172c6a228c0298Przemyslaw Szczepaniak } 133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String getPath() { 133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return path; 133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String getQuery() { 134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return query; 134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String getRef() { 134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ref; 134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 1347