package ecologylab.bigsemantics.metametadata; import java.io.File; import java.util.ArrayList; import java.util.List; /** * Tools for file / path operations. * * @author quyin * */ public class FileTools { /** * Returns the relative path of file with respect to ancestor. Convenient method so that the * caller does not need to specify the separator. * * @param ancestor * @param path * @return */ public static String getRelativePath(String ancestor, String path) { return getRelativePath(ancestor, path, File.separatorChar); } /** * Returns the relative path of file with respect to ancestor. Requires that the two arguments are * either both absolute paths or both relative paths. * * @param ancestor * @param path * @param separator * @return */ public static String getRelativePath(String ancestor, String path, char separator) { List<String> p1 = decompositePath(ancestor, separator); List<String> p2 = decompositePath(path, separator); // under windows, if the two paths are for different disk partitions, we cannot find a relative // path. if (separator == '\\' && p1.size() > 0 && p1.get(0).endsWith(":") && p2.size() > 0 && p2.get(0).endsWith(":") && !p1.get(0).equals(p2.get(0))) return path; StringBuilder sb = new StringBuilder(); while (!compatible(p1, p2)) { p1.remove(p1.size() - 1); sb.append("..").append(separator); } for (int i = p1.size(); i < p2.size(); ++i) { sb.append(p2.get(i)).append(i == p2.size() - 1 ? "" : separator); } return sb.toString(); } static boolean compatible(List<String> ancestor, List<String> path) { if (ancestor.size() == 0) return true; for (int i = 0; i < ancestor.size(); ++i) { if (i >= path.size() || !ancestor.get(i).equals(path.get(i))) return false; } return true; } static List<String> decompositePath(String path, char separator) { List<String> components = new ArrayList<String>(); StringBuilder sb = new StringBuilder(); char c = 0; for (int i = 0; i < path.length(); ++i) { c = path.charAt(i); if (c != separator) { sb.append(c); } else if (sb.length() > 0) { components.add(sb.toString()); sb.delete(0, sb.length()); } } // last component: if (sb.length() > 0) components.add(sb.toString()); return components; } }