1 package com.thoughtworks.xstream.io.path; 2 3 import com.thoughtworks.xstream.core.util.FastStack; 4 5 import java.util.List ; 6 import java.util.ArrayList ; 7 8 38 public class Path { 39 40 private final String [] chunks; 41 private transient String pathAsString; 42 private static final Path DOT = new Path(new String [] {"."}); 43 44 public Path(String pathAsString) { 45 List result = new ArrayList (); 47 int currentIndex = 0; 48 int nextSeperator; 49 while ((nextSeperator = pathAsString.indexOf('/', currentIndex)) != -1) { 50 result.add(pathAsString.substring(currentIndex, nextSeperator)); 51 currentIndex = nextSeperator + 1; 52 } 53 result.add(pathAsString.substring(currentIndex)); 54 String [] arr = new String [result.size()]; 55 result.toArray(arr); 56 chunks = arr; 57 this.pathAsString = pathAsString; 58 } 59 60 public Path(String [] chunks) { 61 this.chunks = chunks; 62 } 63 64 public String toString() { 65 if (pathAsString == null) { 66 StringBuffer buffer = new StringBuffer (); 67 for (int i = 0; i < chunks.length; i++) { 68 if (i > 0) buffer.append('/'); 69 buffer.append(chunks[i]); 70 } 71 pathAsString = buffer.toString(); 72 } 73 return pathAsString.toString(); 74 } 75 76 public boolean equals(Object o) { 77 if (this == o) return true; 78 if (!(o instanceof Path)) return false; 79 80 final Path other = (Path) o; 81 if (chunks.length != other.chunks.length) return false; 82 for (int i = 0; i < chunks.length; i++) { 83 if (!chunks[i].equals(other.chunks[i])) return false; 84 } 85 86 return true; 87 } 88 89 public int hashCode() { 90 int result = 543645643; 91 for (int i = 0; i < chunks.length; i++) { 92 result = 29 * result + chunks[i].hashCode(); 93 } 94 return result; 95 } 96 97 public Path relativeTo(Path that) { 98 int depthOfPathDivergence = depthOfPathDivergence(chunks, that.chunks); 99 String [] result = new String [chunks.length + that.chunks.length - 2 * depthOfPathDivergence]; 100 int count = 0; 101 102 for (int i = depthOfPathDivergence; i < chunks.length; i++) { 103 result[count++] = ".."; 104 } 105 for (int j = depthOfPathDivergence; j < that.chunks.length; j++) { 106 result[count++] = that.chunks[j]; 107 } 108 109 if (count == 0) { 110 return DOT; 111 } else { 112 return new Path(result); 113 } 114 } 115 116 private int depthOfPathDivergence(String [] path1, String [] path2) { 117 int minLength = Math.min(path1.length, path2.length); 118 for (int i = 0; i < minLength; i++) { 119 if (!path1[i].equals(path2[i])) { 120 return i; 121 } 122 } 123 return minLength; 124 } 125 126 public Path apply(Path relativePath) { 127 FastStack absoluteStack = new FastStack(16); 128 129 for (int i = 0; i < chunks.length; i++) { 130 absoluteStack.push(chunks[i]); 131 } 132 133 for (int i = 0; i < relativePath.chunks.length; i++) { 134 String relativeChunk = relativePath.chunks[i]; 135 if (relativeChunk.equals("..")) { 136 absoluteStack.pop(); 137 } else if (!relativeChunk.equals(".")) { 138 absoluteStack.push(relativeChunk); 139 } 140 } 141 142 String [] result = new String [absoluteStack.size()]; 143 for (int i = 0; i < result.length; i++) { 144 result[i] = (String ) absoluteStack.get(i); 145 } 146 147 return new Path(result); 148 } 149 } 150 | Popular Tags |