The heart of URLStreamHandler is parseURL, Classpath's current implementation
of parseURL set strict constraints on the input url_string according to
rfc1738.txt(url_string
has been cut off the leading "file:"):
//[host[:port]]/dir/dir/file#anchor
But in my using of URLStreamHandler, there may be many exceptions such like:
[host[:port]]/dir/dir/file
d:\dir\dir\file
\dir\dir\file
//d:\dir\dir\file
///d:/dir/dir/file
//\dir\dir\file
///dir/dir/file
/d:/dir/dir/file
///d%7C/dir/dir/file
///d|/dir/dir/file
////host/path <- UNC name convention
.. ...
Those exceptions are from platform difference, different usage model(webserver
file resource
or webDAV resource or RMI codebase problem etc. ) We should deal with such exceptions,
here
is a patch for it, it should not be the best, but it tries to keep the changes
minor. And there're
many places (especially string operations) could be optimized.
protected void
parseURL(URL url, String url_string, int start, int end)
{
// This method does not throw an exception or return a value. Thus our
// strategy when we encounter an error in parsing is to return without
// doing anything.
// Bunches of things should be true. Make sure.
if (end < start)
return;
if ((end - start) < 2)
return;
if (start > url_string.length())
return;
if (end > url_string.length())
end = url_string.length(); // This should be safe
// Turn end into an offset from the end of the string instead of
// the beginning
end = url_string.length() - end;
// Skip remains of protocol
url_string = url_string.substring(start);
- if (!url_string.startsWith("//"))
- return;
- url_string = url_string.substring(2);
+ //normalize the file separator
+ url_string =
+url_string.replace(System.getProperty("file.separator").charAt(0), '/');
+ //deal with the case: file:///d|/dir/dir/file and file:///d%7C/dir/dir/file
+ url_string = url_string.replace('|', ':');
+ int i;
+ if((i = url_string.toUpperCase().indexOf("%7C")) >= 0)
+ url_string = url_string.substring(0, i) + ":" + url_string.substring(i+3);
+ boolean nohost = false; //whether no host part presents
+ if (url_string.startsWith("//"))
url_string = url_string.substring(2); //filter the leading "//"
+ // if another "/" encounters, it's end of a null host part or beginning of
+root path
+ if (url_string.startsWith("/")){
+ nohost = true;
+ url_string = url_string.substring(1);
+ }
+ boolean winfile = false; //whether it's a windows platform file:
+drive:/dir/dir/file
+ String prefix = "/"; //root path prefix of a file: could be "/" or "drive:/"
+ if(url_string.charAt(1) == ':' && url_string.charAt(2) == '/'){
+ winfile = true;
+ nohost = true;
+ prefix = url_string.substring(0, 3); //assign "drive:/" to prefix
+ url_string = url_string.substring(3);
+ }
// Declare some variables
String host = null;
int port = -1;
String file = null;
String anchor = null;
+ if(!nohost){
// Process host and port
int slash_index = url_string.indexOf("/");
int colon_index = url_string.indexOf(":");
if (slash_index > (url_string.length() - end))
return;
else if (slash_index == -1)
slash_index = url_string.length() - end;
if ((colon_index == -1) || (colon_index > slash_index))
{
host = url_string.substring(0, slash_index);
}
else
{
host = url_string.substring(0, colon_index);
String port_str = url_string.substring(colon_index + 1, slash_index);
try
{
port = Integer.parseInt(port_str);
}
catch (NumberFormatException e)
{
return;
}
}
if (slash_index < (url_string.length() - 1))
url_string = url_string.substring(slash_index + 1);
else
url_string = "";
+ }
// Process file and anchor
if (end == 0)
{
- file = "/" + url_string;
+ file = prefix + url_string;
anchor = null;
}
else
{
- file = "/" + url_string.substring(0, url_string.length() - end);
+ file = prefix + url_string.substring(0, url_string.length() - end);
// Only set anchor if end char is a '#'. Otherwise assume we're
// just supposed to stop scanning for some reason
if (url_string.charAt(url_string.length() - end) == '#')
anchor = url_string.substring((url_string.length() - end) + 1,
url_string.length());
else
anchor = null;
}
- if ((file == null) || (file == "")) <--- file couldn't be null
or ""
- file = "/";
// Now set the values
setURL(url, url.getProtocol(), host, port, file, anchor);
}
_______________________________________________
Classpath mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/classpath