All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java.net.URLStreamHandler Maven / Gradle / Ivy

Go to download

JVM AOT compiler currently generating JavaScript, C++, Haxe, with initial focus on Kotlin and games.

There is a newer version: 0.6.8
Show newest version
/*
 * Copyright 2016 Carlos Ballesteros Velasco
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package java.net;

import java.io.IOException;
import java.net.internal.UrlUtils;
import java.util.Objects;

public abstract class URLStreamHandler {
	/**
	 * Establishes a new connection to the resource specified by the URL {@code
	 * u}. Since different protocols also have unique ways of connecting, it
	 * must be overwritten by the subclass.
	 *
	 * @param u the URL to the resource where a connection has to be opened.
	 * @return the opened URLConnection to the specified resource.
	 * @throws IOException if an I/O error occurs during opening the connection.
	 */
	protected abstract URLConnection openConnection(URL u) throws IOException;

	/**
	 * Establishes a new connection to the resource specified by the URL {@code
	 * u} using the given {@code proxy}. Since different protocols also have
	 * unique ways of connecting, it must be overwritten by the subclass.
	 *
	 * @param u     the URL to the resource where a connection has to be opened.
	 * @param proxy the proxy that is used to make the connection.
	 * @return the opened URLConnection to the specified resource.
	 * @throws IOException                   if an I/O error occurs during opening the connection.
	 * @throws IllegalArgumentException      if any argument is {@code null} or the type of proxy is
	 *                                       wrong.
	 * @throws UnsupportedOperationException if the protocol handler doesn't support this method.
	 */
	protected URLConnection openConnection(URL u, Proxy proxy) throws IOException {
		throw new UnsupportedOperationException();
	}

	/**
	 * Parses the clear text URL in {@code str} into a URL object. URL strings
	 * generally have the following format:
	 * 

* http://www.company.com/java/file1.java#reference *

* The string is parsed in HTTP format. If the protocol has a different URL * format this method must be overridden. * * @param url the URL to fill in the parsed clear text URL parts. * @param spec the URL string that is to be parsed. * @param start the string position from where to begin parsing. * @param end the string position to stop parsing. * @see #toExternalForm * @see URL */ protected void parseURL(URL url, String spec, int start, int end) { if (this != url.streamHandler) { throw new SecurityException("Only a URL's stream handler is permitted to mutate it"); } if (end < start) { throw new StringIndexOutOfBoundsException(); } int fileStart; String authority; String userInfo; String host; int port = -1; String path; String query; String ref; if (spec.regionMatches(start, "//", 0, 2)) { // Parse the authority from the spec. int authorityStart = start + 2; fileStart = UrlUtils.findFirstOf(spec, "/?#", authorityStart, end); authority = spec.substring(authorityStart, fileStart); int userInfoEnd = UrlUtils.findFirstOf(spec, "@", authorityStart, fileStart); int hostStart; if (userInfoEnd != fileStart) { userInfo = spec.substring(authorityStart, userInfoEnd); hostStart = userInfoEnd + 1; } else { userInfo = null; hostStart = authorityStart; } /* * Extract the host and port. The host may be an IPv6 address with * colons like "[::1]", in which case we look for the port delimiter * colon after the ']' character. */ int colonSearchFrom = hostStart; int ipv6End = UrlUtils.findFirstOf(spec, "]", hostStart, fileStart); if (ipv6End != fileStart) { if (UrlUtils.findFirstOf(spec, ":", hostStart, ipv6End) == ipv6End) { throw new IllegalArgumentException("Expected an IPv6 address: " + spec.substring(hostStart, ipv6End + 1)); } colonSearchFrom = ipv6End; } int hostEnd = UrlUtils.findFirstOf(spec, ":", colonSearchFrom, fileStart); host = spec.substring(hostStart, hostEnd); int portStart = hostEnd + 1; if (portStart < fileStart) { port = Integer.parseInt(spec.substring(portStart, fileStart)); if (port < 0) { throw new IllegalArgumentException("port < 0: " + port); } } path = null; query = null; ref = null; } else { // Get the authority from the context URL. fileStart = start; authority = url.getAuthority(); userInfo = url.getUserInfo(); host = url.getHost(); if (host == null) { host = ""; } port = url.getPort(); path = url.getPath(); query = url.getQuery(); ref = url.getRef(); } /* * Extract the path, query and fragment. Each part has its own leading * delimiter character. The query can contain slashes and the fragment * can contain slashes and question marks. * / path ? query # fragment */ int pos = fileStart; while (pos < end) { int nextPos; switch (spec.charAt(pos)) { case '#': nextPos = end; ref = spec.substring(pos + 1, nextPos); break; case '?': nextPos = UrlUtils.findFirstOf(spec, "#", pos, end); query = spec.substring(pos + 1, nextPos); ref = null; break; default: nextPos = UrlUtils.findFirstOf(spec, "?#", pos, end); path = relativePath(path, spec.substring(pos, nextPos)); query = null; ref = null; break; } pos = nextPos; } if (path == null) { path = ""; } path = UrlUtils.authoritySafePath(authority, path); setURL(url, url.getProtocol(), host, port, authority, userInfo, path, query, ref); } /** * Returns a new path by resolving {@code path} relative to {@code base}. */ private static String relativePath(String base, String path) { if (path.startsWith("/")) { return UrlUtils.canonicalizePath(path, true); } else if (base != null) { String combined = base.substring(0, base.lastIndexOf('/') + 1) + path; return UrlUtils.canonicalizePath(combined, true); } else { return path; } } /** * Sets the fields of the URL {@code u} to the values of the supplied * arguments. * * @param u the non-null URL object to be set. * @param protocol the protocol. * @param host the host name. * @param port the port number. * @param file the file component. * @param ref the reference. * @deprecated Use setURL(URL, String String, int, String, String, String, * String, String) instead. */ @Deprecated protected void setURL(URL u, String protocol, String host, int port, String file, String ref) { if (this != u.streamHandler) { throw new SecurityException(); } u.set(protocol, host, port, file, ref); } /** * Sets the fields of the URL {@code u} to the values of the supplied * arguments. */ protected void setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref) { if (this != u.streamHandler) { throw new SecurityException(); } u.set(protocol, host, port, authority, userInfo, path, query, ref); } /** * Returns the clear text representation of a given URL using HTTP format. * * @param url the URL object to be converted. * @return the clear text representation of the specified URL. * @see #parseURL * @see URL#toExternalForm() */ protected String toExternalForm(URL url) { return toExternalForm(url, false); } String toExternalForm(URL url, boolean escapeIllegalCharacters) { StringBuilder result = new StringBuilder(); result.append(url.getProtocol()); result.append(':'); String authority = url.getAuthority(); if (authority != null) { result.append("//"); if (escapeIllegalCharacters) { URI.AUTHORITY_ENCODER.appendPartiallyEncoded(result, authority); } else { result.append(authority); } } String fileAndQuery = url.getFile(); if (fileAndQuery != null) { if (escapeIllegalCharacters) { URI.FILE_AND_QUERY_ENCODER.appendPartiallyEncoded(result, fileAndQuery); } else { result.append(fileAndQuery); } } String ref = url.getRef(); if (ref != null) { result.append('#'); if (escapeIllegalCharacters) { URI.ALL_LEGAL_ENCODER.appendPartiallyEncoded(result, ref); } else { result.append(ref); } } return result.toString(); } /** * Returns true if {@code a} and {@code b} have the same protocol, host, * port, file, and reference. */ protected boolean equals(URL a, URL b) { return sameFile(a, b) && Objects.equals(a.getRef(), b.getRef()) && Objects.equals(a.getQuery(), b.getQuery()); } /** * Returns the default port of the protocol used by the handled URL. The * default implementation always returns {@code -1}. */ protected int getDefaultPort() { return -1; } /** * Returns the host address of {@code url}. */ protected InetAddress getHostAddress(URL url) { try { String host = url.getHost(); if (host == null || host.length() == 0) { return null; } return InetAddress.getByName(host); } catch (UnknownHostException e) { return null; } } /** * Returns the hash code of {@code url}. */ protected int hashCode(URL url) { return toExternalForm(url).hashCode(); } /** * Returns true if the hosts of {@code a} and {@code b} are equal. */ protected boolean hostsEqual(URL a, URL b) { // URLs with the same case-insensitive host name have equal hosts String aHost = a.getHost(); String bHost = b.getHost(); return Objects.equals(aHost, bHost) || aHost != null && aHost.equalsIgnoreCase(bHost); } /** * Returns true if {@code a} and {@code b} have the same protocol, host, * port and file. */ protected boolean sameFile(URL a, URL b) { return Objects.equals(a.getProtocol(), b.getProtocol()) && hostsEqual(a, b) && a.getEffectivePort() == b.getEffectivePort() && Objects.equals(a.getFile(), b.getFile()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy