diff --git a/util/pom.xml b/util/pom.xml index 110d5cb4..82687fe7 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -16,5 +16,10 @@ commons-cli 1.2 + + junit + junit + 4.6 + \ No newline at end of file diff --git a/util/src/main/java/org/jf/util/PathUtil.java b/util/src/main/java/org/jf/util/PathUtil.java new file mode 100644 index 00000000..91eb7584 --- /dev/null +++ b/util/src/main/java/org/jf/util/PathUtil.java @@ -0,0 +1,125 @@ +/* + * [The "BSD licence"] + * Copyright (c) 2010 Ben Gruver + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.util; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +public class PathUtil { + private PathUtil() { + } + + public static File getRelativeFile(File baseFile, File fileToRelativize) throws IOException { + if (baseFile.isFile()) { + baseFile = baseFile.getParentFile(); + } + + return new File(getRelativeFileInternal(baseFile.getCanonicalFile(), fileToRelativize.getCanonicalFile())); + } + + public static String getRelativePath(String basePath, String pathToRelativize) throws IOException { + File baseFile = new File(basePath); + if (baseFile.isFile()) { + baseFile = baseFile.getParentFile(); + } + + return getRelativeFileInternal(baseFile.getCanonicalFile(), + new File(pathToRelativize).getCanonicalFile()); + } + + static String getRelativeFileInternal(File canonicalBaseFile, File canonicalFileToRelativize) { + ArrayList basePath = getPathComponents(canonicalBaseFile); + ArrayList pathToRelativize = getPathComponents(canonicalFileToRelativize); + + //if the roots aren't the same (i.e. different drives on a windows machine), we can't construct a relative + //path from one to the other, so just return the canonical file + if (!basePath.get(0).equals(pathToRelativize.get(0))) { + return canonicalFileToRelativize.getPath(); + } + + int commonDirs; + StringBuilder sb = new StringBuilder(); + + for (commonDirs=1; commonDirs getPathComponents(File file) { + ArrayList path = new ArrayList(); + + while (file != null) { + File parentFile = file.getParentFile(); + + if (parentFile == null) { + path.add(0, file.getPath()); + } else { + path.add(0, file.getName()); + } + + file = parentFile; + } + + return path; + } +} diff --git a/util/src/test/java/org/jf/util/PathUtilTest.java b/util/src/test/java/org/jf/util/PathUtilTest.java new file mode 100644 index 00000000..cafc41f5 --- /dev/null +++ b/util/src/test/java/org/jf/util/PathUtilTest.java @@ -0,0 +1,269 @@ +/* + * [The "BSD licence"] + * Copyright (c) 2010 Ben Gruver + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.util; + +import org.junit.*; + +import java.io.File; + +public class PathUtilTest { + + @Test + public void pathUtilTest1() { + File[] roots = File.listRoots(); + + if (roots.length > 1) { + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "test.txt"); + File relativePath = new File(roots[1] + "some" + File.separatorChar + "dir" + File.separatorChar + "test.txt"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, relativePath.getPath()); + } + } + + @Test + public void pathUtilTest2() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "test.txt"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "test.txt"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + /*the "internal" version of the method in PathUtil doesn't handle the case when the "leaf" of the base path + is a file, this is handled by the two public wrappers. Since we're not calling them, the correct return is + a single dot"*/ + Assert.assertEquals(path, "."); + } + + @Test + public void pathUtilTest3() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "."); + } + + @Test + public void pathUtilTest4() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "."); + } + + @Test + public void pathUtilTest5() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "."); + } + + @Test + public void pathUtilTest6() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "."); + } + + @Test + public void pathUtilTest7() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir"); + } + + @Test + public void pathUtilTest8() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir"); + } + + @Test + public void pathUtilTest9() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir"); + } + + @Test + public void pathUtilTest10() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir"); + } + + @Test + public void pathUtilTest11() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest12() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2" + File.separatorChar); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest13() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2" + File.separatorChar); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest14() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest15() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir3"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, ".." + File.separatorChar + "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest16() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some2" + File.separatorChar + "dir3"); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, ".." + File.separatorChar + ".." + File.separatorChar + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest17() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0].getPath()); + File relativePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + } + + @Test + public void pathUtilTest18() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir"); + File relativePath = new File(roots[0] + "some"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, ".."); + } + + @Test + public void pathUtilTest19() { + File[] roots = File.listRoots(); + + File basePath = new File(roots[0] + "some" + File.separatorChar + "dir" + File.separatorChar + "dir2"); + File relativePath = new File(roots[0] + "some"); + + String path = PathUtil.getRelativeFileInternal(basePath, relativePath); + + Assert.assertEquals(path, ".." + File.separatorChar + ".."); + } +}