1 29 30 package com.caucho.vfs; 31 32 import com.caucho.util.CharBuffer; 33 34 import java.io.File ; 35 import java.io.FileInputStream ; 36 import java.io.FileNotFoundException ; 37 import java.io.FileOutputStream ; 38 import java.io.IOException ; 39 import java.io.RandomAccessFile ; 40 import java.util.Map ; 41 42 45 public class FilePath extends FilesystemPath { 46 private static byte []NEWLINE = getNewlineString().getBytes(); 48 49 private static FilesystemPath PWD; 50 51 private File _file; 52 53 56 protected FilePath(FilesystemPath root, String userPath, String path) 57 { 58 super(root, userPath, path); 59 60 _separatorChar = getFileSeparatorChar(); 61 } 62 63 public FilePath(String path) 64 { 65 this(null, path, normalizePath("/", initialPath(path), 67 0, getFileSeparatorChar())); 68 69 if (_root == null) { 70 _root = new FilePath(null, "/", "/"); 71 _root._root = _root; 72 73 if (PWD == null) 74 PWD = _root; 75 } 76 77 _separatorChar = _root._separatorChar; 78 } 79 80 protected static String initialPath(String path) 81 { 82 if (path == null) 83 return getPwd(); 84 else if (path.length() > 0 && path.charAt(0) == '/') 85 return path; 86 else { 87 String dir = getPwd(); 88 89 if (dir.length() > 0 && dir.charAt(dir.length() - 1) == '/') 90 return dir + path; 91 else 92 return dir + "/" + path; 93 } 94 } 95 96 99 public static String getPwd() 100 { 101 String path = getUserDir(); 102 103 path = path.replace(getFileSeparatorChar(), '/'); 104 105 if (isWindows()) 106 path = convertFromWindowsPath(path); 107 108 return path; 109 } 110 111 117 private static String convertFromWindowsPath(String path) 118 { 119 int colon = path.indexOf(':'); 120 int length = path.length(); 121 char ch; 122 123 if (colon == 1 && (ch = path.charAt(0)) != '/' && ch != '\\') 124 return "/" + path.charAt(0) + ":/" + path.substring(2); 125 else if (length > 1 && 126 ((ch = path.charAt(0)) == '/' || ch == '\\') && 127 ((ch = path.charAt(1)) == '/' || ch == '\\')) { 128 if (colon < 0) 129 return "/:" + path; 130 131 for (int i = colon - 2; i > 1; i--) { 132 if ((ch = path.charAt(i)) != '/' && ch != '\\') 133 return "/:" + path; 134 } 135 136 ch = path.charAt(colon - 1); 137 138 if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') 139 return path.substring(colon - 2); 140 else 141 return "/:" + path; 142 } 143 else 144 return path; 145 } 146 147 150 protected Path schemeWalk(String userPath, 151 Map <String ,Object > attributes, 152 String filePath, 153 int offset) 154 { 155 if (! isWindows()) 156 return super.schemeWalk(userPath, attributes, filePath, offset); 157 158 String canonicalPath; 159 160 if (filePath.length() < offset + 2) 161 return super.schemeWalk(userPath, attributes, filePath, offset); 162 163 char ch1 = filePath.charAt(offset + 1); 164 char ch2 = filePath.charAt(offset); 165 166 if ((ch2 == '/' || ch2 == _separatorChar) && 167 (ch1 == '/' || ch1 == _separatorChar)) 168 return super.schemeWalk(userPath, attributes, 169 convertFromWindowsPath(filePath.substring(offset)), 0); 170 else 171 return super.schemeWalk(userPath, attributes, filePath, offset); 172 } 173 174 183 public Path fsWalk(String userPath, 184 Map <String ,Object > attributes, 185 String path) 186 { 187 return new FilePath(_root, userPath, path); 188 } 189 190 public String getScheme() 191 { 192 return "file"; 193 } 194 195 198 public String getURL() 199 { 200 return escapeURL("file:" + getFullPath()); 201 } 202 203 206 public String getNativePath() 207 { 208 if (_separatorChar == '/' && ! isWindows()) 209 return getFullPath(); 210 211 String path = getFullPath(); 212 int length = path.length(); 213 CharBuffer cb = CharBuffer.allocate(); 214 char ch; 215 int offset = 0; 216 if (isWindows()) { 218 if (length >= 3 && 219 path.charAt(0) == '/' && 220 path.charAt(2) == ':' && 221 ((ch = path.charAt(1)) >= 'a' && ch <= 'z' || 222 ch >= 'A' && ch <= 'Z')) { 223 offset = 1; 224 } 225 else if (length >= 3 && 226 path.charAt(0) == '/' && 227 path.charAt(1) == ':' && 228 path.charAt(2) == '/') { 229 cb.append('\\'); 230 cb.append('\\'); 231 offset = 3; 232 } 233 } 234 235 for (; offset < length; offset++) { 236 ch = path.charAt(offset); 237 if (ch == '/') 238 cb.append(_separatorChar); 239 else 240 cb.append(ch); 241 } 242 243 return cb.close(); 244 } 245 246 public boolean exists() 247 { 248 if (_separatorChar == '\\' && isAux()) 249 return false; 250 else 251 return getFile().exists(); 252 } 253 254 public int getMode() 255 { 256 int perms = 0; 257 258 if (isDirectory()) { 259 perms += 01000; 260 perms += 0111; 261 } 262 263 if (canRead()) 264 perms += 0444; 265 266 if (canWrite()) 267 perms += 0222; 268 269 return perms; 270 } 271 272 public boolean isDirectory() 273 { 274 return getFile().isDirectory(); 275 } 276 277 public boolean isFile() 278 { 279 if (_separatorChar == '\\' && isAux()) 280 return false; 281 else 282 return getFile().isFile(); 283 } 284 285 public long getLength() 286 { 287 return getFile().length(); 288 } 289 290 public long getLastModified() 291 { 292 return getFile().lastModified(); 293 } 294 295 public void setLastModified(long time) 297 { 298 getFile().setLastModified(time); 299 } 300 301 public boolean canRead() 302 { 303 File file = getFile(); 304 305 if (_separatorChar == '\\' && isAux()) 306 return false; 307 else 308 return file.canRead(); 309 } 310 311 public boolean canWrite() 312 { 313 File file = getFile(); 314 315 if (_separatorChar == '\\' && isAux()) 316 return false; 317 else 318 return file.canWrite(); 319 } 320 321 324 public String []list() throws IOException 325 { 326 String []list = getFile().list(); 327 328 if (list != null) 329 return list; 330 331 return new String [0]; 332 } 333 334 public boolean mkdir() 335 throws IOException 336 { 337 boolean value = getFile().mkdir(); 338 if (! value && ! getFile().isDirectory()) 339 throw new IOException ("cannot create directory"); 340 341 return value; 342 } 343 344 public boolean mkdirs() 345 throws IOException 346 { 347 File file = getFile(); 348 349 boolean value; 350 351 synchronized (file) { 352 value = file.mkdirs(); 353 } 354 355 if (! value && ! file.isDirectory()) 356 throw new IOException ("Cannot create directory: " + getFile()); 357 358 return value; 359 } 360 361 public boolean remove() 362 { 363 if (getFile().delete()) 364 return true; 365 366 if (getPath().endsWith(".jar")) { 367 return getFile().delete(); 370 } 371 372 return false; 373 } 374 375 public boolean truncate(long length) 376 throws IOException 377 { 378 File file = getFile(); 379 380 FileOutputStream fos = new FileOutputStream (file); 381 382 try { 383 fos.getChannel().truncate(length); 384 385 return true; 386 } finally { 387 fos.close(); 388 } 389 } 390 391 public boolean renameTo(Path path) 392 { 393 if (! (path instanceof FilePath)) 394 return false; 395 396 FilePath file = (FilePath) path; 397 398 return this.getFile().renameTo(file.getFile()); 399 } 400 401 404 public StreamImpl openReadImpl() throws IOException 405 { 406 if (_separatorChar == '\\' && isAux()) 407 throw new FileNotFoundException (_file.toString()); 408 409 413 414 return new FileReadStream(new FileInputStream (getFile()), this); 415 } 416 417 public StreamImpl openWriteImpl() throws IOException 418 { 419 VfsStream os; 420 421 os = new VfsStream(null, new FileOutputStream (getFile()), this); 422 423 os.setNewline(NEWLINE); 424 425 return os; 426 } 427 428 public StreamImpl openAppendImpl() throws IOException 429 { 430 FileOutputStream fos = null; 431 432 try { 433 fos = new FileOutputStream (getFile().toString(), true); 434 } catch (IOException e) { 435 fos = new FileOutputStream (getFile().toString()); 437 } 438 439 VfsStream os = new VfsStream(null, fos); 440 441 os.setNewline(NEWLINE); 442 443 return os; 444 } 445 446 public StreamImpl openReadWriteImpl() throws IOException 447 { 448 VfsStream os; 449 450 os = new VfsStream(new FileInputStream (getFile()), 451 new FileOutputStream (getFile()), 452 this); 453 454 os.setNewline(NEWLINE); 455 456 return os; 457 } 458 459 462 public RandomAccessStream openRandomAccess() throws IOException 463 { 464 if (_separatorChar == '\\' && isAux()) 465 throw new FileNotFoundException (_file.toString()); 466 467 return new FileRandomAccessStream(new RandomAccessFile (getFile(), "rw")); 468 } 469 470 @Override 471 protected Path copy() 472 { 473 return new FilePath(getRoot(), getUserPath(), getPath()); 474 } 475 476 public int hashCode() 477 { 478 return getFullPath().hashCode(); 479 } 480 481 public boolean equals(Object b) 482 { 483 if (this == b) 484 return true; 485 486 if (! (b instanceof FilePath)) 487 return false; 488 489 FilePath file = (FilePath) b; 490 491 return getFullPath().equals(file.getFullPath()); 492 } 493 494 497 public File getFile() 498 { 499 if (_file != null) 500 return _file; 501 502 if (com.caucho.util.Alarm.isTest()) 503 _file = new File (getFullPath()); 504 else 505 _file = new File (getNativePath()); 506 507 return _file; 508 } 509 510 513 protected boolean isAux() 514 { 515 File file = getFile(); 516 517 String path = getFullPath().toLowerCase(); 518 519 int len = path.length(); 520 int p = path.indexOf("/aux"); 521 int ch; 522 if (p >= 0 && (p + 4 >= len || path.charAt(p + 4) == '.')) 523 return true; 524 525 p = path.indexOf("/con"); 526 if (p >= 0 && (p + 4 >= len || path.charAt(p + 4) == '.')) 527 return true; 528 529 p = path.indexOf("/nul"); 530 if (p >= 0 && (p + 4 >= len || path.charAt(p + 4) == '.')) 531 return true; 532 533 return false; 534 } 535 } 536 | Popular Tags |