1 11 package org.eclipse.osgi.framework.adaptor; 12 13 import java.io.File ; 14 15 24 public class FilePath { 25 private static final boolean WINDOWS = java.io.File.separatorChar == '\\'; 27 private final static String CURRENT_DIR = "."; private static final char DEVICE_SEPARATOR = ':'; 30 private static final byte HAS_LEADING = 1; 31 private static final byte HAS_TRAILING = 4; 32 private static final String [] NO_SEGMENTS = new String [0]; 34 private final static String PARENT_DIR = ".."; private final static char SEPARATOR = '/'; 36 private final static String UNC_SLASHES = "//"; private String device; 39 private byte flags; 40 private String [] segments; 41 42 47 public FilePath(File location) { 48 initialize(location.getPath()); 49 if (location.isDirectory()) 50 flags |= HAS_TRAILING; 51 else 52 flags &= ~HAS_TRAILING; 53 } 54 55 60 public FilePath(String original) { 61 initialize(original); 62 } 63 64 67 private int computeSegmentCount(String path) { 68 int len = path.length(); 69 if (len == 0 || (len == 1 && path.charAt(0) == SEPARATOR)) 70 return 0; 71 int count = 1; 72 int prev = -1; 73 int i; 74 while ((i = path.indexOf(SEPARATOR, prev + 1)) != -1) { 75 if (i != prev + 1 && i != len) 76 ++count; 77 prev = i; 78 } 79 if (path.charAt(len - 1) == SEPARATOR) 80 --count; 81 return count; 82 } 83 84 87 private String [] computeSegments(String path) { 88 int maxSegmentCount = computeSegmentCount(path); 89 if (maxSegmentCount == 0) 90 return NO_SEGMENTS; 91 String [] newSegments = new String [maxSegmentCount]; 92 int len = path.length(); 93 int firstPosition = isAbsolute() ? 1 : 0; 95 int lastPosition = hasTrailingSlash() ? len - 2 : len - 1; 96 int next = firstPosition; 100 int actualSegmentCount = 0; 101 for (int i = 0; i < maxSegmentCount; i++) { 102 int start = next; 103 int end = path.indexOf(SEPARATOR, next); 104 next = end + 1; 105 String segment = path.substring(start, end == -1 ? lastPosition + 1 : end); 106 if (CURRENT_DIR.equals(segment)) 107 continue; 108 if (PARENT_DIR.equals(segment)) { 109 if (actualSegmentCount > 0) 110 actualSegmentCount--; 111 continue; 112 } 113 newSegments[actualSegmentCount++] = segment; 114 } 115 if (actualSegmentCount == newSegments.length) 116 return newSegments; 117 if (actualSegmentCount == 0) 118 return NO_SEGMENTS; 119 String [] actualSegments = new String [actualSegmentCount]; 120 System.arraycopy(newSegments, 0, actualSegments, 0, actualSegments.length); 121 return actualSegments; 122 } 123 124 130 public String getDevice() { 131 return device; 132 } 133 134 139 public String [] getSegments() { 140 return (String []) segments.clone(); 141 } 142 143 148 public boolean hasTrailingSlash() { 149 return (flags & HAS_TRAILING) != 0; 150 } 151 152 private void initialize(String original) { 153 original = original.indexOf('\\') == -1 ? original : original.replace('\\', SEPARATOR); 154 if (WINDOWS) { 155 int deviceSeparatorPos = original.indexOf(DEVICE_SEPARATOR); 157 if (deviceSeparatorPos >= 0) { 158 int start = original.charAt(0) == SEPARATOR ? 1 : 0; 161 device = original.substring(start, deviceSeparatorPos + 1); 162 original = original.substring(deviceSeparatorPos + 1, original.length()); 163 } else if (original.startsWith(UNC_SLASHES)) { 164 int uncPrefixEnd = original.indexOf(SEPARATOR, 2); 166 if (uncPrefixEnd >= 0) 167 uncPrefixEnd = original.indexOf(SEPARATOR, uncPrefixEnd + 1); 168 if (uncPrefixEnd >= 0) { 169 device = original.substring(0, uncPrefixEnd); 170 original = original.substring(uncPrefixEnd, original.length()); 171 } else 172 throw new IllegalArgumentException ("Not a valid UNC: " + original); } 175 } 176 if (original.charAt(0) == SEPARATOR) 178 flags |= HAS_LEADING; 179 if (original.charAt(original.length() - 1) == SEPARATOR) 180 flags |= HAS_TRAILING; 181 segments = computeSegments(original); 182 } 183 184 189 public boolean isAbsolute() { 190 return (flags & HAS_LEADING) != 0; 191 } 192 193 203 public String makeRelative(FilePath base) { 204 if (base.device != null && !base.device.equalsIgnoreCase(this.device)) 205 return base.toString(); 206 int baseCount = this.segments.length; 207 int count = this.matchingFirstSegments(base); 208 if (baseCount == count && count == base.segments.length) 209 return base.hasTrailingSlash() ? ("." + SEPARATOR) : "."; StringBuffer relative = new StringBuffer (); for (int j = 0; j < baseCount - count; j++) 212 relative.append(PARENT_DIR + SEPARATOR); 213 for (int i = 0; i < base.segments.length - count; i++) { 214 relative.append(base.segments[count + i]); 215 relative.append(SEPARATOR); 216 } 217 if (!base.hasTrailingSlash()) 218 relative.deleteCharAt(relative.length() - 1); 219 return relative.toString(); 220 } 221 222 226 private int matchingFirstSegments(FilePath anotherPath) { 227 int anotherPathLen = anotherPath.segments.length; 228 int max = Math.min(segments.length, anotherPathLen); 229 int count = 0; 230 for (int i = 0; i < max; i++) { 231 if (!segments[i].equals(anotherPath.segments[i])) 232 return count; 233 count++; 234 } 235 return count; 236 } 237 238 243 public String toString() { 244 StringBuffer result = new StringBuffer (); 245 if (device != null) 246 result.append(device); 247 if (isAbsolute()) 248 result.append(SEPARATOR); 249 for (int i = 0; i < segments.length; i++) { 250 result.append(segments[i]); 251 result.append(SEPARATOR); 252 } 253 if (segments.length > 0 && !hasTrailingSlash()) 254 result.deleteCharAt(result.length() - 1); 255 return result.toString(); 256 } 257 } 258 | Popular Tags |