URL.java revision adc854b798c1cfe3bfd4c27d68d5cee38ca617da
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Hashtable;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.StringTokenizer;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Util;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A URL instance specifies the location of a resource on the internet as
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified by RFC 1738. Such a resource can be a simple file or a service
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which generates the output dynamically. A URL is divided in its parts
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * protocol, host name, port, path, file, user-info, query, reference and
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * authority. However, not each of this parts has to be defined.
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since Android 1.0
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class URL implements java.io.Serializable {
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -7627629688361524110L;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final NetPermission specifyStreamHandlerPermission = new NetPermission(
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "specifyStreamHandler"); //$NON-NLS-1$
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int hashCode;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's filename.
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial the file of this URL
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String file;
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's protocol identifier.
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial the protocol of this URL (http, file)
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String protocol = null;
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's host name.
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial the host of this URL
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String host;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's port number.
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial the port of this URL
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int port = -1;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's authority.
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial the authority of this URL
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String authority = null;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's userInfo.
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String userInfo = null;
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's path.
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String path = null;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's query.
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String query = null;
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The receiver's reference.
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @serial the reference of this URL
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String ref = null;
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Cache for storing protocol handler
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static Hashtable<String, URLStreamHandler> streamHandlers = new Hashtable<String, URLStreamHandler>();
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The URL Stream (protocol) Handler
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    transient URLStreamHandler strmHandler;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The factory responsible for producing URL Stream (protocol) Handler
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static URLStreamHandlerFactory streamHandlerFactory;
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the {@code URLStreamHandlerFactory} which creates protocol specific
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream handlers. This method can be invoked only once during an
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * application's lifetime. If the {@code URLStreamHandlerFactory} is already
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * set an {@link Error} will be thrown.
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A security check is performed to verify whether the current policy allows
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to set the stream handler factory.
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </p>
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streamFactory
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the factory to be used for creating stream protocol handlers.
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized void setURLStreamHandlerFactory(
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            URLStreamHandlerFactory streamFactory) {
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (streamHandlerFactory != null) {
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new Error(Msg.getString("K004b")); //$NON-NLS-1$
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager sm = System.getSecurityManager();
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (sm != null) {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            sm.checkSetFactory();
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        streamHandlers.clear();
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        streamHandlerFactory = streamFactory;
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new URL instance by parsing the string {@code spec}.
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param spec
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL string representation which has to be parsed.
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws MalformedURLException
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given string {@code spec} could not be parsed as a
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             URL.
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URL(String spec) throws MalformedURLException {
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this((URL) null, spec, (URLStreamHandler) null);
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new URL to the specified resource {@code spec}. This URL is
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * relative to the given {@code context}. If the protocol of the parsed URL
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * does not match with the protocol of the context URL, then the newly
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * created URL is absolute and bases only on the given URL represented by
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code spec}. Otherwise the protocol is defined by the context URL.
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param context
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL which is used as the context.
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param spec
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL string representation which has to be parsed.
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws MalformedURLException
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given string {@code spec} could not be parsed as a URL
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             or an invalid protocol has been found.
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URL(URL context, String spec) throws MalformedURLException {
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(context, spec, (URLStreamHandler) null);
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new URL to the specified resource {@code spec}. This URL is
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * relative to the given {@code context}. The {@code handler} will be used
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to parse the URL string representation. If this argument is {@code null}
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the default {@code URLStreamHandler} will be used. If the protocol of the
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parsed URL does not match with the protocol of the context URL, then the
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * newly created URL is absolute and bases only on the given URL represented
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by {@code spec}. Otherwise the protocol is defined by the context URL.
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param context
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL which is used as the context.
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param spec
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL string representation which has to be parsed.
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handler
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific stream handler to be used by this URL.
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws MalformedURLException
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given string {@code spec} could not be parsed as a URL
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             or an invalid protocol has been found.
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URL(URL context, String spec, URLStreamHandler handler)
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws MalformedURLException {
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (handler != null) {
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            SecurityManager sm = System.getSecurityManager();
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (sm != null) {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                sm.checkPermission(specifyStreamHandlerPermission);
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            strmHandler = handler;
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (spec == null) {
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new MalformedURLException();
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        spec = spec.trim();
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The spec includes a protocol if it includes a colon character
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // before the first occurrence of a slash character. Note that,
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // "protocol" is the field which holds this URLs protocol.
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int index;
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            index = spec.indexOf(':');
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (NullPointerException e) {
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new MalformedURLException(e.toString());
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int startIPv6Addr = spec.indexOf('[');
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (index >= 0) {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((startIPv6Addr == -1) || (index < startIPv6Addr)) {
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                protocol = spec.substring(0, index);
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // According to RFC 2396 scheme part should match
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // the following expression:
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // alpha *( alpha | digit | "+" | "-" | "." )
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // BEGIN android-changed
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // copied from newer version of harmony
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char c = protocol.charAt(0);
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                boolean valid = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i = 1; valid && (i < protocol.length()); i++) {
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    c = protocol.charAt(i);
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    valid = ('a' <= c && c <= 'z') ||
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ('A' <= c && c <= 'Z') ||
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ('0' <= c && c <= '9') ||
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            (c == '+') ||
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            (c == '-') ||
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            (c == '.');
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!valid) {
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    protocol = null;
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    index = -1;
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Ignore case in protocol names.
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // Scheme is defined by ASCII characters.
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    protocol = Util.toASCIILowerCase(protocol);
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // END android-changed
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (protocol != null) {
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If the context was specified, and it had the same protocol
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // as the spec, then fill in the receiver's slots from the values
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // in the context but still allow them to be over-ridden later
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // by the values in the spec.
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (context != null && protocol.equals(context.getProtocol())) {
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String cPath = context.getPath();
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (cPath != null && cPath.startsWith("/")) { //$NON-NLS-1$
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    set(protocol, context.getHost(), context.getPort(), context
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getAuthority(), context.getUserInfo(), cPath,
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            context.getQuery(), null);
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (strmHandler == null) {
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    strmHandler = context.strmHandler;
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If the spec did not include a protocol, then the context
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // *must* be specified. Fill in the receiver's slots from the
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // values in the context, but still allow them to be over-ridden
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // by the values in the ("relative") spec.
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (context == null) {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new MalformedURLException(
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        org.apache.harmony.luni.util.Msg.getString(
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                "K00d8", spec)); //$NON-NLS-1$
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            set(context.getProtocol(), context.getHost(), context.getPort(),
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    context.getAuthority(), context.getUserInfo(), context
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getPath(), context.getQuery(), null);
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (strmHandler == null) {
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                strmHandler = context.strmHandler;
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If the stream handler has not been determined, set it
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // to the default for the specified protocol.
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (strmHandler == null) {
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setupStreamHandler();
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (strmHandler == null) {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new MalformedURLException(
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        org.apache.harmony.luni.util.Msg.getString(
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                "K00b3", protocol)); //$NON-NLS-1$
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let the handler parse the URL. If the handler throws
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // any exception, throw MalformedURLException instead.
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Note: We want "index" to be the index of the start of the scheme
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // specific part of the URL. At this point, it will be either
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // -1 or the index of the colon after the protocol, so we
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // increment it to point at either character 0 or the character
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // after the colon.
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            strmHandler.parseURL(this, spec, ++index, spec.length());
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (Exception e) {
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new MalformedURLException(e.toString());
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (port < -1) {
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new MalformedURLException(org.apache.harmony.luni.util.Msg
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .getString("K0325", port)); //$NON-NLS-1$
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new URL instance using the given arguments. The URL uses the
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * default port for the specified protocol.
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param protocol
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the protocol of the new URL.
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the host name or IP address of the new URL.
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the resource.
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws MalformedURLException
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the combination of all arguments do not represent a valid
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             URL or the protocol is invalid.
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URL(String protocol, String host, String file)
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws MalformedURLException {
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(protocol, host, -1, file, (URLStreamHandler) null);
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new URL instance using the given arguments. The URL uses the
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified port instead of the default port for the given protocol.
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param protocol
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the protocol of the new URL.
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the host name or IP address of the new URL.
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific port number of the URL. {@code -1} represents the
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            default port of the protocol.
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the resource.
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws MalformedURLException
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the combination of all arguments do not represent a valid
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             URL or the protocol is invalid.
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URL(String protocol, String host, int port, String file)
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws MalformedURLException {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(protocol, host, port, file, (URLStreamHandler) null);
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new URL instance using the given arguments. The URL uses the
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified port instead of the default port for the given protocol.
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param protocol
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the protocol of the new URL.
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the host name or IP address of the new URL.
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific port number of the URL. {@code -1} represents the
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            default port of the protocol.
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the resource.
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handler
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the stream handler to be used by this URL.
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws MalformedURLException
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the combination of all arguments do not represent a valid
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             URL or the protocol is invalid.
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URL(String protocol, String host, int port, String file,
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            URLStreamHandler handler) throws MalformedURLException {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (port < -1) {
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new MalformedURLException(org.apache.harmony.luni.util.Msg
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .getString("K0325", port)); //$NON-NLS-1$
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (host != null && host.indexOf(":") != -1 && host.charAt(0) != '[') { //$NON-NLS-1$
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (protocol != null) {
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.protocol = protocol;
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException(Msg.getString("K00b3", protocol)); //$NON-NLS-1$
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.host = host;
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.port = port;
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Set the fields from the arguments. Handle the case where the
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // passed in "file" includes both a file and a reference part.
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int index = -1;
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        index = file.indexOf("#", file.lastIndexOf("/")); //$NON-NLS-1$ //$NON-NLS-2$
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (index >= 0) {
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.file = file.substring(0, index);
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ref = file.substring(index + 1);
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.file = file;
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fixURL(false);
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Set the stream handler for the URL either to the handler
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // argument if it was specified, or to the default for the
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // receiver's protocol if the handler was null.
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (handler == null) {
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setupStreamHandler();
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (strmHandler == null) {
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new MalformedURLException(
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        org.apache.harmony.luni.util.Msg.getString(
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                "K00b3", protocol)); //$NON-NLS-1$
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            SecurityManager sm = System.getSecurityManager();
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (sm != null) {
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                sm.checkPermission(specifyStreamHandlerPermission);
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            strmHandler = handler;
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void fixURL(boolean fixHost) {
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int index;
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (host != null && host.length() > 0) {
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            authority = host;
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (port != -1) {
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                authority = authority + ":" + port; //$NON-NLS-1$
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (fixHost) {
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (host != null && (index = host.lastIndexOf('@')) > -1) {
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                userInfo = host.substring(0, index);
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = host.substring(index + 1);
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                userInfo = null;
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (file != null && (index = file.indexOf('?')) > -1) {
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            query = file.substring(index + 1);
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            path = file.substring(0, index);
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            query = null;
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            path = file;
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the properties of this URL using the provided arguments. Only a
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code URLStreamHandler} can use this method to set fields of the
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * existing URL instance. A URL is generally constant.
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param protocol
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the protocol to be set.
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the host name to be set.
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port number to be set.
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the file to be set.
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ref
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the reference to be set.
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void set(String protocol, String host, int port, String file,
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String ref) {
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.protocol == null) {
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.protocol = protocol;
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.host = host;
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.file = file;
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.port = port;
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.ref = ref;
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        hashCode = 0;
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fixURL(true);
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares this URL instance with the given argument {@code o} and
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * determines if both are equal. Two URL instances are equal if all single
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parts are identical in their meaning. Compares the argument to the
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver, and returns true if they represent the same URL. Two URLs are
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * equal if they have the same file, host, port, protocol, and reference
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * components.
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param o
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL this instance has to be compared with.
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if both instances represents the same URL, {@code
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         false} otherwise.
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #hashCode
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object o) {
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o == null) {
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this == o) {
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.getClass() != o.getClass()) {
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return strmHandler.equals(this, (URL) o);
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this URL refers to the same resource as the given
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * argument {@code otherURL}. All URL components except the reference field
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * are compared.
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param otherURL
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL to compare against.
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if both instances refer to the same resource,
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean sameFile(URL otherURL) {
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return strmHandler.sameFile(this, otherURL);
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the hashcode value of this URL instance.
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the appropriate hashcode value.
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hashCode == 0) {
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hashCode = strmHandler.hashCode(this);
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return hashCode;
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the receiver's stream handler to one which is appropriate for its
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * protocol. Throws a MalformedURLException if no reasonable handler is
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * available.
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note that this will overwrite any existing stream handler with the new
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * one. Senders must check if the strmHandler is null before calling the
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method if they do not want this behavior (a speed optimization).
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </p>
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void setupStreamHandler() {
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check for a cached (previously looked up) handler for
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // the requested protocol.
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        strmHandler = streamHandlers.get(protocol);
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (strmHandler != null) {
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If there is a stream handler factory, then attempt to
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // use it to create the handler.
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (streamHandlerFactory != null) {
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            strmHandler = streamHandlerFactory.createURLStreamHandler(protocol);
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (strmHandler != null) {
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                streamHandlers.put(protocol, strmHandler);
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Check if there is a list of packages which can provide handlers.
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If so, then walk this list looking for an applicable one.
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String packageList = AccessController
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .doPrivileged(new PriviAction<String>(
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        "java.protocol.handler.pkgs")); //$NON-NLS-1$
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (packageList != null) {
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            StringTokenizer st = new StringTokenizer(packageList, "|"); //$NON-NLS-1$
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (st.hasMoreTokens()) {
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String className = st.nextToken() + "." + protocol + ".Handler"; //$NON-NLS-1$ //$NON-NLS-2$
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    strmHandler = (URLStreamHandler) Class.forName(className,
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            true, ClassLoader.getSystemClassLoader())
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .newInstance();
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (strmHandler != null) {
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        streamHandlers.put(protocol, strmHandler);
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return;
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (IllegalAccessException e) {
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (InstantiationException e) {
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (ClassNotFoundException e) {
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // No one else has provided a handler, so try our internal one.
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String className = "org.apache.harmony.luni.internal.net.www.protocol." + protocol //$NON-NLS-1$
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                + ".Handler"; //$NON-NLS-1$
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            strmHandler = (URLStreamHandler) Class.forName(className)
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .newInstance();
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IllegalAccessException e) {
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (InstantiationException e) {
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (ClassNotFoundException e) {
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (strmHandler != null) {
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            streamHandlers.put(protocol, strmHandler);
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the content of the resource which is referred by this URL. By
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * default one of the following object types will be returned:
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>Image for pictures</li>
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>AudioClip for audio sequences</li>
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>{@link InputStream} for all other data</li>
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </p>
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the content of the referred resource.
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs obtaining the content.
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Object getContent() throws IOException {
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return openConnection().getContent();
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the content of the resource which is referred by this URL. The
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * argument {@code types} is an array of allowed or expected object types.
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null} will be returned if the obtained object type does not match
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * with one from this list. Otherwise the first type that matches will be
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * used.
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param types
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the list of allowed or expected object types.
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the object representing the resource referred by this URL,
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if the content does not match to a specified content
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         type.
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs obtaining the content.
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Param not generic in spec
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Object getContent(Class[] types) throws IOException {
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return openConnection().getContent(types);
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Opens an InputStream to read the resource referred by this URL.
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the stream which allows to read the resource.
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while opening the InputStream.
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final InputStream openStream() throws java.io.IOException {
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return openConnection().getInputStream();
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Opens a connection to the remote resource specified by this URL. This
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connection allows bidirectional data transfer.
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the connection to this URL.
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while opening the connection.
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URLConnection openConnection() throws IOException {
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return strmHandler.openConnection(this);
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts this URL instance into an equivalent URI object.
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the URI instance that represents this URL.
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws URISyntaxException
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this URL cannot be converted into a URI.
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URI toURI() throws URISyntaxException {
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new URI(toExternalForm());
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Opens a connection to the remote resource specified by this URL. The
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connection will be established through the given proxy and allows
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bidirectional data transfer.
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param proxy
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the proxy through which the connection will be established.
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the appropriate URLconnection instance representing the
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         connection to this URL.
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an I/O error occurs while opening the connection.
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager is installed and it denies to connect
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             to the proxy.
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the argument proxy is {@code null} or is an invalid type.
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnsupportedOperationException
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the protocol handler does not support opening connections
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             through proxies.
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public URLConnection openConnection(Proxy proxy) throws IOException {
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null == proxy) {
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K034c")); //$NON-NLS-1$
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return strmHandler.openConnection(this, proxy);
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable representation of
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this URL. The returned string is the same as the result of the method
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code toExternalForm()}.
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string representation of this URL.
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return toExternalForm();
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable representation of
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this URL.
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string representation of this URL.
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toExternalForm() {
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (strmHandler == null) {
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return "unknown protocol(" + protocol + ")://" + host + file; //$NON-NLS-1$ //$NON-NLS-2$
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return strmHandler.toExternalForm(this);
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method is called to restore the state of a URL object that has been
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * serialized. The stream handler is determined from the URL's protocol.
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param stream
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the stream to read from.
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an IO Exception occurs while reading the stream or the
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             handler can not be found.
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObject(java.io.ObjectInputStream stream)
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws java.io.IOException {
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            stream.defaultReadObject();
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (host != null && authority == null) {
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                fixURL(true);
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (authority != null) {
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int index;
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((index = authority.lastIndexOf('@')) > -1) {
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    userInfo = authority.substring(0, index);
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (file != null && (index = file.indexOf('?')) > -1) {
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    query = file.substring(index + 1);
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    path = file.substring(0, index);
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    path = file;
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setupStreamHandler();
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (strmHandler == null) {
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Msg.getString("K00b3", protocol)); //$NON-NLS-1$
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (ClassNotFoundException e) {
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(e.toString());
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method is called to write any non-transient, non-static variables
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * into the output stream.
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note that, we really only need the readObject method but the spec that
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * says readObject will be ignored if no writeObject is present.
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </p>
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param s
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the stream to write on.
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an IO Exception occurs during the write.
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(ObjectOutputStream s) throws IOException {
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        s.defaultWriteObject();
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the file part of this URL.
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the file name this URL refers to or an empty string if the file
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         part is not set.
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getFile() {
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return file;
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the host part of this URL.
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the host name or IP address of this URL.
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getHost() {
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return host;
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the port number of this URL or {@code -1} if the port is not set.
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the port number of this URL.
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getPort() {
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return port;
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the protocol of this URL.
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the protocol type of this URL.
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getProtocol() {
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return protocol;
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the reference part of this URL.
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the reference part of this URL.
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getRef() {
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ref;
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the query part of this URL.
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the query part of this URL.
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getQuery() {
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return query;
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the path part of this URL.
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the path part of this URL.
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getPath() {
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return path;
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the user-info part of this URL.
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the user-info part of this URL.
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getUserInfo() {
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return userInfo;
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the authority part of this URL.
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the authority part of this URL.
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getAuthority() {
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return authority;
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the properties of this URL using the provided arguments. Only a
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code URLStreamHandler} can use this method to set fields of the
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * existing URL instance. A URL is generally constant.
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param protocol
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the protocol to be set.
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param host
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the host name to be set.
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port number to be set.
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param authority
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the authority to be set.
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param userInfo
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the user-info to be set.
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param path
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the path to be set.
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param query
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the query to be set.
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ref
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the reference to be set.
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void set(String protocol, String host, int port,
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String authority, String userInfo, String path, String query,
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String ref) {
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String file = path;
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (query != null && !query.equals("")) { //$NON-NLS-1$
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (file != null) {
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                file = file + "?" + query; //$NON-NLS-1$
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                file = "?" + query; //$NON-NLS-1$
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        set(protocol, host, port, file, ref);
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.authority = authority;
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.userInfo = userInfo;
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.path = path;
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.query = query;
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-removed
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // copied from newer version of harmony
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // URLStreamHandler getStreamHandler() {
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     return strmHandler;
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // }
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-removed
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the default port number of the protocol used by this URL. If no
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * default port is defined by the protocol or the {@code URLStreamHandler},
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code -1} will be returned.
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the default port number according to the protocol of this URL.
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see URLStreamHandler#getDefaultPort
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @since Android 1.0
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getDefaultPort() {
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return strmHandler.getDefaultPort();
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
964