Java tutorial
/* Copyright 2009 Tomer Gabel <tomer@tomergabel.com> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ant-intellij-tasks project (http://code.google.com/p/ant-intellij-tasks/) $Id: PathUtils.java 106 2009-09-30 02:07:29Z tomergabel $ */ //package com.tomergabel.util; import java.io.File; import java.util.Deque; import java.util.ArrayDeque; public class PathUtils { /** * Calculates the relative path between a specified root directory and a target path. * * @param root The absolute path of the root directory. * @param target The path to the target file or directory. * @return The relative path between the specified root directory and the target path. * @throws IllegalArgumentException <ul><li>The root file cannot be null.</li><li>The target cannot be * null.</li><li>The root file must be a directory.</li><li>The root file must be * absolute.</li></ul> */ public static String relativize(final File root, final File target) throws IllegalArgumentException { if (root == null) throw new IllegalArgumentException("The root file cannot be null."); if (target == null) throw new IllegalArgumentException("The target cannot be null."); if (!root.isDirectory()) throw new IllegalArgumentException("The root file must be a directory."); if (!root.isAbsolute()) throw new IllegalArgumentException("The root file must be absolute."); if (!target.isAbsolute()) return target.toString(); if (root.equals(target)) return "."; // Deconstruct hierarchies final Deque<File> rootHierarchy = new ArrayDeque<File>(); for (File f = root; f != null; f = f.getParentFile()) rootHierarchy.push(f); final Deque<File> targetHierarchy = new ArrayDeque<File>(); for (File f = target; f != null; f = f.getParentFile()) targetHierarchy.push(f); // Trace common root while (rootHierarchy.size() > 0 && targetHierarchy.size() > 0 && rootHierarchy.peek().equals(targetHierarchy.peek())) { rootHierarchy.pop(); targetHierarchy.pop(); } // Create relative path final StringBuilder sb = new StringBuilder(rootHierarchy.size() * 3 + targetHierarchy.size() * 32); while (rootHierarchy.size() > 0) { sb.append(".."); rootHierarchy.pop(); if (rootHierarchy.size() > 0 || targetHierarchy.size() > 0) sb.append(File.separator); } while (targetHierarchy.size() > 0) { sb.append(targetHierarchy.pop().getName()); if (targetHierarchy.size() > 0) sb.append(File.separator); } return sb.toString(); } }