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}