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: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.vfs;
030:
031: import java.io.IOException;
032: import java.util.Map;
033:
034: class BindPath extends FilesystemPath {
035: private Node _node;
036: private Path _backing;
037:
038: BindPath(Path backing) {
039: this (null, "/", null, "/", null, backing);
040:
041: _root = this ;
042: if (backing instanceof FilesystemPath)
043: _separatorChar = ((FilesystemPath) backing)._separatorChar;
044: }
045:
046: /**
047: * @param path canonical path
048: */
049: private BindPath(BindPath root, String userPath,
050: Map<String, Object> attributes, String path, Node node,
051: Path backing) {
052: super (root, userPath, path);
053:
054: if (backing == null)
055: throw new IllegalArgumentException(
056: "backing must not be null");
057:
058: if (node == null)
059: node = new Node("", backing);
060:
061: if (backing == null)
062: backing = node._backing;
063:
064: _node = node;
065: _backing = backing;
066:
067: if (backing instanceof FilesystemPath)
068: _separatorChar = ((FilesystemPath) backing)._separatorChar;
069: }
070:
071: public Path fsWalk(String userPath, Map<String, Object> attributes,
072: String path) {
073: Node ptr = _node;
074:
075: int offset = 0;
076: while (offset + 1 < path.length()) {
077: if (ptr.firstChild == null)
078: return ptr._backing.lookup(path.substring(offset),
079: attributes);
080:
081: int p = path.indexOf(_separatorChar, offset + 1);
082: String segment;
083: if (p == -1)
084: segment = path.substring(offset + 1);
085: else
086: segment = path.substring(offset + 1, p);
087:
088: Node next = ptr.findChild(segment);
089:
090: if (next == null)
091: return ptr._backing.lookup(path.substring(offset),
092: attributes);
093:
094: offset = p;
095: ptr = next;
096: }
097:
098: return new BindPath(this , userPath, attributes, path, _node,
099: null);
100: }
101:
102: public String getScheme() {
103: return _root.getScheme();
104: }
105:
106: public boolean exists() {
107: return _backing.exists();
108: }
109:
110: public boolean isDirectory() {
111: return _backing.isDirectory();
112: }
113:
114: public boolean isFile() {
115: return _backing.isFile();
116: }
117:
118: public long getLength() {
119: return _backing.getLength();
120: }
121:
122: public long getLastModified() {
123: return _backing.getLastModified();
124: }
125:
126: public boolean canRead() {
127: return _backing.canRead();
128: }
129:
130: public boolean canWrite() {
131: return _backing.canWrite();
132: }
133:
134: public String[] list() throws IOException {
135: String[] list = _backing.list();
136:
137: if (_node.firstChild == null)
138: return list;
139:
140: String[] newList = new String[list.length + _node.size()];
141:
142: int i = 0;
143: for (Node ptr = _node.firstChild; ptr != null; ptr = ptr.next)
144: newList[i++] = ptr.name;
145:
146: for (int j = 0; j < list.length; j++)
147: newList[i++] = list[j++];
148:
149: return newList;
150: }
151:
152: public boolean mkdir() throws IOException {
153: return _backing.mkdir();
154: }
155:
156: public boolean mkdirs() throws IOException {
157: return _backing.mkdirs();
158: }
159:
160: public boolean remove() throws IOException {
161: return _backing.remove();
162: }
163:
164: public boolean renameTo(Path path) throws IOException {
165: return _backing.renameTo(path);
166: }
167:
168: public StreamImpl openReadImpl() throws IOException {
169: return _backing.openReadImpl();
170: }
171:
172: public StreamImpl openWriteImpl() throws IOException {
173: return _backing.openWriteImpl();
174: }
175:
176: public StreamImpl openReadWriteImpl() throws IOException {
177: return _backing.openReadWriteImpl();
178: }
179:
180: public StreamImpl openAppendImpl() throws IOException {
181: return _backing.openAppendImpl();
182: }
183:
184: void bind(String path, Path context) {
185: Node ptr = _node;
186:
187: int offset = 0;
188: while (offset + 1 < path.length()) {
189: int p = path.indexOf(_separatorChar, offset + 1);
190: String segment;
191: if (p == -1)
192: segment = path.substring(offset + 1);
193: else
194: segment = path.substring(offset + 1, p);
195:
196: Node next = ptr.findChild(segment);
197:
198: if (next == null)
199: next = ptr.addChild(segment, ptr._backing);
200: }
201:
202: ptr._backing = context;
203: }
204:
205: public int hashCode() {
206: return _backing.hashCode();
207: }
208:
209: public boolean equals(Object b) {
210: return _backing.equals(b);
211: }
212:
213: public String toString() {
214: return _backing.toString();
215: }
216:
217: static class Node {
218: Node parent;
219: Node firstChild;
220: Node next;
221:
222: String name;
223: Path _backing;
224:
225: Node(String name, Path backing) {
226: this .name = name;
227: this ._backing = backing;
228: }
229:
230: int size() {
231: int size = 0;
232:
233: for (Node ptr = firstChild; ptr != null; ptr = ptr.next)
234: size++;
235:
236: return size;
237: }
238:
239: Node findChild(String name) {
240: for (Node ptr = firstChild; ptr != null; ptr = ptr.next) {
241: if (ptr.name.equals(name))
242: return ptr;
243: }
244:
245: return null;
246: }
247:
248: Node addChild(String name, Path backing) {
249: for (Node ptr = firstChild; ptr != null; ptr = ptr.next) {
250: if (ptr.name.equals(name)) {
251: ptr._backing = backing;
252: return ptr;
253: }
254: }
255:
256: Node node = new Node(name, backing);
257: node.next = firstChild;
258: node.parent = this;
259: firstChild = node;
260:
261: return node;
262: }
263: }
264: }
|