RelativePath.java :  » UML » xuml-compiler » moten » david » util » io » Java Open Source

Java Open Source » UML » xuml compiler 
xuml compiler » moten » david » util » io » RelativePath.java
package moten.david.util.io;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 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;

    // added by David Moten because did not work properly if home was not
    // a directory
    if (!home.isDirectory())
      return getRelativePath(home.getParentFile(), f);

    homelist = getPathList(home);
    filelist = getPathList(f);
    s = matchPathLists(homelist, filelist);

    return s;
  }

  /**
   * test the function
   */
  public static void main(String args[]) {
    String s1 = "a/b.t";
    String s2 = "a/c.t";
    System.out.println(getRelativePath(new File(s1), new File(s2)));
    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])));
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.