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