| // URLStreamHandler.java - Superclass of all stream protocol handlers. |
| |
| /* Copyright (C) 1999 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; |
| |
| /** |
| * @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. |
| */ |
| |
| public abstract class URLStreamHandler |
| { |
| protected abstract URLConnection openConnection(URL u) |
| throws java.io.IOException; |
| |
| protected void parseURL(URL u, String spec, int start, int limit) |
| { |
| String host = u.getHost(); |
| int port = u.getPort(); |
| String file = u.getFile(); |
| |
| /* 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; |
| int colon; |
| |
| start += 2; |
| int slash = spec.indexOf('/', start); |
| if (slash >= 0) |
| hostEnd = slash; |
| else |
| hostEnd = limit; |
| |
| host = spec.substring (start, hostEnd); |
| |
| // Look for optional port number. It is valid for the non-port |
| // part of the host name to be null (e.g. a URL "http://:80"). |
| // TBD: JDK 1.2 in this case sets host to null rather than ""; |
| // this is undocumented and likely an unintended side effect in 1.2 |
| // so we'll be simple here and stick with "". Note that |
| // "http://" or "http:///" produce a "" host in JDK 1.2. |
| if ((colon = host.indexOf(':')) >= 0) |
| { |
| try |
| { |
| port = Integer.parseInt(host.substring(colon + 1)); |
| } |
| catch (NumberFormatException e) |
| { |
| ; // Ignore invalid port values; port is already set to u's |
| // port. |
| } |
| host = host.substring(0, colon); |
| } |
| file = null; |
| start = hostEnd; |
| } |
| 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) |
| { |
| // No file context available; just spec for file. |
| file = "/" + spec.substring(start, limit); |
| } |
| else if (start < limit) |
| { |
| // Context is available, but only override it if there is a new file. |
| // FIXME: unsure to what extent `/` and File.separatorChar |
| // can mix in URLs. Ignore File.separatorChar for now. |
| file = file.substring(0, file.lastIndexOf('/')) |
| + "/" + spec.substring(start, limit); |
| } |
| |
| int index; |
| |
| // Replace "/./" with "/". This probably isn't very efficient in |
| // the general case, but it's probably not bad most of the time. |
| while ((index = file.indexOf("/./")) >= 0) |
| file = file.substring(0, index) + file.substring(index + 2); |
| |
| // Process "/../" correctly. This probably isn't very efficient in |
| // the general case, but it's probably not bad most of the time. |
| while ((index = file.indexOf("/../")) >= 0) |
| { |
| // Strip of the previous directory - if it exists. |
| int previous = file.lastIndexOf('/', index - 1); |
| if (previous >= 0) |
| file = file.substring(0, previous) + file.substring(index + 3); |
| else |
| break; |
| } |
| |
| u.set(u.getProtocol(), host, port, file, u.getRef()); |
| } |
| |
| protected void setURL(URL u, String protocol, String host, int port, |
| String file, String ref) |
| { |
| u.set(protocol, host, port, file, ref); |
| } |
| |
| protected String toExternalForm(URL u) |
| { |
| String resStr, host, file, ref; |
| int port; |
| |
| resStr = u.getProtocol() + ":"; |
| host = u.getHost(); |
| 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. |
| // |
| // 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); |
| |
| resStr = resStr + file; |
| |
| if (ref != null) |
| resStr = resStr + "#" + ref; |
| |
| return resStr; |
| } |
| } |