19ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com/* 29ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * [The "BSD licence"] 39ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver 49ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * All rights reserved. 59ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * 69ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without 79ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions 89ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * are met: 99ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright 109ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer. 119ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright 129ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer in the 139ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * documentation and/or other materials provided with the distribution. 149ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products 159ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * derived from this software without specific prior written permission. 169ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * 179ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 189ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 199ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 209ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 219ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 269ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com */ 289ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 299ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.compackage org.jf.util; 309ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 319ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.comimport java.io.File; 329ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.comimport java.io.IOException; 339ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.comimport java.util.ArrayList; 349ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 359ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.compublic class PathUtil { 369ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com private PathUtil() { 379ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 389ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 399ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com public static File getRelativeFile(File baseFile, File fileToRelativize) throws IOException { 409ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (baseFile.isFile()) { 419ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com baseFile = baseFile.getParentFile(); 429ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 439ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 449ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com return new File(getRelativeFileInternal(baseFile.getCanonicalFile(), fileToRelativize.getCanonicalFile())); 459ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 469ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 479ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com public static String getRelativePath(String basePath, String pathToRelativize) throws IOException { 489ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com File baseFile = new File(basePath); 499ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (baseFile.isFile()) { 509ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com baseFile = baseFile.getParentFile(); 519ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 529ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 539ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com return getRelativeFileInternal(baseFile.getCanonicalFile(), 549ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com new File(pathToRelativize).getCanonicalFile()); 559ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 569ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 579ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com static String getRelativeFileInternal(File canonicalBaseFile, File canonicalFileToRelativize) { 589ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com ArrayList<String> basePath = getPathComponents(canonicalBaseFile); 599ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com ArrayList<String> pathToRelativize = getPathComponents(canonicalFileToRelativize); 609ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 619ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com //if the roots aren't the same (i.e. different drives on a windows machine), we can't construct a relative 629ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com //path from one to the other, so just return the canonical file 639ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (!basePath.get(0).equals(pathToRelativize.get(0))) { 649ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com return canonicalFileToRelativize.getPath(); 659ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 669ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 679ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com int commonDirs; 689ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com StringBuilder sb = new StringBuilder(); 699ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 709ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com for (commonDirs=1; commonDirs<basePath.size() && commonDirs<pathToRelativize.size(); commonDirs++) { 719ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (!basePath.get(commonDirs).equals(pathToRelativize.get(commonDirs))) { 729ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com break; 739ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 749ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 759ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 769ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com boolean first = true; 779ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com for (int i=commonDirs; i<basePath.size(); i++) { 789ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (!first) { 799ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com sb.append(File.separatorChar); 809ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } else { 819ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com first = false; 829ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 839ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 849ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com sb.append(".."); 859ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 869ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 879ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com first = true; 889ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com for (int i=commonDirs; i<pathToRelativize.size(); i++) { 899ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (first) { 909ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (sb.length() != 0) { 919ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com sb.append(File.separatorChar); 929ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 939ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com first = false; 949ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } else { 959ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com sb.append(File.separatorChar); 969ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 979ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 989ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com sb.append(pathToRelativize.get(i)); 999ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 1009ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1019ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (sb.length() == 0) { 1029ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com return "."; 1039ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 1049ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1059ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com return sb.toString(); 1069ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 1079ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1089ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com private static ArrayList<String> getPathComponents(File file) { 1099ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com ArrayList<String> path = new ArrayList<String>(); 1109ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1119ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com while (file != null) { 1129ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com File parentFile = file.getParentFile(); 1139ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1149ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com if (parentFile == null) { 1159ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com path.add(0, file.getPath()); 1169ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } else { 1179ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com path.add(0, file.getName()); 1189ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 1199ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1209ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com file = parentFile; 1219ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 1229ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com 1239ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com return path; 1249ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com } 1259ac6fa5048d851c4afd92534e16cf794bed87ec6JesusFreke@JesusFreke.com} 126