You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by qi...@apache.org on 2008/11/27 03:29:02 UTC

svn commit: r721071 - in /harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/io/ test/api/unix/org/ test/api/unix/org/apache/ test/api/unix/org/apache/harmony/ test/api/unix/org/apache/harmony/luni/ test/api/unix/org/apache/harmony/luni/t...

Author: qiuxx
Date: Wed Nov 26 18:29:02 2008
New Revision: 721071

URL: http://svn.apache.org/viewvc?rev=721071&view=rev
Log:
Apply for HARMONY-6006 with minor modification,([classlib] [luni] Cannot process platform paths using backslash)

Added:
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java?rev=721071&r1=721070&r2=721071&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/File.java Wed Nov 26 18:29:02 2008
@@ -489,33 +489,12 @@
      */
     public String getCanonicalPath() throws IOException {
         byte[] result = properPath(false);
-
-        boolean exists = false;
-        byte[] pathBytes = result;
-        do {
-            byte[] linkBytes = getLinkImpl(pathBytes);
-            if (linkBytes == pathBytes) {
-                break;
-            }
-            if (linkBytes[0] == separatorChar) {
-                pathBytes = linkBytes;
-            } else {
-                int index = pathBytes.length - 1;
-                while (pathBytes[index] != separatorChar) {
-                    index--;
-                }
-                byte[] temp = new byte[index + 1 + linkBytes.length];
-                System.arraycopy(pathBytes, 0, temp, 0, index + 1);
-                System.arraycopy(linkBytes, 0, temp, index + 1,
-                        linkBytes.length);
-                pathBytes = temp;
-            }
-            exists = existsImpl(pathBytes);
-        } while (exists);
-        if (exists) {
-            result = pathBytes;
+        if(separatorChar == '/') {
+            // resolve the full path first
+            result = resolveLink(result, result.length, false);
+            // resolve the parent directories
+            result = resolve(result);
         }
-
         int numSeparators = 1;
         for (int i = 0; i < result.length; i++) {
             if (result[i] == separatorChar) {
@@ -583,6 +562,93 @@
         newLength = newResult.length;
         return Util.toUTF8String(newResult, 0, newLength);
     }
+    
+    /*
+     * Resolve symbolic links in the parent directories.
+     */
+    private byte[] resolve(byte[] newResult) throws IOException {
+        int last = 1, nextSize, linkSize;
+        byte[] linkPath = newResult, bytes;
+        boolean done, inPlace;
+        for (int i = 1; i <= newResult.length; i++) {
+            if (i == newResult.length || newResult[i] == separatorChar) {
+                done = i >= newResult.length - 1;
+                // if there is only one segment, do nothing
+                if (done && linkPath.length == 1) {
+                    return newResult;
+                }
+                inPlace = false;
+                if (linkPath == newResult) {
+                    bytes = newResult;
+                    // if there are no symbolic links, terminate the C string
+                    // instead of copying
+                    if (!done) {
+                        inPlace = true;
+                        newResult[i] = '\0';
+                    }
+                } else {
+                    nextSize = i - last + 1;
+                    linkSize = linkPath.length;
+                    if (linkPath[linkSize - 1] == separatorChar) {
+                        linkSize--;
+                    }
+                    bytes = new byte[linkSize + nextSize];
+                    System.arraycopy(linkPath, 0, bytes, 0, linkSize);
+                    System.arraycopy(newResult, last - 1, bytes, linkSize,
+                            nextSize);
+                    // the full path has already been resolved
+                }
+                if (done) {
+                    return bytes;
+                }
+                linkPath = resolveLink(bytes, inPlace ? i : bytes.length, true);
+                if (inPlace) {
+                    newResult[i] = '/';
+                }
+                last = i + 1;
+            }
+        }
+        throw new InternalError();
+    }
+
+    /*
+     * Resolve a symbolic link. While the path resolves to an existing path,
+     * keep resolving. If an absolute link is found, resolve the parent
+     * directories if resolveAbsolute is true.
+     */
+    private byte[] resolveLink(byte[] pathBytes, int length,
+            boolean resolveAbsolute) throws IOException {
+        boolean restart = false;
+        byte[] linkBytes, temp;
+        do {
+            linkBytes = getLinkImpl(pathBytes);
+            if (linkBytes == pathBytes) {
+                break;
+            }
+            if (linkBytes[0] == separatorChar) {
+                // link to an absolute path, if resolving absolute paths,
+                // resolve the parent dirs again
+                restart = resolveAbsolute;
+                pathBytes = linkBytes;
+            } else {
+                int last = length - 1;
+                while (pathBytes[last] != separatorChar) {
+                    last--;
+                }
+                last++;
+                temp = new byte[last + linkBytes.length];
+                System.arraycopy(pathBytes, 0, temp, 0, last);
+                System.arraycopy(linkBytes, 0, temp, last, linkBytes.length);
+                pathBytes = temp;
+            }
+            length = pathBytes.length;
+        } while (existsImpl(pathBytes));
+        // resolve the parent directories
+        if (restart) {
+            return resolve(pathBytes);
+        }
+        return pathBytes;
+    }
 
     /**
      * Answers a new File created using the canonical file path of this File.

Added: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java?rev=721071&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java (added)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java Wed Nov 26 18:29:02 2008
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.harmony.luni.tests.java.io;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class UnixFileTest extends TestCase {
+
+    public void test_getCanonicalPath() throws IOException {
+        File tmpFolder1 = new File("folder1");
+        tmpFolder1.mkdirs();
+        tmpFolder1.deleteOnExit();
+
+        File tmpFolder2 = new File(tmpFolder1.toString() + "/folder2");
+        tmpFolder2.mkdirs();
+        tmpFolder2.deleteOnExit();
+
+        File tmpFolder3 = new File(tmpFolder2.toString() + "/folder3");
+        tmpFolder3.mkdirs();
+        tmpFolder3.deleteOnExit();
+
+        File tmpFolder4 = new File(tmpFolder3.toString() + "/folder4");
+        tmpFolder4.mkdirs();
+        tmpFolder4.deleteOnExit();
+
+        // make a link to folder1/folder2
+        Runtime.getRuntime().exec("ln -s folder1/folder2 folder2");
+        File linkFile = new File("folder2");
+        linkFile.deleteOnExit();
+
+        File file = new File("folder2");
+        assertEquals(tmpFolder2.getCanonicalPath(), file.getCanonicalPath());
+
+        file = new File("folder1/folder2");
+        assertEquals(tmpFolder2.getCanonicalPath(), file.getCanonicalPath());
+
+        file = new File("folder2/folder3");
+        assertEquals(tmpFolder3.getCanonicalPath(), file.getCanonicalPath());
+
+        file = new File("folder2/folder3/folder4");
+        assertEquals(tmpFolder4.getCanonicalPath(), file.getCanonicalPath());
+
+        file = new File("folder1/folder2/folder3");
+        assertEquals(tmpFolder3.getCanonicalPath(), file.getCanonicalPath());
+
+        file = new File("folder1/folder2/folder3/folder4");
+        assertEquals(tmpFolder4.getCanonicalPath(), file.getCanonicalPath());
+    }
+    
+}
\ No newline at end of file

Propchange: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/unix/org/apache/harmony/luni/tests/java/io/UnixFileTest.java
------------------------------------------------------------------------------
    svn:eol-style = native