Java tutorial
//package com.java2s; //License from project: Apache License import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Main { public static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0; public static final String WINDOWS_DRIVE_ROOT_REGEX = "[a-zA-Z]:\\\\"; /** * Resolves the relative path of the specified artifact * * @param outputDirectory typically the parent directory of the directory containing the makefile * @param file * @return */ protected static String resolveRelativePath(File outputDirectory, File file) throws IOException { String resolvedPath = file.getCanonicalPath(); String strOutputDirectoryPath = outputDirectory.getCanonicalPath(); String strFilePath = file.getCanonicalPath(); //System.out.println( "Resolving " + strFilePath + " against " + strOutputDirectoryPath ); if (strFilePath.startsWith(strOutputDirectoryPath)) { // Simple case where file is in a subdirectory of outputDirectory resolvedPath = strFilePath.substring(strOutputDirectoryPath.length() + 1); } else { // Look for commonality in paths List<String> outputDirectoryPathParts = splitPath(outputDirectory.getCanonicalFile()); List<String> filePathParts = splitPath(file.getCanonicalFile()); int commonDepth = 0; int maxCommonDepth = Math.min(outputDirectoryPathParts.size(), filePathParts.size()); for (int i = 0; (i < maxCommonDepth) && outputDirectoryPathParts.get(i).equals(filePathParts.get(i)); i++) { commonDepth++; } // If there is a common root build a relative path between the common roots if (commonDepth > 0) { final StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(".."); for (int i = 0; i < outputDirectoryPathParts.size() - commonDepth - 1; i++) { stringBuilder.append(File.separator); stringBuilder.append(".."); } for (int i = commonDepth; i < filePathParts.size(); i++) { stringBuilder.append(File.separator); stringBuilder.append(filePathParts.get(i)); } resolvedPath = stringBuilder.toString(); } else { if (IS_WINDOWS) { // Windows has no common root directory, cannot resolve a path // across drives so ... throw new IOException("Unable to resolve relative path across windows drives"); } // no intersection between paths so calculate a path via the root directory final StringBuilder stringBuilder = new StringBuilder(); File depthCheck = outputDirectory.getParentFile(); while (depthCheck != null) { if (stringBuilder.length() > 0) { stringBuilder.append(File.separator); } stringBuilder.append(".."); depthCheck = depthCheck.getParentFile(); } resolvedPath = stringBuilder.toString() + strFilePath; } } //System.out.println( "resolvedPath = " + resolvedPath ); return resolvedPath; } /** * Method to split the path components of a file into a List * @param f the file to split * @return a new list containing the components of the path as strings */ protected static List<String> splitPath(File f) { List<String> result; File parent = f.getParentFile(); if (parent == null) { result = new ArrayList<String>(); if (f.getName().length() > 0) { // We're at the root but have a name so we have a relative path // for which we need to add the first component to the list result.add(f.getName()); } else if (IS_WINDOWS) { String strF = f.toString(); if (strF.matches(WINDOWS_DRIVE_ROOT_REGEX)) { // We're on windows and the path is <Drive>:\ so we // add the <Drive>: to the list result.add(strF.substring(0, strF.length() - 1).toUpperCase()); } } } else { result = splitPath(parent); result.add(f.getName()); } return result; } }