package sg.atom2d.tools.map; import java.io.*; import java.util.*; /** * this class provides functions used to generate a relative path * from two absolute paths * @author David M. Howard */ public class RelativePath { /** * break a path down into individual elements and add to a list. * example : if a path is /a/b/c/d.txt, the breakdown will be [d.txt,c,b,a] * @param f input file * @return a List collection with the individual elements of the path in * reverse order */ private static List getPathList(File f) { List l = new ArrayList(); File r; try { r = f.getCanonicalFile(); while(r != null) { l.add(r.getName()); r = r.getParentFile(); } } catch (IOException e) { e.printStackTrace(); l = null; } return l; } /** * figure out a string representing the relative path of * 'f' with respect to 'r' * @param r home path * @param f path of file */ private static String matchPathLists(List r,List f) { int i; int j; String s; // start at the beginning of the lists // iterate while both lists are equal s = ""; i = r.size()-1; j = f.size()-1; // first eliminate common root while((i >= 0)&&(j >= 0)&&(r.get(i).equals(f.get(j)))) { i--; j--; } // for each remaining level in the home path, add a .. for(;i>=0;i--) { s += ".." + File.separator; } // for each level in the file path, add the path for(;j>=1;j--) { s += f.get(j) + File.separator; } // file name s += f.get(j); return s; } /** * get relative path of File 'f' with respect to 'home' directory * example : home = /a/b/c * f = /a/d/e/x.txt * s = getRelativePath(home,f) = ../../d/e/x.txt * @param home base path, should be a directory, not a file, * or it doesn't make sense * @param f file to generate path for * @return path from home to f as a string */ public static String getRelativePath(File home,File f){ File r; List homelist; List filelist; String s; homelist = getPathList(home); filelist = getPathList(f); s = matchPathLists(homelist,filelist); return s; } /** * test the function */ public static void main(String args[]) { if (args.length != 2) { System.out.println("RelativePath <home> <file>"); return; } System.out.println("home = " + args[0]); System.out.println("file = " + args[1]); System.out.println("path = " + getRelativePath(new File(args[0]),new File(args[1]))); } }