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