classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Enhancement to URLStreamHandler


From: Wu, Gansha
Subject: Enhancement to URLStreamHandler
Date: Fri, 10 Aug 2001 10:06:09 +0800

    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); 
        }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]