KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.Map JavaDoc;
35
36 /**
37  * Abstract FilesystemPath, the parent of hierarchical Paths like
38  * FilePath or HttpPath.
39  */

40 abstract public class FilesystemPath extends Path {
41   protected FilesystemPath _root;
42   protected BindPath _bindRoot;
43   protected String JavaDoc _pathname;
44   protected String JavaDoc _userPath;
45
46   /**
47    * Create a new filesystemPath
48    *
49    * @param root Root of url space
50    * @param userPath the user's path
51    * @param pathname Canonical path
52    */

53   protected FilesystemPath(FilesystemPath root,
54                            String JavaDoc userPath,
55                String JavaDoc pathname)
56   {
57     super(root);
58
59     if (pathname == null)
60       throw new NullPointerException JavaDoc();
61
62     _pathname = pathname;
63     _userPath = userPath;
64
65     if (root != null) {
66       _root = root;
67       _bindRoot = root._bindRoot;
68     }
69   }
70
71   /**
72    * Return the parent Path
73    */

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   /**
95    * schemeWalk is called by Path for a scheme lookup like file:/tmp/foo
96    *
97    * @param userPath the user's lookup() path
98    * @param attributes the user's attributes
99    * @param filePath the actual lookup() path
100    * @param offset offset into filePath
101    */

102   protected Path schemeWalk(String JavaDoc userPath,
103                             Map JavaDoc<String JavaDoc,Object JavaDoc> attributes,
104                 String JavaDoc filePath,
105                             int offset)
106   {
107     String JavaDoc 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   /**
122    * Lookup a path relative to the current filesystem's root.
123    * Filesystems will specialize fsWalk.
124    *
125    * @param userPath the exact string passed by the user's lookup()
126    * @param newAttributes the user's new attributes
127    * @param newPath the normalized real path
128    *
129    * @return the matching path
130    */

131   abstract public Path fsWalk(String JavaDoc userPath,
132                                  Map JavaDoc<String JavaDoc,Object JavaDoc> newAttributes,
133                  String JavaDoc newPath);
134
135   /**
136    * wrapper for the real normalize path routine to use CharBuffer.
137    *
138    * @param oldPath The parent Path's path
139    * @param newPath The user's new path
140    * @param offset Offset into the user path
141    *
142    * @return the normalized path
143    */

144   static protected String JavaDoc normalizePath(String JavaDoc oldPath,
145                                         String JavaDoc 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   /**
155    * Normalizes a filesystemPath path.
156    *
157    * <ul>
158    * <li>foo//bar -> foo/bar
159    * <li>foo/./bar -> foo/bar
160    * <li>foo/../bar -> bar
161    * <li>/../bar -> /bar
162    * </ul>
163    *
164    * @param cb charBuffer holding the normalized result
165    * @param oldPath the parent path
166    * @param newPath the relative path
167    * @param offset where in the child path to start
168    */

169   static protected void normalizePath(CharBuffer cb, String JavaDoc oldPath,
170                                       String JavaDoc 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         // the separator character falls through to be treated as '/'
192

193       case '/':
194         // "//" -> "/"
195
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         // "/." -> ""
208
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           // the separator falls through to be treated as '/'
221

222           // "/./" -> "/"
223
case '/':
224           i += 2;
225           break;
226
227           // "foo/.." -> ""
228
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     // strip trailing "/"
251
/*
252     if (cb.length() > 1 && cb.getLastChar() == '/')
253       cb.setLength(cb.length() - 1);
254     */

255   }
256
257   /**
258    * Returns the root.
259    */

260   protected FilesystemPath getRoot()
261   {
262     return _root;
263   }
264
265   /**
266    * Returns the path portion of the URL.
267    */

268   public String JavaDoc getPath()
269   {
270     return _pathname;
271   }
272
273   /**
274    * Return's the application's name for the path, e.g. for
275    * a relative path.
276    */

277   public String JavaDoc getUserPath()
278   {
279     return _userPath != null ? _userPath : _pathname;
280   }
281
282   public void setUserPath(String JavaDoc path)
283   {
284     _userPath = path;
285   }
286
287   /**
288    * For chrooted filesystems return the real system path.
289    */

290   public String JavaDoc getFullPath()
291   {
292     if (_root == this)
293       return getPath();
294
295     String JavaDoc rootPath = _root.getFullPath();
296     String JavaDoc 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 JavaDoc getTail()
307   {
308     String JavaDoc 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   /**
325    * Essentially chroot
326    */

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 JavaDoc 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 JavaDoc toString()
370   {
371     return getPath();
372   }
373 }
374
Popular Tags