Repository: ant-ivy
Updated Branches:
  refs/heads/master 36e99429c -> a7a348910


IVY-1522 Fix FileUtil.normalize to not base its normalization logic on ":" 
character


Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/9ea5c69b
Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/9ea5c69b
Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/9ea5c69b

Branch: refs/heads/master
Commit: 9ea5c69bda2ed1ec0c69c081e91b72dcf6a6e81c
Parents: 36e9942
Author: Jaikiran Pai <[email protected]>
Authored: Thu May 18 20:12:41 2017 +0530
Committer: Jaikiran Pai <[email protected]>
Committed: Fri May 26 13:25:01 2017 +0530

----------------------------------------------------------------------
 src/java/org/apache/ivy/util/FileUtil.java     | 99 ++++++++++++---------
 test/java/org/apache/ivy/ant/FileUtilTest.java | 92 +++++++++++++++++++
 2 files changed, 150 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/9ea5c69b/src/java/org/apache/ivy/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/FileUtil.java 
b/src/java/org/apache/ivy/util/FileUtil.java
index e251f5c..52e03db 100644
--- a/src/java/org/apache/ivy/util/FileUtil.java
+++ b/src/java/org/apache/ivy/util/FileUtil.java
@@ -543,11 +543,11 @@ public final class FileUtil {
      *             if path is null.
      */
     public static File normalize(final String path) {
-        Stack<String> s = new Stack<String>();
-        String[] dissect = dissect(path);
-        s.push(dissect[0]);
+        final Stack<String> s = new Stack<String>();
+        final DissectedPath dissectedPath = dissect(path);
+        s.push(dissectedPath.root);
 
-        StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
+        final StringTokenizer tok = new 
StringTokenizer(dissectedPath.remainingPath, File.separator);
         while (tok.hasMoreTokens()) {
             String thisToken = tok.nextToken();
             if (".".equals(thisToken)) {
@@ -563,7 +563,7 @@ public final class FileUtil {
                 s.push(thisToken);
             }
         }
-        StringBuffer sb = new StringBuffer();
+        final StringBuffer sb = new StringBuffer();
         for (int i = 0; i < s.size(); i++) {
             if (i > 1) {
                 // not before the filesystem root and not after it, since root
@@ -580,49 +580,50 @@ public final class FileUtil {
      * 
      * @param path
      *            the path to dissect.
-     * @return String[] {root, remaining path}.
+     * @return {@link DissectedPath}
      * @throws java.lang.NullPointerException
      *             if path is null.
      * @since Ant 1.7
      */
-    private static String[] dissect(String path) {
-        char sep = File.separatorChar;
-        path = path.replace('/', sep).replace('\\', sep);
-
-        // // make sure we are dealing with an absolute path
-        // if (!isAbsolutePath(path)) {
-        // throw new BuildException(path + " is not an absolute path");
-        // }
-        String root = null;
-        int colon = path.indexOf(':');
-        if (colon > 0) { // && (ON_DOS || ON_NETWARE)) {
-
-            int next = colon + 1;
-            root = path.substring(0, next);
-            char[] ca = path.toCharArray();
-            root += sep;
-            // remove the initial separator; the root has it.
-            next = (ca[next] == sep) ? next + 1 : next;
-
-            StringBuffer sbPath = new StringBuffer();
-            // Eliminate consecutive slashes after the drive spec:
-            for (int i = next; i < ca.length; i++) {
-                if (ca[i] != sep || ca[i - 1] != sep) {
-                    sbPath.append(ca[i]);
+    private static DissectedPath dissect(final String path) {
+        final char sep = File.separatorChar;
+        final String pathToDissect = path.replace('/', sep).replace('\\', 
sep).trim();
+
+        // check if the path starts with a filesystem root
+        final File[] filesystemRoots = File.listRoots();
+        if (filesystemRoots != null) {
+            for (final File filesystemRoot : filesystemRoots) {
+                if (pathToDissect.startsWith(filesystemRoot.getPath())) {
+                    // filesystem root is the root and the rest of the path is 
the "remaining path"
+                    final String root = filesystemRoot.getPath();
+                    final String rest = pathToDissect.substring(root.length());
+                    final StringBuffer sbPath = new StringBuffer();
+                    // Eliminate consecutive slashes after the drive spec:
+                    for (int i = 0; i < rest.length(); i++) {
+                        final char currentChar = rest.charAt(i);
+                        if (i == 0) {
+                            sbPath.append(currentChar);
+                            continue;
+                        }
+                        final char previousChar = rest.charAt(i -1);
+                        if (currentChar != sep || previousChar != sep) {
+                            sbPath.append(currentChar);
+                        }
+                    }
+                    return new DissectedPath(root, sbPath.toString());
                 }
             }
-            path = sbPath.toString();
-        } else if (path.length() > 1 && path.charAt(1) == sep) {
-            // UNC drive
-            int nextsep = path.indexOf(sep, 2);
-            nextsep = path.indexOf(sep, nextsep + 1);
-            root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
-            path = path.substring(root.length());
-        } else {
-            root = File.separator;
-            path = path.substring(1);
         }
-        return new String[] {root, path};
+        // UNC drive
+        if (pathToDissect.length() > 1 && pathToDissect.charAt(1) == sep) {
+            int nextsep = pathToDissect.indexOf(sep, 2);
+            nextsep = pathToDissect.indexOf(sep, nextsep + 1);
+            final String root = (nextsep > 2) ? pathToDissect.substring(0, 
nextsep + 1) : pathToDissect;
+            final String rest = pathToDissect.substring(root.length());
+            return new DissectedPath(root, rest);
+        }
+
+        return new DissectedPath(File.separator, pathToDissect.substring(1));
     }
 
     /**
@@ -741,4 +742,20 @@ public final class FileUtil {
         }
 
     }
+
+    private static final class DissectedPath {
+        private final String root;
+        private final String remainingPath;
+
+        private DissectedPath(final String root, final String remainingPath) {
+            this.root = root;
+            this.remainingPath = remainingPath;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder("Dissected Path 
[root=").append(root).append(", remainingPath=")
+                    .append(remainingPath).append("]").toString();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/9ea5c69b/test/java/org/apache/ivy/ant/FileUtilTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/ant/FileUtilTest.java 
b/test/java/org/apache/ivy/ant/FileUtilTest.java
new file mode 100644
index 0000000..955462b
--- /dev/null
+++ b/test/java/org/apache/ivy/ant/FileUtilTest.java
@@ -0,0 +1,92 @@
+/*
+ *  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.ivy.ant;
+
+
+import org.apache.ivy.util.FileUtil;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests {@link FileUtil}
+ *
+ * @author Jaikiran Pai
+ */
+public class FileUtilTest {
+
+    /**
+     * Tests that {@link FileUtil#normalize(String)} works as expected for 
some basic file paths
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSimpleNormalize() throws Exception {
+        final File ivySettingsFile = new 
File("test/repositories/ivysettings.xml");
+        final File normalizedIvySettingsFile = 
FileUtil.normalize(ivySettingsFile.getAbsolutePath());
+        assertEquals("Unexpected normalization of file path " + 
ivySettingsFile.getAbsolutePath(), ivySettingsFile.getAbsolutePath(), 
normalizedIvySettingsFile.getAbsolutePath());
+        assertTrue(normalizedIvySettingsFile.getAbsolutePath() + " isn't a 
file", normalizedIvySettingsFile.isFile());
+    }
+
+
+    /**
+     * Tests that {@link FileUtil#normalize(String)} works as expected when 
passed a path that starts with
+     * {@link File#listRoots() filesystem roots}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testNormalizeOfFileSystemRootPath() throws Exception {
+        for (final File fileSystemRoot : File.listRoots()) {
+            final File normalized = 
FileUtil.normalize(fileSystemRoot.getPath());
+            assertNotNull("Normalized path was null for " + fileSystemRoot, 
normalized);
+            assertEquals("Unexpected normalized path for " + fileSystemRoot, 
fileSystemRoot.getPath(), normalized.getPath());
+
+            // use . and .. characters in the path to test out the normalize 
method
+            final String pathOne = fileSystemRoot.getPath() + "." + 
File.separator;
+            assertEquals("Unexpected normalization of " + pathOne, 
fileSystemRoot.getPath(), FileUtil.normalize(pathOne).getPath());
+
+            final String pathTwo = fileSystemRoot.getPath() + "." + 
File.separator + "foo-bar";
+            assertEquals("Unexpected normalization of " + pathTwo, 
fileSystemRoot.getPath() + "foo-bar",
+                    FileUtil.normalize(pathTwo).getPath());
+
+            final String pathThree = fileSystemRoot.getPath() + "foo-bar" + 
File.separator + ".." + File.separator;
+            assertEquals("Unexpected normalization of " + pathThree, 
fileSystemRoot.getPath(),
+                    FileUtil.normalize(pathThree).getPath());
+
+            // append some additional file separator characters to the file 
system root and normalize it
+            final String pathFour = fileSystemRoot.getPath() + File.separator 
+ File.separator + File.separator;
+            assertEquals("Unexpected normalization of " + pathFour, 
fileSystemRoot.getPath(), FileUtil.normalize(pathFour).getPath());
+
+            final String pathFive = fileSystemRoot.getPath() + File.separator 
+ File.separator + "abcd";
+            assertEquals("Unexpected normalization of path " + pathFive, 
fileSystemRoot.getPath() + "abcd", FileUtil.normalize(pathFive).getPath());
+
+            final String pathSix = fileSystemRoot.getPath() + File.separator + 
File.separator + "1234" + File.separator;
+            assertEquals("Unexpected normalization of path " + pathSix, 
fileSystemRoot.getPath() + "1234", FileUtil.normalize(pathSix).getPath());
+
+            final String pathSeven = fileSystemRoot.getPath() + "helloworld" + 
File.separator + ".." + File.separator + File.separator + File.separator + 
"helloworld";
+            assertEquals("Unexpected normalization of path " + pathSeven, 
fileSystemRoot.getPath() + "helloworld", 
FileUtil.normalize(pathSeven).getPath());
+
+        }
+    }
+
+}

Reply via email to