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