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])));
}
}