URLStreamHandler.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.net;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.URLUtil;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The abstract class {@code URLStreamHandler} is the base for all classes which
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can handle the communication with a URL object over a particular protocol
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type.
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class URLStreamHandler {
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Establishes a new connection to the resource specified by the URL {@code
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * u}. Since different protocols also have unique ways of connecting, it
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * must be overwritten by the subclass.
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param u
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL to the resource where a connection has to be opened.
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the opened URLConnection to the specified resource.
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an I/O error occurs during opening the connection.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected abstract URLConnection openConnection(URL u) throws IOException;
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Establishes a new connection to the resource specified by the URL {@code
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * u} using the given {@code proxy}. Since different protocols also have
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * unique ways of connecting, it must be overwritten by the subclass.
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param u
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL to the resource where a connection has to be opened.
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param proxy
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the proxy that is used to make the connection.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the opened URLConnection to the specified resource.
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an I/O error occurs during opening the connection.
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if any argument is {@code null} or the type of proxy is
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             wrong.
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws UnsupportedOperationException
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the protocol handler doesn't support this method.
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected URLConnection openConnection(URL u, Proxy proxy)
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws IOException {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new UnsupportedOperationException(Msg.getString("K034d")); //$NON-NLS-1$
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Parses the clear text URL in {@code str} into a URL object. URL strings
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * generally have the following format:
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * http://www.company.com/java/file1.java#reference
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * </p>
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The string is parsed in HTTP format. If the protocol has a different URL
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * format this method must be overridden.
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param u
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL to fill in the parsed clear text URL parts.
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param str
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL string that is to be parsed.
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param start
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the string position from where to begin parsing.
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param end
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the string position to stop parsing.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #toExternalForm
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see URL
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void parseURL(URL u, String str, int start, int end) {
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // For compatibility, refer to Harmony-2941
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (str.startsWith("//", start) //$NON-NLS-1$
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && str.indexOf('/', start + 2) == -1
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && end <= Integer.MIN_VALUE + 1) {
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new StringIndexOutOfBoundsException(end - 2 - start);
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (end < start) {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (this != u.strmHandler) {
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new SecurityException();
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String parseString = ""; //$NON-NLS-1$
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (start < end) {
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parseString = str.substring(start, end);
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        end -= start;
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int fileIdx = 0;
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Default is to use info from context
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String host = u.getHost();
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int port = u.getPort();
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String ref = u.getRef();
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String file = u.getPath();
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String query = u.getQuery();
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String authority = u.getAuthority();
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String userInfo = u.getUserInfo();
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int refIdx = parseString.indexOf('#', 0);
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parseString.startsWith("//")) { //$NON-NLS-1$
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int hostIdx = 2, portIdx = -1;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            port = -1;
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fileIdx = parseString.indexOf('/', hostIdx);
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int questionMarkIndex = parseString.indexOf('?', hostIdx);
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((questionMarkIndex != -1)
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    && ((fileIdx == -1) || (fileIdx > questionMarkIndex))) {
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fileIdx = questionMarkIndex;
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (fileIdx == -1) {
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fileIdx = end;
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Use default
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                file = ""; //$NON-NLS-1$
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int hostEnd = fileIdx;
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (refIdx != -1 && refIdx < fileIdx) {
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                hostEnd = refIdx;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int userIdx = parseString.lastIndexOf('@', hostEnd);
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            authority = parseString.substring(hostIdx, hostEnd);
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (userIdx > -1) {
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                userInfo = parseString.substring(hostIdx, userIdx);
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                hostIdx = userIdx + 1;
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            portIdx = parseString.indexOf(':', userIdx == -1 ? hostIdx
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    : userIdx);
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int endOfIPv6Addr = parseString.indexOf(']');
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if there are square braces, ie. IPv6 address, use last ':'
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (endOfIPv6Addr != -1) {
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                try {
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (parseString.length() > endOfIPv6Addr + 1) {
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        char c = parseString.charAt(endOfIPv6Addr + 1);
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        if (c == ':') {
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            portIdx = endOfIPv6Addr + 1;
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        } else {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            portIdx = -1;
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    } else {
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        portIdx = -1;
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } catch (Exception e) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Ignored
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (portIdx == -1 || portIdx > fileIdx) {
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                host = parseString.substring(hostIdx, hostEnd);
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                host = parseString.substring(hostIdx, portIdx);
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String portString = parseString.substring(portIdx + 1, hostEnd);
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (portString.length() == 0) {
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    port = -1;
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    port = Integer.parseInt(portString);
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (refIdx > -1) {
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ref = parseString.substring(refIdx + 1, end);
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int fileEnd = (refIdx == -1 ? end : refIdx);
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int queryIdx = parseString.lastIndexOf('?', fileEnd);
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean canonicalize = false;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (queryIdx > -1) {
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            query = parseString.substring(queryIdx + 1, fileEnd);
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (queryIdx == 0 && file != null) {
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (file.equals("")) { //$NON-NLS-1$
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    file = "/"; //$NON-NLS-1$
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (file.startsWith("/")) { //$NON-NLS-1$
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    canonicalize = true;
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int last = file.lastIndexOf('/') + 1;
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                file = file.substring(0, last);
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fileEnd = queryIdx;
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Don't inherit query unless only the ref is changed
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (refIdx != 0) {
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            query = null;
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fileIdx > -1) {
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (fileIdx < end && parseString.charAt(fileIdx) == '/') {
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                file = parseString.substring(fileIdx, fileEnd);
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if (fileEnd > fileIdx) {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (file == null) {
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    file = ""; //$NON-NLS-1$
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (file.equals("")) { //$NON-NLS-1$
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    file = "/"; //$NON-NLS-1$
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (file.startsWith("/")) { //$NON-NLS-1$
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    canonicalize = true;
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int last = file.lastIndexOf('/') + 1;
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (last == 0) {
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    file = parseString.substring(fileIdx, fileEnd);
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    file = file.substring(0, last)
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            + parseString.substring(fileIdx, fileEnd);
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (file == null) {
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            file = ""; //$NON-NLS-1$
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (host == null) {
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            host = ""; //$NON-NLS-1$
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (canonicalize) {
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // modify file if there's any relative referencing
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            file = URLUtil.canonicalizePath(file);
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        setURL(u, u.getProtocol(), host, port, authority, userInfo, file,
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                query, ref);
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the fields of the URL {@code u} to the values of the supplied
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * arguments.
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param u
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the non-null URL object to be set.
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param protocol
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the protocol.
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param host
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the host name.
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param port
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the port number.
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param file
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the file component.
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ref
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the reference.
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @deprecated use setURL(URL, String String, int, String, String, String,
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             String, String) instead.
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Deprecated
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void setURL(URL u, String protocol, String host, int port,
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String file, String ref) {
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this != u.strmHandler) {
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SecurityException();
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u.set(protocol, host, port, file, ref);
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the fields of the URL {@code u} to the values of the supplied
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * arguments.
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param u
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the non-null URL object to be set.
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param protocol
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the protocol.
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param host
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the host name.
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param port
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the port number.
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param authority
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the authority.
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param userInfo
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the user info.
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param file
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the file component.
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param query
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the query.
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ref
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the reference.
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void setURL(URL u, String protocol, String host, int port,
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String authority, String userInfo, String file, String query,
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String ref) {
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this != u.strmHandler) {
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SecurityException();
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u.set(protocol, host, port, authority, userInfo, file, query, ref);
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the clear text representation of a given URL using HTTP format.
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL object to be converted.
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the clear text representation of the specified URL.
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #parseURL
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see URL#toExternalForm()
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected String toExternalForm(URL url) {
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuffer answer = new StringBuffer(url.getProtocol().length()
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                + url.getFile().length() + 16);
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        answer.append(url.getProtocol());
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        answer.append(':');
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String authority = url.getAuthority();
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (authority != null && authority.length() > 0) {
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            answer.append("//"); //$NON-NLS-1$
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            answer.append(url.getAuthority());
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String file = url.getFile();
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String ref = url.getRef();
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // file is never null
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        answer.append(file);
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ref != null) {
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            answer.append('#');
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            answer.append(ref);
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return answer.toString();
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compares two URL objects whether they represent the same URL. Two URLs
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * are equal if they have the same file, host, port, protocol, query, and
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * reference components.
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url1
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the first URL to compare.
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url2
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the second URL to compare.
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the URLs are the same, {@code false} otherwise.
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #hashCode
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected boolean equals(URL url1, URL url2) {
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!sameFile(url1, url2)) {
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String s1 = url1.getRef(), s2 = url2.getRef();
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s1 != s2 && (s1 == null || !s1.equals(s2))) {
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        s1 = url1.getQuery();
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        s2 = url2.getQuery();
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return s1 == s2 || (s1 != null && s1.equals(s2));
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the default port of the protocol used by the handled URL. The
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * current implementation returns always {@code -1}.
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the appropriate default port number of the protocol.
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected int getDefaultPort() {
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the host address of the given URL.
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL object where to read the host address from.
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the host address of the specified URL.
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected InetAddress getHostAddress(URL url) {
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String host = url.getHost();
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (host == null || host.length() == 0) {
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return null;
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return InetAddress.getByName(host);
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (UnknownHostException e) {
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the hashcode value for the given URL object.
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the URL to determine the hashcode.
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the hashcode of the given URL.
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected int hashCode(URL url) {
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return toExternalForm(url).hashCode();
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compares two URL objects whether they refer to the same host.
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url1
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the first URL to be compared.
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url2
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the second URL to be compared.
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if both URLs refer to the same host, {@code false}
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected boolean hostsEqual(URL url1, URL url2) {
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String host1 = getHost(url1), host2 = getHost(url2);
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (host1 == host2 || (host1 != null && host1.equalsIgnoreCase(host2))) {
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Compare host address if the host name is not equal.
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        InetAddress address1 = getHostAddress(url1);
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        InetAddress address2 = getHostAddress(url2);
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (address1 != null && address1.equals(address2)) {
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compares two URL objects whether they refer to the same file. In the
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * comparison included are the URL components protocol, host, port and file.
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url1
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the first URL to be compared.
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param url2
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the second URL to be compared.
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if both URLs refer to the same file, {@code false}
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected boolean sameFile(URL url1, URL url2) {
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String s1 = url1.getProtocol();
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String s2 = url2.getProtocol();
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s1 != s2 && (s1 == null || !s1.equals(s2))) {
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        s1 = url1.getFile();
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        s2 = url2.getFile();
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s1 != s2 && (s1 == null || !s1.equals(s2))) {
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!hostsEqual(url1, url2)) {
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int p1 = url1.getPort();
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (p1 == -1) {
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            p1 = getDefaultPort();
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int p2 = url2.getPort();
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (p2 == -1) {
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            p2 = getDefaultPort();
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return p1 == p2;
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If the URL host is empty while protocal is file, the host is regarded as
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * localhost.
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static String getHost(URL url) {
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String host = url.getHost();
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ("file".equals(url.getProtocol()) //$NON-NLS-1$
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && "".equals(host)) { //$NON-NLS-1$
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            host = "localhost"; //$NON-NLS-1$
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return host;
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
483