Source Code Cross Referenced for URL.java in  » 6.0-JDK-Core » net » java » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » net » java.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.net;
0027
0028        import java.io.IOException;
0029        import java.io.InputStream;
0030        import java.io.OutputStream;
0031        import java.util.Hashtable;
0032        import java.util.StringTokenizer;
0033        import sun.security.util.SecurityConstants;
0034
0035        /**
0036         * Class <code>URL</code> represents a Uniform Resource
0037         * Locator, a pointer to a "resource" on the World
0038         * Wide Web. A resource can be something as simple as a file or a
0039         * directory, or it can be a reference to a more complicated object,
0040         * such as a query to a database or to a search engine. More
0041         * information on the types of URLs and their formats can be found at:
0042         * <blockquote>
0043         *     <a href="http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html">
0044         *    <i>http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html</i></a>
0045         * </blockquote>
0046         * <p>
0047         * In general, a URL can be broken into several parts. The previous
0048         * example of a URL indicates that the protocol to use is
0049         * <code>http</code> (HyperText Transfer Protocol) and that the
0050         * information resides on a host machine named
0051         * <code>www.socs.uts.edu.au</code>. The information on that host
0052         * machine is named <code>/MosaicDocs-old/url-primer.html</code>. The exact
0053         * meaning of this name on the host machine is both protocol
0054         * dependent and host dependent. The information normally resides in
0055         * a file, but it could be generated on the fly. This component of
0056         * the URL is called the <i>path</i> component.
0057         * <p>
0058         * A URL can optionally specify a "port", which is the
0059         * port number to which the TCP connection is made on the remote host
0060         * machine. If the port is not specified, the default port for
0061         * the protocol is used instead. For example, the default port for
0062         * <code>http</code> is <code>80</code>. An alternative port could be
0063         * specified as:
0064         * <blockquote><pre>
0065         *     http://www.socs.uts.edu.au:80/MosaicDocs-old/url-primer.html
0066         * </pre></blockquote>
0067         * <p>
0068         * The syntax of <code>URL</code> is defined by  <a
0069         * href="http://www.ietf.org/rfc/rfc2396.txt""><i>RFC&nbsp;2396: Uniform
0070         * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a
0071         * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for
0072         * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format
0073         * also supports scope_ids. The syntax and usage of scope_ids is described
0074         * <a href="Inet6Address.html#scoped">here</a>.
0075         * <p>
0076         * A URL may have appended to it a "fragment", also known
0077         * as a "ref" or a "reference". The fragment is indicated by the sharp
0078         * sign character "#" followed by more characters. For example,
0079         * <blockquote><pre>
0080         *     http://java.sun.com/index.html#chapter1
0081         * </pre></blockquote>
0082         * <p>
0083         * This fragment is not technically part of the URL. Rather, it
0084         * indicates that after the specified resource is retrieved, the
0085         * application is specifically interested in that part of the
0086         * document that has the tag <code>chapter1</code> attached to it. The
0087         * meaning of a tag is resource specific.
0088         * <p>
0089         * An application can also specify a "relative URL",
0090         * which contains only enough information to reach the resource
0091         * relative to another URL. Relative URLs are frequently used within
0092         * HTML pages. For example, if the contents of the URL:
0093         * <blockquote><pre>
0094         *     http://java.sun.com/index.html
0095         * </pre></blockquote>
0096         * contained within it the relative URL:
0097         * <blockquote><pre>
0098         *     FAQ.html
0099         * </pre></blockquote>
0100         * it would be a shorthand for:
0101         * <blockquote><pre>
0102         *     http://java.sun.com/FAQ.html
0103         * </pre></blockquote>
0104         * <p>
0105         * The relative URL need not specify all the components of a URL. If
0106         * the protocol, host name, or port number is missing, the value is
0107         * inherited from the fully specified URL. The file component must be
0108         * specified. The optional fragment is not inherited.
0109         * <p>
0110         * The URL class does not itself encode or decode any URL components
0111         * according to the escaping mechanism defined in RFC2396. It is the
0112         * responsibility of the caller to encode any fields, which need to be
0113         * escaped prior to calling URL, and also to decode any escaped fields,
0114         * that are returned from URL. Furthermore, because URL has no knowledge
0115         * of URL escaping, it does not recognise equivalence between the encoded
0116         * or decoded form of the same URL. For example, the two URLs:<br>
0117         * <pre>    http://foo.com/hello world/ and http://foo.com/hello%20world</pre>
0118         * would be considered not equal to each other.
0119         * <p>
0120         * Note, the {@link java.net.URI} class does perform escaping of its
0121         * component fields in certain circumstances. The recommended way
0122         * to manage the encoding and decoding of URLs is to use {@link java.net.URI},
0123         * and to convert between these two classes using {@link #toURI()} and
0124         * {@link URI#toURL()}.
0125         * <p>
0126         * The {@link URLEncoder} and {@link URLDecoder} classes can also be
0127         * used, but only for HTML form encoding, which is not the same
0128         * as the encoding scheme defined in RFC2396.
0129         *
0130         * @author  James Gosling
0131         * @version 1.144, 07/20/07
0132         * @since JDK1.0 
0133         */
0134        public final class URL implements  java.io.Serializable {
0135
0136            static final long serialVersionUID = -7627629688361524110L;
0137
0138            /**
0139             * The property which specifies the package prefix list to be scanned
0140             * for protocol handlers.  The value of this property (if any) should
0141             * be a vertical bar delimited list of package names to search through
0142             * for a protocol handler to load.  The policy of this class is that
0143             * all protocol handlers will be in a class called <protocolname>.Handler,
0144             * and each package in the list is examined in turn for a matching
0145             * handler.  If none are found (or the property is not specified), the
0146             * default package prefix, sun.net.www.protocol, is used.  The search
0147             * proceeds from the first package in the list to the last and stops
0148             * when a match is found.
0149             */
0150            private static final String protocolPathProp = "java.protocol.handler.pkgs";
0151
0152            /**
0153             * The protocol to use (ftp, http, nntp, ... etc.) .
0154             * @serial
0155             */
0156            private String protocol;
0157
0158            /**
0159             * The host name to connect to.
0160             * @serial
0161             */
0162            private String host;
0163
0164            /**
0165             * The protocol port to connect to.
0166             * @serial
0167             */
0168            private int port = -1;
0169
0170            /**
0171             * The specified file name on that host. <code>file</code> is
0172             * defined as <code>path[?query]</code>
0173             * @serial
0174             */
0175            private String file;
0176
0177            /**
0178             * The query part of this URL.
0179             */
0180            private transient String query;
0181
0182            /**
0183             * The authority part of this URL.
0184             * @serial
0185             */
0186            private String authority;
0187
0188            /**
0189             * The path part of this URL.
0190             */
0191            private transient String path;
0192
0193            /**
0194             * The userinfo part of this URL.
0195             */
0196            private transient String userInfo;
0197
0198            /**
0199             * # reference.
0200             * @serial
0201             */
0202            private String ref;
0203
0204            /**
0205             * The host's IP address, used in equals and hashCode.
0206             * Computed on demand. An uninitialized or unknown hostAddress is null.
0207             */
0208            transient InetAddress hostAddress;
0209
0210            /**
0211             * The URLStreamHandler for this URL.
0212             */
0213            transient URLStreamHandler handler;
0214
0215            /* Our hash code.
0216             * @serial
0217             */
0218            private int hashCode = -1;
0219
0220            /**
0221             * Creates a <code>URL</code> object from the specified
0222             * <code>protocol</code>, <code>host</code>, <code>port</code>
0223             * number, and <code>file</code>.<p>
0224             *
0225             * <code>host</code> can be expressed as a host name or a literal
0226             * IP address. If IPv6 literal address is used, it should be
0227             * enclosed in square brackets (<tt>'['</tt> and <tt>']'</tt>), as
0228             * specified by <a
0229             * href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>;
0230             * However, the literal IPv6 address format defined in <a
0231             * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IP
0232             * Version 6 Addressing Architecture</i></a> is also accepted.<p>
0233             *
0234             * Specifying a <code>port</code> number of <code>-1</code>
0235             * indicates that the URL should use the default port for the
0236             * protocol.<p>
0237             *
0238             * If this is the first URL object being created with the specified
0239             * protocol, a <i>stream protocol handler</i> object, an instance of
0240             * class <code>URLStreamHandler</code>, is created for that protocol:
0241             * <ol>
0242             * <li>If the application has previously set up an instance of
0243             *     <code>URLStreamHandlerFactory</code> as the stream handler factory,
0244             *     then the <code>createURLStreamHandler</code> method of that instance
0245             *     is called with the protocol string as an argument to create the
0246             *     stream protocol handler.
0247             * <li>If no <code>URLStreamHandlerFactory</code> has yet been set up,
0248             *     or if the factory's <code>createURLStreamHandler</code> method
0249             *     returns <code>null</code>, then the constructor finds the
0250             *     value of the system property:
0251             *     <blockquote><pre>
0252             *         java.protocol.handler.pkgs
0253             *     </pre></blockquote>
0254             *     If the value of that system property is not <code>null</code>,
0255             *     it is interpreted as a list of packages separated by a vertical
0256             *     slash character '<code>|</code>'. The constructor tries to load
0257             *     the class named:
0258             *     <blockquote><pre>
0259             *         &lt;<i>package</i>&gt;.&lt;<i>protocol</i>&gt;.Handler
0260             *     </pre></blockquote>
0261             *     where &lt;<i>package</i>&gt; is replaced by the name of the package
0262             *     and &lt;<i>protocol</i>&gt; is replaced by the name of the protocol.
0263             *     If this class does not exist, or if the class exists but it is not
0264             *     a subclass of <code>URLStreamHandler</code>, then the next package
0265             *     in the list is tried.
0266             * <li>If the previous step fails to find a protocol handler, then the
0267             *     constructor tries to load from a system default package.
0268             *     <blockquote><pre>
0269             *         &lt;<i>system default package</i>&gt;.&lt;<i>protocol</i>&gt;.Handler
0270             *     </pre></blockquote>
0271             *     If this class does not exist, or if the class exists but it is not a
0272             *     subclass of <code>URLStreamHandler</code>, then a
0273             *     <code>MalformedURLException</code> is thrown.
0274             * </ol>
0275             *
0276             * <p>Protocol handlers for the following protocols are guaranteed
0277             * to exist on the search path :-
0278             * <blockquote><pre>
0279             *     http, https, ftp, file, and jar
0280             * </pre></blockquote>
0281             * Protocol handlers for additional protocols may also be
0282             * available.
0283             *
0284             * <p>No validation of the inputs is performed by this constructor.
0285             *
0286             * @param      protocol   the name of the protocol to use.
0287             * @param      host       the name of the host.
0288             * @param      port       the port number on the host.
0289             * @param      file       the file on the host
0290             * @exception  MalformedURLException  if an unknown protocol is specified.
0291             * @see        java.lang.System#getProperty(java.lang.String)
0292             * @see        java.net.URL#setURLStreamHandlerFactory(
0293             *			java.net.URLStreamHandlerFactory)
0294             * @see        java.net.URLStreamHandler
0295             * @see        java.net.URLStreamHandlerFactory#createURLStreamHandler(
0296             *                  java.lang.String)
0297             */
0298            public URL(String protocol, String host, int port, String file)
0299                    throws MalformedURLException {
0300                this (protocol, host, port, file, null);
0301            }
0302
0303            /**
0304             * Creates a URL from the specified <code>protocol</code>
0305             * name, <code>host</code> name, and <code>file</code> name. The
0306             * default port for the specified protocol is used.
0307             * <p>
0308             * This method is equivalent to calling the four-argument
0309             * constructor with the arguments being <code>protocol</code>,
0310             * <code>host</code>, <code>-1</code>, and <code>file</code>.
0311             *
0312             * No validation of the inputs is performed by this constructor.
0313             *
0314             * @param      protocol   the name of the protocol to use.
0315             * @param      host       the name of the host.
0316             * @param      file       the file on the host.
0317             * @exception  MalformedURLException  if an unknown protocol is specified.
0318             * @see        java.net.URL#URL(java.lang.String, java.lang.String,
0319             *			int, java.lang.String)
0320             */
0321            public URL(String protocol, String host, String file)
0322                    throws MalformedURLException {
0323                this (protocol, host, -1, file);
0324            }
0325
0326            /**
0327             * Creates a <code>URL</code> object from the specified
0328             * <code>protocol</code>, <code>host</code>, <code>port</code>
0329             * number, <code>file</code>, and <code>handler</code>. Specifying
0330             * a <code>port</code> number of <code>-1</code> indicates that
0331             * the URL should use the default port for the protocol. Specifying
0332             * a <code>handler</code> of <code>null</code> indicates that the URL
0333             * should use a default stream handler for the protocol, as outlined
0334             * for:
0335             *     java.net.URL#URL(java.lang.String, java.lang.String, int,
0336             *                      java.lang.String)
0337             *
0338             * <p>If the handler is not null and there is a security manager,
0339             * the security manager's <code>checkPermission</code>
0340             * method is called with a
0341             * <code>NetPermission("specifyStreamHandler")</code> permission.
0342             * This may result in a SecurityException.
0343             *
0344             * No validation of the inputs is performed by this constructor.
0345             *
0346             * @param      protocol   the name of the protocol to use.
0347             * @param      host       the name of the host.
0348             * @param      port       the port number on the host.
0349             * @param      file       the file on the host
0350             * @param	   handler    the stream handler for the URL.
0351             * @exception  MalformedURLException  if an unknown protocol is specified.
0352             * @exception  SecurityException
0353             *        if a security manager exists and its
0354             *        <code>checkPermission</code> method doesn't allow
0355             *        specifying a stream handler explicitly.
0356             * @see        java.lang.System#getProperty(java.lang.String)
0357             * @see        java.net.URL#setURLStreamHandlerFactory(
0358             *			java.net.URLStreamHandlerFactory)
0359             * @see        java.net.URLStreamHandler
0360             * @see        java.net.URLStreamHandlerFactory#createURLStreamHandler(
0361             *			java.lang.String)
0362             * @see        SecurityManager#checkPermission
0363             * @see        java.net.NetPermission
0364             */
0365            public URL(String protocol, String host, int port, String file,
0366                    URLStreamHandler handler) throws MalformedURLException {
0367                if (handler != null) {
0368                    SecurityManager sm = System.getSecurityManager();
0369                    if (sm != null) {
0370                        // check for permission to specify a handler
0371                        checkSpecifyHandler(sm);
0372                    }
0373                }
0374
0375                protocol = protocol.toLowerCase();
0376                this .protocol = protocol;
0377                if (host != null) {
0378
0379                    /**
0380                     * if host is a literal IPv6 address,
0381                     * we will make it conform to RFC 2732
0382                     */
0383                    if (host.indexOf(':') >= 0 && !host.startsWith("[")) {
0384                        host = "[" + host + "]";
0385                    }
0386                    this .host = host;
0387
0388                    if (port < -1) {
0389                        throw new MalformedURLException("Invalid port number :"
0390                                + port);
0391                    }
0392                    this .port = port;
0393                    authority = (port == -1) ? host : host + ":" + port;
0394                }
0395
0396                Parts parts = new Parts(file);
0397                path = parts.getPath();
0398                query = parts.getQuery();
0399
0400                if (query != null) {
0401                    this .file = path + "?" + query;
0402                } else {
0403                    this .file = path;
0404                }
0405                ref = parts.getRef();
0406
0407                // Note: we don't do validation of the URL here. Too risky to change
0408                // right now, but worth considering for future reference. -br
0409                if (handler == null
0410                        && (handler = getURLStreamHandler(protocol)) == null) {
0411                    throw new MalformedURLException("unknown protocol: "
0412                            + protocol);
0413                }
0414                this .handler = handler;
0415            }
0416
0417            /**
0418             * Creates a <code>URL</code> object from the <code>String</code>
0419             * representation.
0420             * <p>
0421             * This constructor is equivalent to a call to the two-argument
0422             * constructor with a <code>null</code> first argument.
0423             *
0424             * @param      spec   the <code>String</code> to parse as a URL.
0425             * @exception  MalformedURLException  if no protocol is specified, or an
0426             *               unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>.
0427             * @see        java.net.URL#URL(java.net.URL, java.lang.String)
0428             */
0429            public URL(String spec) throws MalformedURLException {
0430                this (null, spec);
0431            }
0432
0433            /**
0434             * Creates a URL by parsing the given spec within a specified context.
0435             *
0436             * The new URL is created from the given context URL and the spec
0437             * argument as described in
0438             * RFC2396 &quot;Uniform Resource Identifiers : Generic * Syntax&quot; :
0439             * <blockquote><pre>
0440             *          &lt;scheme&gt;://&lt;authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt;
0441             * </pre></blockquote>
0442             * The reference is parsed into the scheme, authority, path, query and
0443             * fragment parts. If the path component is empty and the scheme,
0444             * authority, and query components are undefined, then the new URL is a
0445             * reference to the current document. Otherwise, the fragment and query
0446             * parts present in the spec are used in the new URL.
0447             * <p>
0448             * If the scheme component is defined in the given spec and does not match
0449             * the scheme of the context, then the new URL is created as an absolute
0450             * URL based on the spec alone. Otherwise the scheme component is inherited
0451             * from the context URL.
0452             * <p>
0453             * If the authority component is present in the spec then the spec is
0454             * treated as absolute and the spec authority and path will replace the
0455             * context authority and path. If the authority component is absent in the
0456             * spec then the authority of the new URL will be inherited from the
0457             * context.
0458             * <p>
0459             * If the spec's path component begins with a slash character
0460             * &quot;/&quot; then the
0461             * path is treated as absolute and the spec path replaces the context path.
0462             * <p>
0463             * Otherwise, the path is treated as a relative path and is appended to the
0464             * context path, as described in RFC2396. Also, in this case, 
0465             * the path is canonicalized through the removal of directory 
0466             * changes made by occurences of &quot;..&quot; and &quot;.&quot;.
0467             * <p>
0468             * For a more detailed description of URL parsing, refer to RFC2396.
0469             *
0470             * @param      context   the context in which to parse the specification.
0471             * @param      spec      the <code>String</code> to parse as a URL.
0472             * @exception  MalformedURLException  if no protocol is specified, or an
0473             *               unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>.
0474             * @see        java.net.URL#URL(java.lang.String, java.lang.String,
0475             *			int, java.lang.String)
0476             * @see        java.net.URLStreamHandler
0477             * @see        java.net.URLStreamHandler#parseURL(java.net.URL,
0478             *			java.lang.String, int, int)
0479             */
0480            public URL(URL context, String spec) throws MalformedURLException {
0481                this (context, spec, null);
0482            }
0483
0484            /**
0485             * Creates a URL by parsing the given spec with the specified handler
0486             * within a specified context. If the handler is null, the parsing
0487             * occurs as with the two argument constructor.
0488             *
0489             * @param      context   the context in which to parse the specification.
0490             * @param      spec      the <code>String</code> to parse as a URL.
0491             * @param	   handler   the stream handler for the URL.
0492             * @exception  MalformedURLException  if no protocol is specified, or an
0493             *               unknown protocol is found, or <tt>spec</tt> is <tt>null</tt>.
0494             * @exception  SecurityException
0495             *        if a security manager exists and its
0496             *        <code>checkPermission</code> method doesn't allow
0497             *        specifying a stream handler.
0498             * @see        java.net.URL#URL(java.lang.String, java.lang.String,
0499             *			int, java.lang.String)
0500             * @see        java.net.URLStreamHandler
0501             * @see        java.net.URLStreamHandler#parseURL(java.net.URL,
0502             *			java.lang.String, int, int)
0503             */
0504            public URL(URL context, String spec, URLStreamHandler handler)
0505                    throws MalformedURLException {
0506                String original = spec;
0507                int i, limit, c;
0508                int start = 0;
0509                String newProtocol = null;
0510                boolean aRef = false;
0511                boolean isRelative = false;
0512
0513                // Check for permission to specify a handler
0514                if (handler != null) {
0515                    SecurityManager sm = System.getSecurityManager();
0516                    if (sm != null) {
0517                        checkSpecifyHandler(sm);
0518                    }
0519                }
0520
0521                try {
0522                    limit = spec.length();
0523                    while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) {
0524                        limit--; //eliminate trailing whitespace
0525                    }
0526                    while ((start < limit) && (spec.charAt(start) <= ' ')) {
0527                        start++; // eliminate leading whitespace
0528                    }
0529
0530                    if (spec.regionMatches(true, start, "url:", 0, 4)) {
0531                        start += 4;
0532                    }
0533                    if (start < spec.length() && spec.charAt(start) == '#') {
0534                        /* we're assuming this is a ref relative to the context URL.
0535                         * This means protocols cannot start w/ '#', but we must parse
0536                         * ref URL's like: "hello:there" w/ a ':' in them.
0537                         */
0538                        aRef = true;
0539                    }
0540                    for (i = start; !aRef && (i < limit)
0541                            && ((c = spec.charAt(i)) != '/'); i++) {
0542                        if (c == ':') {
0543
0544                            String s = spec.substring(start, i).toLowerCase();
0545                            if (isValidProtocol(s)) {
0546                                newProtocol = s;
0547                                start = i + 1;
0548                            }
0549                            break;
0550                        }
0551                    }
0552
0553                    // Only use our context if the protocols match.
0554                    protocol = newProtocol;
0555                    if ((context != null)
0556                            && ((newProtocol == null) || newProtocol
0557                                    .equalsIgnoreCase(context.protocol))) {
0558                        // inherit the protocol handler from the context
0559                        // if not specified to the constructor
0560                        if (handler == null) {
0561                            handler = context.handler;
0562                        }
0563
0564                        // If the context is a hierarchical URL scheme and the spec
0565                        // contains a matching scheme then maintain backwards
0566                        // compatibility and treat it as if the spec didn't contain
0567                        // the scheme; see 5.2.3 of RFC2396
0568                        if (context.path != null
0569                                && context.path.startsWith("/"))
0570                            newProtocol = null;
0571
0572                        if (newProtocol == null) {
0573                            protocol = context.protocol;
0574                            authority = context.authority;
0575                            userInfo = context.userInfo;
0576                            host = context.host;
0577                            port = context.port;
0578                            file = context.file;
0579                            path = context.path;
0580                            isRelative = true;
0581                        }
0582                    }
0583
0584                    if (protocol == null) {
0585                        throw new MalformedURLException("no protocol: "
0586                                + original);
0587                    }
0588
0589                    // Get the protocol handler if not specified or the protocol
0590                    // of the context could not be used
0591                    if (handler == null
0592                            && (handler = getURLStreamHandler(protocol)) == null) {
0593                        throw new MalformedURLException("unknown protocol: "
0594                                + protocol);
0595                    }
0596
0597                    this .handler = handler;
0598
0599                    i = spec.indexOf('#', start);
0600                    if (i >= 0) {
0601                        ref = spec.substring(i + 1, limit);
0602                        limit = i;
0603                    }
0604
0605                    /*
0606                     * Handle special case inheritance of query and fragment
0607                     * implied by RFC2396 section 5.2.2.
0608                     */
0609                    if (isRelative && start == limit) {
0610                        query = context.query;
0611                        if (ref == null) {
0612                            ref = context.ref;
0613                        }
0614                    }
0615
0616                    handler.parseURL(this , spec, start, limit);
0617
0618                } catch (MalformedURLException e) {
0619                    throw e;
0620                } catch (Exception e) {
0621                    MalformedURLException exception = new MalformedURLException(
0622                            e.getMessage());
0623                    exception.initCause(e);
0624                    throw exception;
0625                }
0626            }
0627
0628            /*
0629             * Returns true if specified string is a valid protocol name.
0630             */
0631            private boolean isValidProtocol(String protocol) {
0632                int len = protocol.length();
0633                if (len < 1)
0634                    return false;
0635                char c = protocol.charAt(0);
0636                if (!Character.isLetter(c))
0637                    return false;
0638                for (int i = 1; i < len; i++) {
0639                    c = protocol.charAt(i);
0640                    if (!Character.isLetterOrDigit(c) && c != '.' && c != '+'
0641                            && c != '-') {
0642                        return false;
0643                    }
0644                }
0645                return true;
0646            }
0647
0648            /*
0649             * Checks for permission to specify a stream handler.
0650             */
0651            private void checkSpecifyHandler(SecurityManager sm) {
0652                sm
0653                        .checkPermission(SecurityConstants.SPECIFY_HANDLER_PERMISSION);
0654            }
0655
0656            /**
0657             * Sets the fields of the URL. This is not a public method so that
0658             * only URLStreamHandlers can modify URL fields. URLs are
0659             * otherwise constant.
0660             *
0661             * @param protocol the name of the protocol to use
0662             * @param host the name of the host
0663               @param port the port number on the host
0664             * @param file the file on the host
0665             * @param ref the internal reference in the URL
0666             */
0667            protected void set(String protocol, String host, int port,
0668                    String file, String ref) {
0669                synchronized (this ) {
0670                    this .protocol = protocol;
0671                    this .host = host;
0672                    authority = port == -1 ? host : host + ":" + port;
0673                    this .port = port;
0674                    this .file = file;
0675                    this .ref = ref;
0676                    /* This is very important. We must recompute this after the
0677                     * URL has been changed. */
0678                    hashCode = -1;
0679                    hostAddress = null;
0680                    int q = file.lastIndexOf('?');
0681                    if (q != -1) {
0682                        query = file.substring(q + 1);
0683                        path = file.substring(0, q);
0684                    } else
0685                        path = file;
0686                }
0687            }
0688
0689            /**
0690             * Sets the specified 8 fields of the URL. This is not a public method so
0691             * that only URLStreamHandlers can modify URL fields. URLs are otherwise
0692             * constant.
0693             *
0694             * @param protocol the name of the protocol to use
0695             * @param host the name of the host
0696             * @param port the port number on the host
0697             * @param authority the authority part for the url
0698             * @param userInfo the username and password
0699             * @param path the file on the host
0700             * @param ref the internal reference in the URL
0701             * @param query the query part of this URL
0702             * @since 1.3
0703             */
0704            protected void set(String protocol, String host, int port,
0705                    String authority, String userInfo, String path,
0706                    String query, String ref) {
0707                synchronized (this ) {
0708                    this .protocol = protocol;
0709                    this .host = host;
0710                    this .port = port;
0711                    this .file = query == null ? path : path + "?" + query;
0712                    this .userInfo = userInfo;
0713                    this .path = path;
0714                    this .ref = ref;
0715                    /* This is very important. We must recompute this after the
0716                     * URL has been changed. */
0717                    hashCode = -1;
0718                    hostAddress = null;
0719                    this .query = query;
0720                    this .authority = authority;
0721                }
0722            }
0723
0724            /**
0725             * Gets the query part of this <code>URL</code>.
0726             *
0727             * @return  the query part of this <code>URL</code>, 
0728             * or <CODE>null</CODE> if one does not exist
0729             * @since 1.3
0730             */
0731            public String getQuery() {
0732                return query;
0733            }
0734
0735            /**
0736             * Gets the path part of this <code>URL</code>.
0737             *
0738             * @return  the path part of this <code>URL</code>, or an
0739             * empty string if one does not exist
0740             * @since 1.3
0741             */
0742            public String getPath() {
0743                return path;
0744            }
0745
0746            /**
0747             * Gets the userInfo part of this <code>URL</code>.
0748             *
0749             * @return  the userInfo part of this <code>URL</code>, or 
0750             * <CODE>null</CODE> if one does not exist
0751             * @since 1.3
0752             */
0753            public String getUserInfo() {
0754                return userInfo;
0755            }
0756
0757            /**
0758             * Gets the authority part of this <code>URL</code>.
0759             *
0760             * @return  the authority part of this <code>URL</code>
0761             * @since 1.3
0762             */
0763            public String getAuthority() {
0764                return authority;
0765            }
0766
0767            /**
0768             * Gets the port number of this <code>URL</code>.
0769             *
0770             * @return  the port number, or -1 if the port is not set
0771             */
0772            public int getPort() {
0773                return port;
0774            }
0775
0776            /**
0777             * Gets the default port number of the protocol associated
0778             * with this <code>URL</code>. If the URL scheme or the URLStreamHandler
0779             * for the URL do not define a default port number,
0780             * then -1 is returned.
0781             *
0782             * @return  the port number
0783             * @since 1.4
0784             */
0785            public int getDefaultPort() {
0786                return handler.getDefaultPort();
0787            }
0788
0789            /**
0790             * Gets the protocol name of this <code>URL</code>.
0791             *
0792             * @return  the protocol of this <code>URL</code>.
0793             */
0794            public String getProtocol() {
0795                return protocol;
0796            }
0797
0798            /**
0799             * Gets the host name of this <code>URL</code>, if applicable.
0800             * The format of the host conforms to RFC 2732, i.e. for a
0801             * literal IPv6 address, this method will return the IPv6 address
0802             * enclosed in square brackets (<tt>'['</tt> and <tt>']'</tt>).
0803             *
0804             * @return  the host name of this <code>URL</code>.
0805             */
0806            public String getHost() {
0807                return host;
0808            }
0809
0810            /**
0811             * Gets the file name of this <code>URL</code>.
0812             * The returned file portion will be
0813             * the same as <CODE>getPath()</CODE>, plus the concatenation of
0814             * the value of <CODE>getQuery()</CODE>, if any. If there is 
0815             * no query portion, this method and <CODE>getPath()</CODE> will
0816             * return identical results.
0817             *
0818             * @return  the file name of this <code>URL</code>,
0819             * or an empty string if one does not exist
0820             */
0821            public String getFile() {
0822                return file;
0823            }
0824
0825            /**
0826             * Gets the anchor (also known as the "reference") of this
0827             * <code>URL</code>.
0828             *
0829             * @return  the anchor (also known as the "reference") of this
0830             *          <code>URL</code>, or <CODE>null</CODE> if one does not exist
0831             */
0832            public String getRef() {
0833                return ref;
0834            }
0835
0836            /**
0837             * Compares this URL for equality with another object.<p>
0838             *
0839             * If the given object is not a URL then this method immediately returns
0840             * <code>false</code>.<p>
0841             *
0842             * Two URL objects are equal if they have the same protocol, reference
0843             * equivalent hosts, have the same port number on the host, and the same
0844             * file and fragment of the file.<p>
0845             *
0846             * Two hosts are considered equivalent if both host names can be resolved
0847             * into the same IP addresses; else if either host name can't be
0848             * resolved, the host names must be equal without regard to case; or both
0849             * host names equal to null.<p>
0850             *
0851             * Since hosts comparison requires name resolution, this operation is a
0852             * blocking operation. <p>
0853             *
0854             * Note: The defined behavior for <code>equals</code> is known to
0855             * be inconsistent with virtual hosting in HTTP.
0856             *
0857             * @param   obj   the URL to compare against.
0858             * @return  <code>true</code> if the objects are the same;
0859             *          <code>false</code> otherwise.
0860             */
0861            public boolean equals(Object obj) {
0862                if (!(obj instanceof  URL))
0863                    return false;
0864                URL u2 = (URL) obj;
0865
0866                return handler.equals(this , u2);
0867            }
0868
0869            /**
0870             * Creates an integer suitable for hash table indexing.<p>
0871             * 
0872             * The hash code is based upon all the URL components relevant for URL
0873             * comparison. As such, this operation is a blocking operation.<p>
0874             *
0875             * @return  a hash code for this <code>URL</code>.
0876             */
0877            public synchronized int hashCode() {
0878                if (hashCode != -1)
0879                    return hashCode;
0880
0881                hashCode = handler.hashCode(this );
0882                return hashCode;
0883            }
0884
0885            /**
0886             * Compares two URLs, excluding the fragment component.<p>
0887             *
0888             * Returns <code>true</code> if this <code>URL</code> and the
0889             * <code>other</code> argument are equal without taking the
0890             * fragment component into consideration.
0891             *
0892             * @param   other   the <code>URL</code> to compare against.
0893             * @return  <code>true</code> if they reference the same remote object;
0894             *          <code>false</code> otherwise.
0895             */
0896            public boolean sameFile(URL other) {
0897                return handler.sameFile(this , other);
0898            }
0899
0900            /**
0901             * Constructs a string representation of this <code>URL</code>. The
0902             * string is created by calling the <code>toExternalForm</code>
0903             * method of the stream protocol handler for this object.
0904             *
0905             * @return  a string representation of this object.
0906             * @see     java.net.URL#URL(java.lang.String, java.lang.String, int,
0907             *			java.lang.String)
0908             * @see     java.net.URLStreamHandler#toExternalForm(java.net.URL)
0909             */
0910            public String toString() {
0911                return toExternalForm();
0912            }
0913
0914            /**
0915             * Constructs a string representation of this <code>URL</code>. The
0916             * string is created by calling the <code>toExternalForm</code>
0917             * method of the stream protocol handler for this object.
0918             *
0919             * @return  a string representation of this object.
0920             * @see     java.net.URL#URL(java.lang.String, java.lang.String,
0921             *			int, java.lang.String)
0922             * @see     java.net.URLStreamHandler#toExternalForm(java.net.URL)
0923             */
0924            public String toExternalForm() {
0925                return handler.toExternalForm(this );
0926            }
0927
0928            /**
0929             * Returns a {@link java.net.URI} equivalent to this URL.
0930             * This method functions in the same way as <code>new URI (this.toString())</code>.
0931             * <p>Note, any URL instance that complies with RFC 2396 can be converted 
0932             * to a URI. However, some URLs that are not strictly in compliance 
0933             * can not be converted to a URI.
0934             *
0935             * @exception URISyntaxException if this URL is not formatted strictly according to
0936             *		  to RFC2396 and cannot be converted to a URI.
0937             *
0938             * @return    a URI instance equivalent to this URL.
0939             * @since 1.5
0940             */
0941            public URI toURI() throws URISyntaxException {
0942                return new URI(toString());
0943            }
0944
0945            /**
0946             * Returns a {@link java.net.URLConnection URLConnection} instance that
0947             * represents a connection to the remote object referred to by the
0948             * {@code URL}.
0949             *
0950             * <P>A new instance of {@linkplain java.net.URLConnection URLConnection} is
0951             * created every time when invoking the
0952             * {@linkplain java.net.URLStreamHandler#openConnection(URL) 
0953             * URLStreamHandler.openConnection(URL)} method of the protocol handler for
0954             * this URL.</P>
0955             *
0956             * <P>It should be noted that a URLConnection instance does not establish
0957             * the actual network connection on creation. This will happen only when
0958             * calling {@linkplain java.net.URLConnection#connect() URLConnection.connect()}.</P>
0959             *
0960             * <P>If for the URL's protocol (such as HTTP or JAR), there
0961             * exists a public, specialized URLConnection subclass belonging
0962             * to one of the following packages or one of their subpackages:
0963             * java.lang, java.io, java.util, java.net, the connection
0964             * returned will be of that subclass. For example, for HTTP an
0965             * HttpURLConnection will be returned, and for JAR a
0966             * JarURLConnection will be returned.</P>
0967             *
0968             * @return     a {@link java.net.URLConnection URLConnection} linking 
0969             *		   to the URL.
0970             * @exception  IOException  if an I/O exception occurs.
0971             * @see        java.net.URL#URL(java.lang.String, java.lang.String,
0972             *             int, java.lang.String)
0973             */
0974            public URLConnection openConnection() throws java.io.IOException {
0975                return handler.openConnection(this );
0976            }
0977
0978            /**
0979             * Same as {@link #openConnection()}, except that the connection will be
0980             * made through the specified proxy; Protocol handlers that do not
0981             * support proxing will ignore the proxy parameter and make a
0982             * normal connection.
0983             *
0984             * Invoking this method preempts the system's default ProxySelector
0985             * settings.
0986             *
0987             * @param      proxy the Proxy through which this connection
0988             *             will be made. If direct connection is desired,
0989             *             Proxy.NO_PROXY should be specified.
0990             * @return     a <code>URLConnection</code> to the URL.
0991             * @exception  IOException  if an I/O exception occurs.
0992             * @exception  SecurityException if a security manager is present
0993             *             and the caller doesn't have permission to connect
0994             *             to the proxy.
0995             * @exception  IllegalArgumentException will be thrown if proxy is null,
0996             *             or proxy has the wrong type
0997             * @exception  UnsupportedOperationException if the subclass that
0998             *             implements the protocol handler doesn't support
0999             *             this method.
1000             * @see        java.net.URL#URL(java.lang.String, java.lang.String,
1001             *             int, java.lang.String)
1002             * @see        java.net.URLConnection
1003             * @see        java.net.URLStreamHandler#openConnection(java.net.URL,
1004             *             java.net.Proxy)
1005             * @since      1.5
1006             */
1007            public URLConnection openConnection(Proxy proxy)
1008                    throws java.io.IOException {
1009                if (proxy == null) {
1010                    throw new IllegalArgumentException("proxy can not be null");
1011                }
1012
1013                SecurityManager sm = System.getSecurityManager();
1014                if (proxy.type() != Proxy.Type.DIRECT && sm != null) {
1015                    InetSocketAddress epoint = (InetSocketAddress) proxy
1016                            .address();
1017                    if (epoint.isUnresolved())
1018                        sm.checkConnect(epoint.getHostName(), epoint.getPort());
1019                    else
1020                        sm.checkConnect(epoint.getAddress().getHostAddress(),
1021                                epoint.getPort());
1022                }
1023                return handler.openConnection(this , proxy);
1024            }
1025
1026            /**
1027             * Opens a connection to this <code>URL</code> and returns an
1028             * <code>InputStream</code> for reading from that connection. This
1029             * method is a shorthand for:
1030             * <blockquote><pre>
1031             *     openConnection().getInputStream()
1032             * </pre></blockquote>
1033             *
1034             * @return     an input stream for reading from the URL connection.
1035             * @exception  IOException  if an I/O exception occurs.
1036             * @see        java.net.URL#openConnection()
1037             * @see        java.net.URLConnection#getInputStream()
1038             */
1039            public final InputStream openStream() throws java.io.IOException {
1040                return openConnection().getInputStream();
1041            }
1042
1043            /**
1044             * Gets the contents of this URL. This method is a shorthand for:
1045             * <blockquote><pre>
1046             *     openConnection().getContent()
1047             * </pre></blockquote>
1048             *
1049             * @return     the contents of this URL.
1050             * @exception  IOException  if an I/O exception occurs.
1051             * @see        java.net.URLConnection#getContent()
1052             */
1053            public final Object getContent() throws java.io.IOException {
1054                return openConnection().getContent();
1055            }
1056
1057            /**
1058             * Gets the contents of this URL. This method is a shorthand for:
1059             * <blockquote><pre>
1060             *     openConnection().getContent(Class[])
1061             * </pre></blockquote>
1062             *
1063             * @param classes an array of Java types
1064             * @return     the content object of this URL that is the first match of
1065             *               the types specified in the classes array.
1066             *               null if none of the requested types are supported.
1067             * @exception  IOException  if an I/O exception occurs.
1068             * @see        java.net.URLConnection#getContent(Class[])
1069             * @since 1.3
1070             */
1071            public final Object getContent(Class[] classes)
1072                    throws java.io.IOException {
1073                return openConnection().getContent(classes);
1074            }
1075
1076            /**
1077             * The URLStreamHandler factory.
1078             */
1079            static URLStreamHandlerFactory factory;
1080
1081            /**
1082             * Sets an application's <code>URLStreamHandlerFactory</code>.
1083             * This method can be called at most once in a given Java Virtual
1084             * Machine.
1085             *
1086             *<p> The <code>URLStreamHandlerFactory</code> instance is used to
1087             *construct a stream protocol handler from a protocol name.
1088             *
1089             * <p> If there is a security manager, this method first calls
1090             * the security manager's <code>checkSetFactory</code> method
1091             * to ensure the operation is allowed.
1092             * This could result in a SecurityException.
1093             *
1094             * @param      fac   the desired factory.
1095             * @exception  Error  if the application has already set a factory.
1096             * @exception  SecurityException  if a security manager exists and its
1097             *             <code>checkSetFactory</code> method doesn't allow
1098             *		   the operation.
1099             * @see        java.net.URL#URL(java.lang.String, java.lang.String,
1100             *             int, java.lang.String)
1101             * @see        java.net.URLStreamHandlerFactory
1102             * @see        SecurityManager#checkSetFactory
1103             */
1104            public static void setURLStreamHandlerFactory(
1105                    URLStreamHandlerFactory fac) {
1106                synchronized (streamHandlerLock) {
1107                    if (factory != null) {
1108                        throw new Error("factory already defined");
1109                    }
1110                    SecurityManager security = System.getSecurityManager();
1111                    if (security != null) {
1112                        security.checkSetFactory();
1113                    }
1114                    handlers.clear();
1115                    factory = fac;
1116                }
1117            }
1118
1119            /**
1120             * A table of protocol handlers.
1121             */
1122            static Hashtable handlers = new Hashtable();
1123            private static Object streamHandlerLock = new Object();
1124
1125            /**
1126             * Returns the Stream Handler.
1127             * @param protocol the protocol to use
1128             */
1129            static URLStreamHandler getURLStreamHandler(String protocol) {
1130
1131                URLStreamHandler handler = (URLStreamHandler) handlers
1132                        .get(protocol);
1133                if (handler == null) {
1134
1135                    boolean checkedWithFactory = false;
1136
1137                    // Use the factory (if any)
1138                    if (factory != null) {
1139                        handler = factory.createURLStreamHandler(protocol);
1140                        checkedWithFactory = true;
1141                    }
1142
1143                    // Try java protocol handler
1144                    if (handler == null) {
1145                        String packagePrefixList = null;
1146
1147                        packagePrefixList = (String) java.security.AccessController
1148                                .doPrivileged(new sun.security.action.GetPropertyAction(
1149                                        protocolPathProp, ""));
1150                        if (packagePrefixList != "") {
1151                            packagePrefixList += "|";
1152                        }
1153
1154                        // REMIND: decide whether to allow the "null" class prefix
1155                        // or not.
1156                        packagePrefixList += "sun.net.www.protocol";
1157
1158                        StringTokenizer packagePrefixIter = new StringTokenizer(
1159                                packagePrefixList, "|");
1160
1161                        while (handler == null
1162                                && packagePrefixIter.hasMoreTokens()) {
1163
1164                            String packagePrefix = packagePrefixIter
1165                                    .nextToken().trim();
1166                            try {
1167                                String clsName = packagePrefix + "." + protocol
1168                                        + ".Handler";
1169                                Class cls = null;
1170                                try {
1171                                    cls = Class.forName(clsName);
1172                                } catch (ClassNotFoundException e) {
1173                                    ClassLoader cl = ClassLoader
1174                                            .getSystemClassLoader();
1175                                    if (cl != null) {
1176                                        cls = cl.loadClass(clsName);
1177                                    }
1178                                }
1179                                if (cls != null) {
1180                                    handler = (URLStreamHandler) cls
1181                                            .newInstance();
1182                                }
1183                            } catch (Exception e) {
1184                                // any number of exceptions can get thrown here
1185                            }
1186                        }
1187                    }
1188
1189                    synchronized (streamHandlerLock) {
1190
1191                        URLStreamHandler handler2 = null;
1192
1193                        // Check again with hashtable just in case another
1194                        // thread created a handler since we last checked
1195                        handler2 = (URLStreamHandler) handlers.get(protocol);
1196
1197                        if (handler2 != null) {
1198                            return handler2;
1199                        }
1200
1201                        // Check with factory if another thread set a
1202                        // factory since our last check
1203                        if (!checkedWithFactory && factory != null) {
1204                            handler2 = factory.createURLStreamHandler(protocol);
1205                        }
1206
1207                        if (handler2 != null) {
1208                            // The handler from the factory must be given more
1209                            // importance. Discard the default handler that
1210                            // this thread created.
1211                            handler = handler2;
1212                        }
1213
1214                        // Insert this handler into the hashtable
1215                        if (handler != null) {
1216                            handlers.put(protocol, handler);
1217                        }
1218
1219                    }
1220                }
1221
1222                return handler;
1223
1224            }
1225
1226            /**
1227             * WriteObject is called to save the state of the URL to an
1228             * ObjectOutputStream. The handler is not saved since it is
1229             * specific to this system.
1230             *
1231             * @serialData the default write object value. When read back in,
1232             * the reader must ensure that calling getURLStreamHandler with
1233             * the protocol variable returns a valid URLStreamHandler and
1234             * throw an IOException if it does not.
1235             */
1236            private synchronized void writeObject(java.io.ObjectOutputStream s)
1237                    throws IOException {
1238                s.defaultWriteObject(); // write the fields
1239            }
1240
1241            /**
1242             * readObject is called to restore the state of the URL from the
1243             * stream.  It reads the components of the URL and finds the local
1244             * stream handler.
1245             */
1246            private synchronized void readObject(java.io.ObjectInputStream s)
1247                    throws IOException, ClassNotFoundException {
1248                s.defaultReadObject(); // read the fields
1249                if ((handler = getURLStreamHandler(protocol)) == null) {
1250                    throw new IOException("unknown protocol: " + protocol);
1251                }
1252
1253                // Construct authority part
1254                if (authority == null
1255                        && ((host != null && host.length() > 0) || port != -1)) {
1256                    if (host == null)
1257                        host = "";
1258                    authority = (port == -1) ? host : host + ":" + port;
1259
1260                    // Handle hosts with userInfo in them
1261                    int at = host.lastIndexOf('@');
1262                    if (at != -1) {
1263                        userInfo = host.substring(0, at);
1264                        host = host.substring(at + 1);
1265                    }
1266                } else if (authority != null) {
1267                    // Construct user info part
1268                    int ind = authority.indexOf('@');
1269                    if (ind != -1)
1270                        userInfo = authority.substring(0, ind);
1271                }
1272
1273                // Construct path and query part
1274                path = null;
1275                query = null;
1276                if (file != null) {
1277                    // Fix: only do this if hierarchical?
1278                    int q = file.lastIndexOf('?');
1279                    if (q != -1) {
1280                        query = file.substring(q + 1);
1281                        path = file.substring(0, q);
1282                    } else
1283                        path = file;
1284                }
1285            }
1286        }
1287
1288        class Parts {
1289            String path, query, ref;
1290
1291            Parts(String file) {
1292                int ind = file.indexOf('#');
1293                ref = ind < 0 ? null : file.substring(ind + 1);
1294                file = ind < 0 ? file : file.substring(0, ind);
1295                int q = file.lastIndexOf('?');
1296                if (q != -1) {
1297                    query = file.substring(q + 1);
1298                    path = file.substring(0, q);
1299                } else {
1300                    path = file;
1301                }
1302            }
1303
1304            String getPath() {
1305                return path;
1306            }
1307
1308            String getQuery() {
1309                return query;
1310            }
1311
1312            String getRef() {
1313                return ref;
1314            }
1315        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.