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