001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.vfs;
031:
032: import com.caucho.util.L10N;
033:
034: import java.io.IOException;
035: import java.io.OutputStream;
036: import java.util.ArrayList;
037: import java.util.Iterator;
038: import java.util.Map;
039:
040: /**
041: * Wraps a path object.
042: */
043: public abstract class PathWrapper extends Path {
044: protected final static L10N L = new L10N(PathWrapper.class);
045:
046: private final Path _path;
047:
048: /**
049: * Creates a new Path object.
050: *
051: * @param path the new Path root.
052: */
053: protected PathWrapper(Path path) {
054: super (path);
055:
056: _path = path;
057: }
058:
059: /**
060: * Returns the wrapped path.
061: */
062: public Path getWrappedPath() {
063: return _path;
064: }
065:
066: /**
067: * Returns a new path relative to the current one.
068: *
069: * <p>Path only handles scheme:xxx. Subclasses of Path will specialize
070: * the xxx.
071: *
072: * @param userPath relative or absolute path, essentially any url.
073: * @param newAttributes attributes for the new path.
074: *
075: * @return the new path or null if the scheme doesn't exist
076: */
077: public Path lookup(String userPath,
078: Map<String, Object> newAttributes) {
079: return getWrappedPath().lookup(userPath, newAttributes);
080: }
081:
082: /**
083: * Returns a new path relative to the current one.
084: *
085: * <p>Path only handles scheme:xxx. Subclasses of Path will specialize
086: * the xxx.
087: *
088: * @param userPath relative or absolute path, essentially any url.
089: * @param newAttributes attributes for the new path.
090: *
091: * @return the new path or null if the scheme doesn't exist
092: */
093: public Path lookupImpl(String userPath,
094: Map<String, Object> newAttributes) {
095: return getWrappedPath().lookupImpl(userPath, newAttributes);
096: }
097:
098: /**
099: * Looks up a native path, adding attributes.
100: */
101: public Path lookupNative(String name, Map<String, Object> attributes) {
102: return getWrappedPath().lookupNative(name, attributes);
103: }
104:
105: /**
106: * Looks up all the resources matching a name. (Generally only useful
107: * with MergePath.
108: */
109: public ArrayList<Path> getResources(String name) {
110: return getWrappedPath().getResources(name);
111: }
112:
113: /**
114: * Looks up all the existing resources. (Generally only useful
115: * with MergePath.
116: */
117: public ArrayList<Path> getResources() {
118: return getWrappedPath().getResources();
119: }
120:
121: /**
122: * Returns the parent path.
123: */
124: public Path getParent() {
125: return getWrappedPath().getParent();
126: }
127:
128: /**
129: * Path-specific lookup. Path implementations will override this.
130: *
131: * @param userPath the user's lookup() path.
132: * @param newAttributes the attributes for the new path.
133: * @param newPath the lookup() path
134: * @param offset offset into newPath to start lookup.
135: *
136: * @return the found path
137: */
138: protected Path schemeWalk(String userPath,
139: Map<String, Object> newAttributes, String newPath,
140: int offset) {
141: return getWrappedPath().schemeWalk(userPath, newAttributes,
142: newPath, offset);
143: }
144:
145: /**
146: * Returns the full url for the given path.
147: */
148: public String getURL() {
149: return getWrappedPath().getURL();
150: }
151:
152: /**
153: * Returns the url scheme
154: */
155: public String getScheme() {
156: return getWrappedPath().getScheme();
157: }
158:
159: /**
160: * Returns the hostname
161: */
162: public String getHost() {
163: return getWrappedPath().getHost();
164: }
165:
166: /**
167: * Returns the port.
168: */
169: public int getPort() {
170: return getWrappedPath().getPort();
171: }
172:
173: /**
174: * Returns the path. e.g. for HTTP, returns the part after the
175: * host and port.
176: */
177: public String getPath() {
178: return getWrappedPath().getPath();
179: }
180:
181: /**
182: * Returns the last segment of the path.
183: *
184: * <p>e.g. for http://www.caucho.com/products/index.html, getTail()
185: * returns 'index.html'
186: */
187: public String getTail() {
188: return getWrappedPath().getTail();
189: }
190:
191: /**
192: * Returns the query string of the path.
193: */
194: public String getQuery() {
195: return getWrappedPath().getQuery();
196: }
197:
198: /**
199: * Returns the native representation of the path.
200: *
201: * On Windows, getNativePath() returns 'd:\\foo\bar.html',
202: * getPath() returns '/d:/foo/bar.html'
203: */
204: public String getNativePath() {
205: return getWrappedPath().getNativePath();
206: }
207:
208: /**
209: * Returns the last string used as a lookup, if available. This allows
210: * parsers to give intelligent error messages, with the user's path
211: * instead of the whole path.
212: *
213: * The following will print '../test.html':
214: * <code><pre>
215: * Path path = Pwd.lookup("/some/dir").lookup("../test.html");
216: * System.out.println(path.getUserPath());
217: * </pre></code>
218: *
219: */
220: public String getUserPath() {
221: return getWrappedPath().getUserPath();
222: }
223:
224: /**
225: * Sets the user path. Useful for temporary files caching another
226: * URL.
227: */
228: public void setUserPath(String userPath) {
229: getWrappedPath().setUserPath(userPath);
230: }
231:
232: /**
233: * Returns the full path, including the restricted root.
234: *
235: * <p>For the following, path.getPath() returns '/file.html', while
236: * path.getFullPath() returns '/chroot/file.html'.
237: * <code><pre>
238: * Path chroot = Pwd.lookup("/chroot").createRoot();
239: * Path path = chroot.lookup("/file.html");
240: * </pre></code>
241: */
242: public String getFullPath() {
243: return getWrappedPath().getFullPath();
244: }
245:
246: /**
247: * For union paths like MergePath, return the relative path into
248: * that path.
249: */
250: public String getRelativePath() {
251: return getWrappedPath().getRelativePath();
252: }
253:
254: /**
255: * Tests if the file exists.
256: */
257: public boolean exists() {
258: return getWrappedPath().exists();
259: }
260:
261: /**
262: * Returns the mime-type of the file.
263: * <p>Mime-type ignorant filesystems return 'application/octet-stream'
264: */
265: public String getContentType() {
266: return getWrappedPath().getContentType();
267: }
268:
269: /**
270: * Tests if the path refers to a directory.
271: */
272: public boolean isDirectory() {
273: return getWrappedPath().isDirectory();
274: }
275:
276: /**
277: * Tests if the path refers to a file.
278: */
279: public boolean isFile() {
280: return getWrappedPath().isFile();
281: }
282:
283: /**
284: * Tests if the path refers to an object.
285: */
286: public boolean isObject() {
287: return getWrappedPath().isObject();
288: }
289:
290: /**
291: * Returns the length of the file in bytes.
292: * @return 0 for non-files
293: */
294: public long getLength() {
295: return getWrappedPath().getLength();
296: }
297:
298: /**
299: * Returns the last modified time of the file. According to the jdk,
300: * this may not correspond to the system time.
301: * @return 0 for non-files.
302: */
303: public long getLastModified() {
304: return getWrappedPath().getLastModified();
305: }
306:
307: public void setLastModified(long time) {
308: getWrappedPath().setLastModified(time);
309: }
310:
311: /**
312: * Returns the last access time of the file.
313: *
314: * @return 0 for non-files.
315: */
316: public long getLastAccessTime() {
317: return getWrappedPath().getLastAccessTime();
318: }
319:
320: /**
321: * Returns the create time of the file.
322: *
323: * @return 0 for non-files.
324: */
325: public long getCreateTime() {
326: return getWrappedPath().getCreateTime();
327: }
328:
329: /**
330: * Tests if the file can be read.
331: */
332: public boolean canRead() {
333: return getWrappedPath().canRead();
334: }
335:
336: /**
337: * Tests if the file can be written.
338: */
339: public boolean canWrite() {
340: return getWrappedPath().canWrite();
341: }
342:
343: /**
344: * Changes the permissions
345: */
346: public boolean chmod(int value) {
347: return getWrappedPath().chmod(value);
348: }
349:
350: /**
351: * @return The contents of this directory or null if the path does not
352: * refer to a directory.
353: */
354: public String[] list() throws IOException {
355: return getWrappedPath().list();
356: }
357:
358: /**
359: * Returns a jdk1.2 Iterator for the contents of this directory.
360: */
361: public Iterator<String> iterator() throws IOException {
362: return getWrappedPath().iterator();
363: }
364:
365: /**
366: * Creates the directory named by this path.
367: * @return true if successful.
368: */
369: public boolean mkdir() throws IOException {
370: return getWrappedPath().mkdir();
371: }
372:
373: /**
374: * Creates the directory named by this path and any parent directories.
375: * @return true if successful.
376: */
377: public boolean mkdirs() throws IOException {
378: return getWrappedPath().mkdirs();
379: }
380:
381: /**
382: * Removes the file or directory named by this path.
383: * @return true if successful.
384: */
385: public boolean remove() throws IOException {
386: return getWrappedPath().remove();
387: }
388:
389: /**
390: * Removes the all files and directories below this path.
391: *
392: * @return true if successful.
393: */
394: public boolean removeAll() throws IOException {
395: return getWrappedPath().removeAll();
396: }
397:
398: /**
399: * Renames the file or directory to the name given by the path.
400: * @return true if successful
401: */
402: public boolean renameTo(Path path) throws IOException {
403: return getWrappedPath().renameTo(path);
404: }
405:
406: /**
407: * Creates a restricted root, like the Unix chroot call.
408: * Restricted roots cannot access schemes, so file:/etc/passwd cannot
409: * be used.
410: *
411: * <p>createRoot is useful for restricting JavaScript scripts without
412: * resorting to the dreadfully slow security manager.
413: */
414: public Path createRoot() {
415: return getWrappedPath().createRoot();
416: }
417:
418: public Path createRoot(SchemeMap schemeMap) {
419: return getWrappedPath().createRoot(schemeMap);
420: }
421:
422: /**
423: * Binds the context to the current path. Later lookups will return
424: * the new context instead of the current path. Essentially, this is a
425: * software symbolic link.
426: */
427: public void bind(Path context) {
428: getWrappedPath().bind(context);
429: }
430:
431: /**
432: * unbinds a link.
433: */
434: public void unbind() {
435: getWrappedPath().unbind();
436: }
437:
438: /**
439: * Gets the object at the path. Normal filesystems will generally
440: * typically return null.
441: *
442: * <p>A bean filesystem or a mime-type aware filesystem could deserialize
443: * the contents of the file.
444: */
445: public Object getValue() throws Exception {
446: return getWrappedPath().getValue();
447: }
448:
449: /**
450: * Sets the object at the path.
451: *
452: * <p>Normal filesystems will generally do nothing. However, a bean
453: * filesystem or a mime-type aware filesystem could serialize the object
454: * and store it.
455: */
456: public void setValue(Object obj) throws Exception {
457: getWrappedPath().setValue(obj);
458: }
459:
460: /**
461: * Gets an attribute of the object.
462: */
463: public Object getAttribute(String name) throws IOException {
464: return getWrappedPath().getAttribute(name);
465: }
466:
467: /**
468: * Returns a iterator of all attribute names set for this object.
469: * @return null if path has no attributes.
470: */
471: public Iterator getAttributeNames() throws IOException {
472: return getWrappedPath().getAttributeNames();
473: }
474:
475: /**
476: * Opens a resin ReadWritePair for reading and writing.
477: *
478: * <p>A chat channel, for example, would open its socket using this
479: * interface.
480: */
481: public ReadWritePair openReadWrite() throws IOException {
482: return getWrappedPath().openReadWrite();
483: }
484:
485: /**
486: * Opens a resin ReadWritePair for reading and writing.
487: *
488: * <p>A chat channel, for example, would open its socket using this
489: * interface.
490: *
491: * @param is pre-allocated ReadStream to be initialized
492: * @param os pre-allocated WriteStream to be initialized
493: */
494: public void openReadWrite(ReadStream is, WriteStream os)
495: throws IOException {
496: getWrappedPath().openReadWrite(is, os);
497: }
498:
499: /**
500: * Opens a resin stream for appending.
501: */
502: public WriteStream openAppend() throws IOException {
503: return getWrappedPath().openAppend();
504: }
505:
506: /**
507: * Opens a random-access stream.
508: */
509: public RandomAccessStream openRandomAccess() throws IOException {
510: return getWrappedPath().openRandomAccess();
511: }
512:
513: /**
514: * Creates the file named by this Path and returns true if the
515: * file is new.
516: */
517: public boolean createNewFile() throws IOException {
518: return getWrappedPath().createNewFile();
519: }
520:
521: /**
522: * Creates a unique temporary file as a child of this directory.
523: *
524: * @param prefix filename prefix
525: * @param suffix filename suffix, defaults to .tmp
526: * @return Path to the new file.
527: */
528: public Path createTempFile(String prefix, String suffix)
529: throws IOException {
530: return getWrappedPath().createTempFile(prefix, suffix);
531: }
532:
533: /**
534: * Utility to write the contents of this path to the destination stream.
535: *
536: * @param os destination stream.
537: */
538: public void writeToStream(OutputStream os) throws IOException {
539: getWrappedPath().writeToStream(os);
540: }
541:
542: /**
543: * Utility to write the contents of this path to the destination stream.
544: *
545: * @param os destination stream.
546: */
547: public void writeToStream(OutputStreamWithBuffer os)
548: throws IOException {
549: getWrappedPath().writeToStream(os);
550: }
551:
552: /**
553: * Returns the crc64 code.
554: */
555: public long getCrc64() {
556: return getWrappedPath().getCrc64();
557: }
558:
559: /**
560: * Returns the object at this path. Normally, only paths like JNDI
561: * will support this.
562: */
563: public Object getObject() throws IOException {
564: return getWrappedPath().getObject();
565: }
566:
567: /**
568: * Sets the object at this path. Normally, only paths like JNDI
569: * will support this.
570: */
571: public void setObject(Object obj) throws IOException {
572: getWrappedPath().setObject(obj);
573: }
574:
575: public long getInode() {
576: return getWrappedPath().getInode();
577: }
578:
579: public boolean isExecutable() {
580: return getWrappedPath().isExecutable();
581: }
582:
583: public boolean setExecutable(boolean isExecutable) {
584: return getWrappedPath().setExecutable(isExecutable);
585: }
586:
587: public int getGroup() {
588: return getWrappedPath().getGroup();
589: }
590:
591: public boolean changeGroup(int gid) throws IOException {
592: return getWrappedPath().changeGroup(gid);
593: }
594:
595: public boolean changeGroup(String groupName) throws IOException {
596: return getWrappedPath().changeGroup(groupName);
597: }
598:
599: public int getOwner() {
600: return getWrappedPath().getOwner();
601: }
602:
603: public boolean changeOwner(int uid) throws IOException {
604: return getWrappedPath().changeOwner(uid);
605: }
606:
607: public boolean changeOwner(String ownerName) throws IOException {
608: return getWrappedPath().changeOwner(ownerName);
609: }
610:
611: public long getDiskSpaceFree() {
612: return getWrappedPath().getDiskSpaceFree();
613: }
614:
615: public long getDiskSpaceTotal() {
616: return getWrappedPath().getDiskSpaceTotal();
617: }
618:
619: public int hashCode() {
620: return getWrappedPath().hashCode();
621: }
622:
623: public boolean equals(Object o) {
624: return o.equals(getWrappedPath());
625: }
626:
627: public String toString() {
628: return getWrappedPath().toString();
629: }
630:
631: public StreamImpl openReadImpl() throws IOException {
632: return getWrappedPath().openReadImpl();
633: }
634:
635: public StreamImpl openWriteImpl() throws IOException {
636: return getWrappedPath().openWriteImpl();
637: }
638:
639: public StreamImpl openReadWriteImpl() throws IOException {
640: return getWrappedPath().openReadWriteImpl();
641: }
642:
643: public StreamImpl openAppendImpl() throws IOException {
644: return getWrappedPath().openAppendImpl();
645: }
646: }
|