diff options
Diffstat (limited to 'libjava/java/net/URLStreamHandler.java')
-rw-r--r-- | libjava/java/net/URLStreamHandler.java | 218 |
1 files changed, 157 insertions, 61 deletions
diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java index a30f157..128a0d2 100644 --- a/libjava/java/net/URLStreamHandler.java +++ b/libjava/java/net/URLStreamHandler.java @@ -1,28 +1,78 @@ -// URLStreamHandler.java - Superclass of all stream protocol handlers. +/* URLStreamHandler.java -- Abstract superclass for all protocol handlers + Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ -/* Copyright (C) 1999, 2002 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.net; import java.io.IOException; -/** - * @author Warren Levy <warrenl@cygnus.com> - * @date March 4, 1999. - */ - -/** +/* * Written using on-line Java Platform 1.2 API Specification, as well * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). * Status: Believed complete and correct. */ +/** + * This class is the superclass of all URL protocol handlers. The URL + * class loads the appropriate protocol handler to establish a connection + * to a (possibly) remote service (eg, "http", "ftp") and to do protocol + * specific parsing of URL's. Refer to the URL class documentation for + * details on how that class locates and loads protocol handlers. + * <p> + * A protocol handler implementation should override the openConnection() + * method, and optionally override the parseURL() and toExternalForm() + * methods if necessary. (The default implementations will parse/write all + * URL's in the same form as http URL's). A protocol specific subclass + * of URLConnection will most likely need to be created as well. + * <p> + * Note that the instance methods in this class are called as if they + * were static methods. That is, a URL object to act on is passed with + * every call rather than the caller assuming the URL is stored in an + * instance variable of the "this" object. + * <p> + * The methods in this class are protected and accessible only to subclasses. + * URLStreamConnection objects are intended for use by the URL class only, + * not by other classes (unless those classes are implementing protocols). + * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Warren Levy (warrenl@cygnus.com) + * + * @see URL + */ public abstract class URLStreamHandler { /** @@ -33,8 +83,15 @@ public abstract class URLStreamHandler } /** - * Opens a connection to the object referenced by the URL argument. - * This method should be overridden by a subclass. + * Returns a URLConnection for the passed in URL. Note that this should + * not actually create the connection to the (possibly) remote host, but + * rather simply return a URLConnection object. The connect() method of + * URL connection is used to establish the actual connection, possibly + * after the caller sets up various connection options. + * + * @param url The URL to get a connection object for + * + * @return A URLConnection object for the given URL * * @exception IOException If an error occurs */ @@ -42,28 +99,33 @@ public abstract class URLStreamHandler throws IOException; /** - * Pasrses the given URL + * This method parses the string passed in as a URL and set's the + * instance data fields in the URL object passed in to the various values + * parsed out of the string. The start parameter is the position to start + * scanning the string. This is usually the position after the ":" which + * terminates the protocol name. The end parameter is the position to + * stop scanning. This will be either the end of the String, or the + * position of the "#" character, which separates the "file" portion of + * the URL from the "anchor" portion. + * <p> + * This method assumes URL's are formatted like http protocol URL's, so + * subclasses that implement protocols with URL's the follow a different + * syntax should override this method. The lone exception is that if + * the protocol name set in the URL is "file", this method will accept + * a an empty hostname (i.e., "file:///"), which is legal for that protocol * - * @param u The URL to parse - * @param spec The specification to use - * @param start The character index at which to begin parsing. This is just - * past the ':' (if there is one) that specifies the determination of the - * protocol name - * @param limit The character position to stop parsing at. This is the end - * of the string or the position of the "#" character, if present. All - * information after the sharp sign indicates an anchor + * @param url The URL object in which to store the results + * @param spec The String-ized URL to parse + * @param start The position in the string to start scanning from + * @param end The position in the string to stop scanning */ - protected void parseURL(URL u, String spec, int start, int limit) + protected void parseURL(URL url, String spec, int start, int end) { - String host = u.getHost(); - int port = u.getPort(); - String file = u.getFile(); + String host = url.getHost(); + int port = url.getPort(); + String file = url.getFile(); + String ref = url.getRef(); - /* TBD: The JDK 1.2 doc specifically says that limit is the position - * to stop parsing at and that it will be either the end of the string - * or the position of '#'; thus the doc infers that this method does - * not set the ref. - */ if (spec.regionMatches (start, "//", 0, 2)) { int hostEnd; @@ -74,7 +136,7 @@ public abstract class URLStreamHandler if (slash >= 0) hostEnd = slash; else - hostEnd = limit; + hostEnd = end; host = spec.substring (start, hostEnd); @@ -103,28 +165,46 @@ public abstract class URLStreamHandler else if (host == null) host = ""; - if (start < limit && spec.charAt(start) == '/') - { - // This is an absolute path name; ignore any file context. - file = spec.substring(start, limit); - } - else if (file == null || file.length() <= 0) + if (file == null || file.length() == 0 + || (start < end && spec.charAt(start) == '/')) { // No file context available; just spec for file. - file = spec.substring(start, limit); - } - else if (start < limit) + // Or this is an absolute path name; ignore any file context. + file = spec.substring(start, end); + ref = null; + } + else if (start < end) { // Context is available, but only override it if there is a new file. file = file.substring(0, file.lastIndexOf('/')) - + '/' + spec.substring(start, limit); + + '/' + spec.substring(start, end); + ref = null; } - u.set(u.getProtocol(), host, port, file, u.getRef()); + if (ref == null) + { + // Normally there should be no '#' in the file part, + // but we are nice. + int hash = file.indexOf('#'); + if (hash != -1) + { + ref = file.substring(hash + 1, file.length()); + file = file.substring(0, hash); + } + } + + // XXX - Classpath used to call PlatformHelper.toCanonicalForm() on + // the file part. It seems like overhead, but supposedly there is some + // benefit in windows based systems (it also lowercased the string). + + setURL(url, url.getProtocol(), host, port, file, ref); } private static String canonicalizeFilename(String file) { + // XXX - GNU Classpath has an implementation that might be more appropriate + // for Windows based systems (gnu.java.io.PlatformHelper.toCanonicalForm) + int index; // Replace "/./" with "/". This probably isn't very efficient in @@ -179,7 +259,8 @@ public abstract class URLStreamHandler } /** - * Sets the fields of the URL argument to the indicated values + * This methods sets the instance variables representing the various fields + * of the URL to the values passed in. * * @param u The URL to modify * @param protocol The protocol to set @@ -317,38 +398,53 @@ public abstract class URLStreamHandler } /** - * Converts an URL of a specific protocol to a string + * This method converts a URL object into a String. This method creates + * Strings in the mold of http URL's, so protocol handlers which use URL's + * that have a different syntax should override this method * - * @param u The URL to convert + * @param url The URL object to convert */ protected String toExternalForm(URL u) { - String resStr, host, file, ref; + String protocol, host, file, ref; int port; - resStr = u.getProtocol() + ":"; + protocol = u.getProtocol(); + + // JDK 1.2 online doc infers that host could be null because it + // explicitly states that file cannot be null, but is silent on host. host = u.getHost(); + if (host == null) + host = ""; + port = u.getPort(); file = u.getFile(); ref = u.getRef(); - // JDK 1.2 online doc infers that host could be null because it - // explicitly states that file cannot be null, but is silent on host. - // + // Guess a reasonable size for the string buffer so we have to resize + // at most once. + int size = protocol.length() + host.length() + file.length() + 24; + StringBuffer sb = new StringBuffer(size); + + sb.append(protocol); + sb.append(':'); + + if (host.length() != 0) + sb.append("//").append(host); + // Note that this produces different results from JDK 1.2 as JDK 1.2 // ignores a non-default port if host is null or "". That is inconsistent // with the spec since the result of this method is spec'ed so it can be // used to construct a new URL that is equivalent to the original. - if (host == null) - host = ""; - if (port >= 0 || ! (host.length() == 0)) - resStr = resStr + "//" + host + (port < 0 ? "" : ":" + port); + boolean port_needed = port >= 0 && port != getDefaultPort(); + if (port_needed) + sb.append(':').append(port); - resStr = resStr + file; + sb.append(file); if (ref != null) - resStr = resStr + "#" + ref; + sb.append('#').append(ref); - return resStr; + return sb.toString(); } } |