001package co.codewizards.cloudstore.core.oio; 002 003import java.io.File; 004import java.util.ArrayList; 005import java.util.StringTokenizer; 006 007public final class IoFileRelativePathUtil { 008 009 private static final boolean LIKE_JAVA_NIO_PATH_RELATIVIZE = true; 010 011 private IoFileRelativePathUtil() { } 012 013 static String getRelativePath(final File from, final File to) { 014 return getRelativePath(from, to, File.separatorChar); 015 } 016 017 static String getRelativePath(final File from, final File to, 018 final char separatorChar) { 019 final String fromPath = from.getAbsolutePath(); 020 final String toPath = to.getAbsolutePath(); 021 final boolean isDirectory = from.isDirectory(); 022 return getRelativePath(fromPath, toPath, isDirectory, separatorChar); 023 } 024 025 static String getRelativePath(final String fromPath, 026 final String toPath, boolean isFromPathDirectory, 027 final char separatorChar) { 028 isFromPathDirectory = LIKE_JAVA_NIO_PATH_RELATIVIZE || isFromPathDirectory; //from observation, left for explanation 029 final ArrayList<String> fromPathSegments = splitPath(fromPath); 030 final ArrayList<String> toPathSegments = splitPath(toPath); 031 while (!fromPathSegments.isEmpty() && !toPathSegments.isEmpty()) { 032 if (!(fromPathSegments.get(0).equals(toPathSegments.get(0)))) { 033 break; 034 } 035 fromPathSegments.remove(0); 036 toPathSegments.remove(0); 037 } 038 039 final StringBuffer sb = new StringBuffer(); 040 for (int i = 0; i < fromPathSegments.size() - (isFromPathDirectory ? 0 : 1); i++) { 041 sb.append(".."); 042 sb.append(separatorChar); 043 } 044 for (final String s : toPathSegments) { 045 sb.append(s); 046 sb.append(separatorChar); 047 } 048 return sb.substring(0, sb.length() - 1); 049 } 050 051 private static ArrayList<String> splitPath(final String path) { 052 final ArrayList<String> pathSegments = new ArrayList<String>(); 053 final StringTokenizer st = new StringTokenizer(path, File.separator); 054 while (st.hasMoreTokens()) { 055 final String token = st.nextToken(); 056 if (token.equals(".")) { 057 // skip 058 } else if (token.equals("..")) { 059 if (!pathSegments.isEmpty()) { 060 pathSegments.remove(pathSegments.size() - 1); 061 } 062 } else { 063 pathSegments.add(token); 064 } 065 } 066 return pathSegments; 067 } 068}