aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/net/URLStreamHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/net/URLStreamHandler.java')
-rw-r--r--libjava/java/net/URLStreamHandler.java218
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();
}
}