1 package com.github.searls.jasmine.io; 2 3 import org.apache.commons.lang3.StringEscapeUtils; 4 import org.apache.commons.lang3.StringUtils; 5 6 import java.io.File; 7 import java.io.IOException; 8 9 public class RelativizesFilePaths { 10 11 public String relativize(File from, File to) throws IOException { 12 String fromPath = from.getCanonicalPath(); 13 String toPath = to.getCanonicalPath(); 14 15 String root = StringUtils.getCommonPrefix(new String[]{fromPath, toPath}); 16 StringBuffer result = new StringBuffer(); 17 if (this.fromPathIsNotADirectAncestor(fromPath, root)) { 18 for (@SuppressWarnings("unused") String dir : this.divergentDirectories(root, fromPath)) { 19 result.append("..").append(File.separator); 20 } 21 } 22 result.append(this.pathAfterRoot(toPath, root)); 23 24 return this.convertSlashes(this.trimLeadingSlashIfNecessary(result)); 25 } 26 27 private String convertSlashes(String path) { 28 return path.replace(File.separatorChar, '/'); 29 } 30 31 private boolean fromPathIsNotADirectAncestor(String fromPath, String root) { 32 return !StringUtils.equals(root, fromPath); 33 } 34 35 private String[] divergentDirectories(String root, String fullPath) { 36 return this.pathAfterRoot(fullPath, root).split(StringEscapeUtils.escapeJava(File.separator)); 37 } 38 39 private String pathAfterRoot(String path, String root) { 40 return StringUtils.substringAfterLast(path, root); 41 } 42 43 private String trimLeadingSlashIfNecessary(StringBuffer result) { 44 return StringUtils.removeStart(result.toString(), File.separator); 45 } 46 47 }