1 29 30 package com.caucho.vfs; 31 32 import com.caucho.util.CharBuffer; 33 34 import java.util.Map ; 35 36 40 abstract public class FilesystemPath extends Path { 41 protected FilesystemPath _root; 42 protected BindPath _bindRoot; 43 protected String _pathname; 44 protected String _userPath; 45 46 53 protected FilesystemPath(FilesystemPath root, 54 String userPath, 55 String pathname) 56 { 57 super(root); 58 59 if (pathname == null) 60 throw new NullPointerException (); 61 62 _pathname = pathname; 63 _userPath = userPath; 64 65 if (root != null) { 66 _root = root; 67 _bindRoot = root._bindRoot; 68 } 69 } 70 71 74 public Path getParent() 75 { 76 if (_pathname.length() <= 1) 77 return fsWalk("/", null, "/"); 78 79 int length = _pathname.length(); 80 int lastSlash = _pathname.lastIndexOf('/'); 81 82 if (lastSlash < 1) 83 return fsWalk("/", null, "/"); 84 85 if (lastSlash == length - 1) { 86 lastSlash = _pathname.lastIndexOf('/', length - 2); 87 if (lastSlash < 1) 88 return fsWalk("/", null, "/"); 89 } 90 91 return fsWalk("..", null, _pathname.substring(0, lastSlash)); 92 } 93 94 102 protected Path schemeWalk(String userPath, 103 Map <String ,Object > attributes, 104 String filePath, 105 int offset) 106 { 107 String canonicalPath; 108 109 if (filePath.length() > offset && 110 (filePath.charAt(offset) == '/' || 111 filePath.charAt(offset) == _separatorChar)) 112 canonicalPath = normalizePath("/", filePath, offset, _separatorChar); 113 else 114 canonicalPath = normalizePath(_pathname, filePath, offset, 115 _separatorChar); 116 117 118 return fsWalk(userPath, attributes, canonicalPath); 119 } 120 121 131 abstract public Path fsWalk(String userPath, 132 Map <String ,Object > newAttributes, 133 String newPath); 134 135 144 static protected String normalizePath(String oldPath, 145 String newPath, 146 int offset, 147 char separatorChar) 148 { 149 CharBuffer cb = new CharBuffer(); 150 normalizePath(cb, oldPath, newPath, offset, separatorChar); 151 return cb.toString(); 152 } 153 154 169 static protected void normalizePath(CharBuffer cb, String oldPath, 170 String newPath, int offset, 171 char separatorChar) 172 { 173 cb.clear(); 174 cb.append(oldPath); 175 if (cb.length() == 0 || cb.getLastChar() != '/') 176 cb.append('/'); 177 178 int length = newPath.length(); 179 int i = offset; 180 while (i < length) { 181 char ch = newPath.charAt(i); 182 char ch2; 183 184 switch (ch) { 185 default: 186 if (ch != separatorChar) { 187 cb.append(ch); 188 i++; 189 break; 190 } 191 193 case '/': 194 if (cb.getLastChar() != '/') 196 cb.append('/'); 197 i++; 198 break; 199 200 case '.': 201 if (cb.getLastChar() != '/') { 202 cb.append('.'); 203 i++; 204 break; 205 } 206 207 if (i + 1 >= length) { 209 i += 2; 210 break; 211 } 212 213 switch (newPath.charAt(i + 1)) { 214 default: 215 if (newPath.charAt(i + 1) != separatorChar) { 216 cb.append('.'); 217 i++; 218 break; 219 } 220 222 case '/': 224 i += 2; 225 break; 226 227 case '.': 229 if ((i + 2 >= length || 230 (ch2 = newPath.charAt(i + 2)) == '/' || ch2 == separatorChar) && 231 cb.getLastChar() == '/') { 232 int segment = cb.lastIndexOf('/', cb.length() - 2); 233 if (segment == -1) { 234 cb.clear(); 235 cb.append('/'); 236 } else 237 cb.setLength(segment + 1); 238 239 i += 3; 240 } else { 241 cb.append('.'); 242 i++; 243 } 244 break; 245 } 246 } 247 248 } 249 250 255 } 256 257 260 protected FilesystemPath getRoot() 261 { 262 return _root; 263 } 264 265 268 public String getPath() 269 { 270 return _pathname; 271 } 272 273 277 public String getUserPath() 278 { 279 return _userPath != null ? _userPath : _pathname; 280 } 281 282 public void setUserPath(String path) 283 { 284 _userPath = path; 285 } 286 287 290 public String getFullPath() 291 { 292 if (_root == this) 293 return getPath(); 294 295 String rootPath = _root.getFullPath(); 296 String path = getPath(); 297 298 if (rootPath.length() <= 1) 299 return path; 300 else if (path.length() <= 1) 301 return rootPath; 302 else 303 return rootPath + path; 304 } 305 306 public String getTail() 307 { 308 String path = getPath(); 309 310 int length = path.length(); 311 int p = path.lastIndexOf('/'); 312 if (p == -1) 313 return ""; 314 else if (p < length - 1) 315 return path.substring(p + 1); 316 else { 317 p = path.lastIndexOf('/', length - 2); 318 if (p < 0) 319 return ""; 320 return path.substring(p + 1, length - 1); 321 } 322 } 323 324 327 public Path createRoot(SchemeMap schemeMap) 328 { 329 FilesystemPath restriction = (FilesystemPath) copy(); 330 331 restriction._schemeMap = schemeMap; 332 restriction._root = this; 333 restriction._pathname = "/"; 334 restriction._userPath = "/"; 335 336 return restriction; 337 } 338 339 public void bind(Path context) 340 { 341 if (_bindRoot == null) 342 _bindRoot = _root._bindRoot; 343 344 if (_bindRoot == null) { 345 _bindRoot = new BindPath(_root); 346 _root._bindRoot = _bindRoot; 347 } 348 349 _bindRoot.bind(getPath(), context); 350 } 351 352 public int hashCode() 353 { 354 return getURL().hashCode(); 355 } 356 357 public boolean equals(Object b) 358 { 359 if (this == b) 360 return true; 361 else if (b == null || ! getClass().equals(b.getClass())) 362 return false; 363 364 Path bPath = (Path) b; 365 366 return getURL().equals(bPath.getURL()); 367 } 368 369 public String toString() 370 { 371 return getPath(); 372 } 373 } 374 | Popular Tags |