KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > vfs > FilePath


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.vfs;
31
32 import com.caucho.util.CharBuffer;
33
34 import java.io.File JavaDoc;
35 import java.io.FileInputStream JavaDoc;
36 import java.io.FileNotFoundException JavaDoc;
37 import java.io.FileOutputStream JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.RandomAccessFile JavaDoc;
40 import java.util.Map JavaDoc;
41
42 /**
43  * FilePath implements the native filesystem.
44  */

45 public class FilePath extends FilesystemPath {
46   // The underlying Java File object.
47
private static byte []NEWLINE = getNewlineString().getBytes();
48
49   private static FilesystemPath PWD;
50   
51   private File JavaDoc _file;
52
53   /**
54    * @param path canonical path
55    */

56   protected FilePath(FilesystemPath root, String JavaDoc userPath, String JavaDoc path)
57   {
58     super(root, userPath, path);
59     
60     _separatorChar = getFileSeparatorChar();
61   }
62
63   public FilePath(String JavaDoc path)
64   {
65     this(null, //PWD != null ? PWD._root : null,
66
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 JavaDoc initialPath(String JavaDoc 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 JavaDoc 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   /**
97    * Gets the system's user dir (pwd) and convert it to the Resin format.
98    */

99   public static String JavaDoc getPwd()
100   {
101     String JavaDoc path = getUserDir();
102
103     path = path.replace(getFileSeparatorChar(), '/');
104
105     if (isWindows())
106       path = convertFromWindowsPath(path);
107
108     return path;
109   }
110
111   /**
112    * a:xxx -> /a:xxx
113    * ///a:xxx -> /a:xxx
114    * //xxx -> /:/xxx
115    *
116    */

117   private static String JavaDoc convertFromWindowsPath(String JavaDoc 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   /**
148    * Lookup the path, handling windows weirdness
149    */

150   protected Path schemeWalk(String JavaDoc userPath,
151                             Map JavaDoc<String JavaDoc,Object JavaDoc> attributes,
152                 String JavaDoc filePath,
153                             int offset)
154   {
155     if (! isWindows())
156       return super.schemeWalk(userPath, attributes, filePath, offset);
157     
158     String JavaDoc 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   /**
175    * Lookup the actual path relative to the filesystem root.
176    *
177    * @param userPath the user's path to lookup()
178    * @param attributes the user's attributes to lookup()
179    * @param path the normalized path
180    *
181    * @return the selected path
182    */

183   public Path fsWalk(String JavaDoc userPath,
184             Map JavaDoc<String JavaDoc,Object JavaDoc> attributes,
185             String JavaDoc path)
186   {
187     return new FilePath(_root, userPath, path);
188   }
189
190   public String JavaDoc getScheme()
191   {
192     return "file";
193   }
194
195   /**
196    * Returns the full url for the given path.
197    */

198   public String JavaDoc getURL()
199   {
200     return escapeURL("file:" + getFullPath());
201   }
202
203   /**
204    * Returns the native path.
205    */

206   public String JavaDoc getNativePath()
207   {
208     if (_separatorChar == '/' && ! isWindows())
209       return getFullPath();
210     
211     String JavaDoc path = getFullPath();
212     int length = path.length();
213     CharBuffer cb = CharBuffer.allocate();
214     char ch;
215     int offset = 0;
216     // For windows, convert /c: to c:
217
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   // This exists in JDK 1.2
296
public void setLastModified(long time)
297   {
298     getFile().setLastModified(time);
299   }
300
301   public boolean canRead()
302   {
303     File JavaDoc 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 JavaDoc file = getFile();
314     
315     if (_separatorChar == '\\' && isAux())
316       return false;
317     else
318       return file.canWrite();
319   }
320
321   /**
322    * Returns a list of files in the directory.
323    */

324   public String JavaDoc []list() throws IOException JavaDoc
325   {
326     String JavaDoc []list = getFile().list();
327
328     if (list != null)
329       return list;
330
331     return new String JavaDoc[0];
332   }
333   
334   public boolean mkdir()
335     throws IOException JavaDoc
336   {
337     boolean value = getFile().mkdir();
338     if (! value && ! getFile().isDirectory())
339       throw new IOException JavaDoc("cannot create directory");
340
341     return value;
342   }
343   
344   public boolean mkdirs()
345     throws IOException JavaDoc
346   {
347     File JavaDoc 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 JavaDoc("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       // XXX:
368
// Jar.create(this).clearCache();
369
return getFile().delete();
370     }
371
372     return false;
373   }
374   
375   public boolean truncate(long length)
376     throws IOException JavaDoc
377   {
378     File JavaDoc file = getFile();
379
380     FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(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   /**
402    * Returns the stream implementation for a read stream.
403    */

404   public StreamImpl openReadImpl() throws IOException JavaDoc
405   {
406     if (_separatorChar == '\\' && isAux())
407       throw new FileNotFoundException JavaDoc(_file.toString());
408
409     /* XXX: only for Solaris (?)
410     if (isDirectory())
411       throw new IOException("is directory");
412     */

413
414     return new FileReadStream(new FileInputStream JavaDoc(getFile()), this);
415   }
416
417   public StreamImpl openWriteImpl() throws IOException JavaDoc
418   {
419     VfsStream os;
420
421     os = new VfsStream(null, new FileOutputStream JavaDoc(getFile()), this);
422
423     os.setNewline(NEWLINE);
424
425     return os;
426   }
427
428   public StreamImpl openAppendImpl() throws IOException JavaDoc
429   {
430     FileOutputStream JavaDoc fos = null;
431
432     try {
433       fos = new FileOutputStream JavaDoc(getFile().toString(), true);
434     } catch (IOException JavaDoc e) {
435       // MacOS hack
436
fos = new FileOutputStream JavaDoc(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 JavaDoc
447   {
448     VfsStream os;
449
450     os = new VfsStream(new FileInputStream JavaDoc(getFile()),
451                        new FileOutputStream JavaDoc(getFile()),
452                        this);
453
454     os.setNewline(NEWLINE);
455     
456     return os;
457   }
458
459   /**
460    * Returns the stream implementation for a random-access stream.
461    */

462   public RandomAccessStream openRandomAccess() throws IOException JavaDoc
463   {
464     if (_separatorChar == '\\' && isAux())
465       throw new FileNotFoundException JavaDoc(_file.toString());
466
467     return new FileRandomAccessStream(new RandomAccessFile JavaDoc(getFile(), "rw"));
468   }
469
470   @Override JavaDoc
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 JavaDoc 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   /**
495    * Lazily returns the native File object.
496    */

497   public File JavaDoc getFile()
498   {
499     if (_file != null)
500       return _file;
501
502     if (com.caucho.util.Alarm.isTest())
503       _file = new File JavaDoc(getFullPath());
504     else
505       _file = new File JavaDoc(getNativePath());
506
507     return _file;
508   }
509
510   /**
511    * Special case for the evil windows special
512    */

513   protected boolean isAux()
514   {
515     File JavaDoc file = getFile();
516
517     String JavaDoc 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