From 5bedfc9356014b29aa696f63421d3a3b000fc57c Mon Sep 17 00:00:00 2001 From: Ranjit Mathew Date: Sat, 1 Mar 2003 23:38:13 +0000 Subject: File (getAbsolutePath): Prefix drive specifier on Windows for paths starting with a '\'. 2003-03-01 Ranjit Mathew * java/io/File (getAbsolutePath): Prefix drive specifier on Windows for paths starting with a '\'. (toURL): Make URL more consistent with what Sun's JDK returns. * java/io/natFileWin32.cc (java::io::File::isAbsolute): Return true only if the path is a UNC network path or it starts with a drive specifier. * java/net/URLStreamHandler.java (parseURL): Correct minor typo. Be prepared to handle either '/' or '\\' in the file path for Windows if using the "file" protocol. Canonicalise the file path if using a relative path in the given context and the "file" protocol. From-SVN: r63635 --- libjava/ChangeLog | 16 ++++++++++++++++ libjava/java/io/File.java | 24 +++++++++++++++++++----- libjava/java/io/natFileWin32.cc | 9 +++++++-- libjava/java/net/URLStreamHandler.java | 33 +++++++++++++++++++++++++++++---- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c340717..a86821f 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,19 @@ +2003-03-01 Ranjit Mathew + + * java/io/File (getAbsolutePath): Prefix drive specifier on + Windows for paths starting with a '\'. + (toURL): Make URL more consistent with what Sun's JDK returns. + + * java/io/natFileWin32.cc (java::io::File::isAbsolute): Return + true only if the path is a UNC network path or it starts with a + drive specifier. + + * java/net/URLStreamHandler.java (parseURL): Correct minor typo. + Be prepared to handle either '/' or '\\' in the file path for + Windows if using the "file" protocol. + Canonicalise the file path if using a relative path in the given + context and the "file" protocol. + 2003-03-01 Mohan Embar * java/lang/natWin32Process.cc (startProcess): Double-quote each diff --git a/libjava/java/io/File.java b/libjava/java/io/File.java index 2086f10..367fd44 100644 --- a/libjava/java/io/File.java +++ b/libjava/java/io/File.java @@ -1,6 +1,6 @@ // File.java - File name -/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of libgcj. @@ -153,12 +153,20 @@ public class File implements Serializable, Comparable this (dir == null ? null : dir.path, name); } - // FIXME ??? public String getAbsolutePath () { if (isAbsolute ()) return path; - return System.getProperty("user.dir") + separatorChar + path; + else if (separatorChar == '\\' + && path.length () > 0 && path.charAt (0) == '\\') + { + // On Windows, even if the path starts with a '\\' it is not + // really absolute until we prefix the drive specifier from + // the current working directory to it. + return System.getProperty ("user.dir").substring (0, 2) + path; + } + else + return System.getProperty ("user.dir") + separatorChar + path; } /** @since 1.2 */ @@ -289,8 +297,14 @@ public class File implements Serializable, Comparable public URL toURL () throws MalformedURLException { - return new URL ("file://" + getAbsolutePath () - + (isDirectory() ? "/" : "")); + // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt", + // while on UNIX, it returns URLs of the form "file:/foo/bar.txt". + if (separatorChar == '\\') + return new URL ("file:/" + getAbsolutePath ().replace ('\\', '/') + + (isDirectory() ? "/" : "")); + else + return new URL ("file:" + getAbsolutePath () + + (isDirectory() ? "/" : "")); } private final native boolean performMkdir (); diff --git a/libjava/java/io/natFileWin32.cc b/libjava/java/io/natFileWin32.cc index 5245feb5..9029881 100644 --- a/libjava/java/io/natFileWin32.cc +++ b/libjava/java/io/natFileWin32.cc @@ -119,9 +119,14 @@ java::io::File::getCanonicalPath (void) jboolean java::io::File::isAbsolute (void) { - if (path->length() > 0 - && (path->charAt(0) == '/' || path->charAt(0) == '\\')) + // See if the path represents a Windows UNC network path. + if (path->length () > 1 + && (path->charAt (0) == '\\') && (path->charAt (1) == '\\')) return true; + + // Note that the path is not an absolute path even if it starts with + // a '/' or a '\' because it lacks a drive specifier. + if (path->length() < 3) return false; // Hard-code A-Za-z because Windows (I think) can't use non-ASCII diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java index 7f86644..d3dd3cc 100644 --- a/libjava/java/net/URLStreamHandler.java +++ b/libjava/java/net/URLStreamHandler.java @@ -1,5 +1,5 @@ /* URLStreamHandler.java -- Abstract superclass for all protocol handlers - Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +39,7 @@ exception statement from your version. */ package java.net; import java.io.IOException; +import java.io.File; /* * Written using on-line Java Platform 1.2 API Specification, as well @@ -112,7 +113,7 @@ public abstract class URLStreamHandler * 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 + * an empty hostname (i.e., "file:///"), which is legal for that protocol * * @param url The URL object in which to store the results * @param spec The String-ized URL to parse @@ -176,8 +177,32 @@ public abstract class URLStreamHandler 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, end); + char sepChar = '/'; + int lastSlash = file.lastIndexOf (sepChar); + if (lastSlash < 0 && File.separatorChar != sepChar + && url.getProtocol ().equals ("file")) + { + // On Windows, even '\' is allowed in a "file" URL. + sepChar = File.separatorChar; + lastSlash = file.lastIndexOf (sepChar); + } + + file = file.substring(0, lastSlash) + + sepChar + spec.substring (start, end); + + if (url.getProtocol ().equals ("file")) + { + // For "file" URLs constructed relative to a context, we + // need to canonicalise the file path. + try + { + file = new File (file).getCanonicalPath (); + } + catch (IOException e) + { + } + } + ref = null; } -- cgit v1.1