With this test case (just added to mauve):
import java.net.URL;
public class URLTest {
public static void main(String []args) {
try {
URL url = new URL("http://www.foo.bar.com");
url = new URL(url, "_urn:testing/");
System.out.println("url: " + url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Classpath is currently treating the "_urn:" as a protocol and discarding
the context even though "_urn:" is not a valid protocol. Sun's runtime
will append the spec to the context in this case instead of replacing
the context.
Unless objections are raised in the next 24 hours, I plan in committing
the folowing patch:
2006-02-28 David Daney <[EMAIL PROTECTED]>
* java/net/URL.java (URL(URL, String, URLStreamHandler)): Treat
spec
as relative if it contains a colon but no protocol handler can be
found.
Index: java/net/URL.java
===================================================================
RCS file: /sources/classpath/classpath/java/net/URL.java,v
retrieving revision 1.52
diff -u -p -r1.52 URL.java
--- java/net/URL.java 12 Jan 2006 13:31:10 -0000 1.52
+++ java/net/URL.java 28 Feb 2006 23:58:16 -0000
@@ -399,40 +399,59 @@ public final class URL implements Serial
&& ! spec.regionMatches(colon, "://:", 0, 4))
context = null;
+ boolean protocolSpecified = false;
+
if ((colon = spec.indexOf(':')) > 0
&& (colon < slash || slash < 0))
{
- // Protocol specified in spec string.
+ // Protocol may have been specified in spec string.
+ protocolSpecified = true;
protocol = spec.substring(0, colon).toLowerCase();
- if (context != null && context.protocol.equals(protocol))
- {
- // The 1.2 doc specifically says these are copied to the new URL.
- host = context.host;
- port = context.port;
- userInfo = context.userInfo;
- authority = context.authority;
- }
+ if (context != null)
+ {
+ if (context.protocol.equals(protocol))
+ {
+ // The 1.2 doc specifically says these are copied to the new
URL.
+ host = context.host;
+ port = context.port;
+ userInfo = context.userInfo;
+ authority = context.authority;
+ }
+ else
+ {
+ // There was a colon in the spec. Check to see if
+ // what precedes it is a valid protocol. If it was
+ // not, assume that it is relative to the context.
+ URLStreamHandler specPh = getURLStreamHandler(protocol.trim());
+ if (null == specPh)
+ protocolSpecified = false;
+ }
+ }
}
- else if (context != null)
+
+ if (!protocolSpecified)
{
- // Protocol NOT specified in spec string.
- // Use context fields (except ref) as a foundation for relative URLs.
- colon = -1;
- protocol = context.protocol;
- host = context.host;
- port = context.port;
- userInfo = context.userInfo;
- if (spec.indexOf(":/", 1) < 0)
- {
- file = context.file;
- if (file == null || file.length() == 0)
- file = "/";
- }
- authority = context.authority;
+ if (context != null)
+ {
+ // Protocol NOT specified in spec string.
+ // Use context fields (except ref) as a foundation for relative
URLs.
+ colon = -1;
+ protocol = context.protocol;
+ host = context.host;
+ port = context.port;
+ userInfo = context.userInfo;
+ if (spec.indexOf(":/", 1) < 0)
+ {
+ file = context.file;
+ if (file == null || file.length() == 0)
+ file = "/";
+ }
+ authority = context.authority;
+ }
+ else // Protocol NOT specified in spec. and no context available.
+ throw new MalformedURLException("Absolute URL required with null"
+ + " context: " + spec);
}
- else // Protocol NOT specified in spec. and no context available.
- throw new MalformedURLException("Absolute URL required with null"
- + " context: " + spec);
protocol = protocol.trim();