KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > vfs > impl > VirtualFileSystem


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.vfs.impl;
17
18 import org.apache.commons.vfs.Capability;
19 import org.apache.commons.vfs.FileName;
20 import org.apache.commons.vfs.FileObject;
21 import org.apache.commons.vfs.FileSystemException;
22 import org.apache.commons.vfs.FileSystemOptions;
23 import org.apache.commons.vfs.FileType;
24 import org.apache.commons.vfs.NameScope;
25 import org.apache.commons.vfs.provider.AbstractFileSystem;
26 import org.apache.commons.vfs.provider.DelegateFileObject;
27
28 import java.util.Collection JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Map JavaDoc;
32
33 /**
34  * A logical file system, made up of set of junctions, or links, to files from
35  * other file systems.
36  *
37  * @author <a HREF="mailto:adammurdoch@apache.org">Adam Murdoch</a>
38  * @todo Handle nested junctions.
39  */

40 public class VirtualFileSystem
41     extends AbstractFileSystem
42 {
43     private final Map JavaDoc junctions = new HashMap JavaDoc();
44
45     public VirtualFileSystem(final FileName rootName, final FileSystemOptions fileSystemOptions)
46     {
47         super(rootName, null, fileSystemOptions);
48     }
49
50     /**
51      * Adds the capabilities of this file system.
52      */

53     protected void addCapabilities(final Collection JavaDoc caps)
54     {
55         // TODO - this isn't really true
56
caps.add(Capability.ATTRIBUTES);
57         caps.add(Capability.CREATE);
58         caps.add(Capability.DELETE);
59         caps.add(Capability.GET_TYPE);
60         caps.add(Capability.JUNCTIONS);
61         caps.add(Capability.GET_LAST_MODIFIED);
62         caps.add(Capability.SET_LAST_MODIFIED_FILE);
63         caps.add(Capability.SET_LAST_MODIFIED_FOLDER);
64         caps.add(Capability.LIST_CHILDREN);
65         caps.add(Capability.READ_CONTENT);
66         caps.add(Capability.SIGNING);
67         caps.add(Capability.WRITE_CONTENT);
68         caps.add(Capability.APPEND_CONTENT);
69     }
70
71     /**
72      * Creates a file object. This method is called only if the requested
73      * file is not cached.
74      */

75     protected FileObject createFile(final FileName name)
76         throws Exception JavaDoc
77     {
78         // Find the file that the name points to
79
final FileName junctionPoint = getJunctionForFile(name);
80         final FileObject file;
81         if (junctionPoint != null)
82         {
83             // Resolve the real file
84
final FileObject junctionFile = (FileObject) junctions.get(junctionPoint);
85             final String JavaDoc relName = junctionPoint.getRelativeName(name);
86             file = junctionFile.resolveFile(relName, NameScope.DESCENDENT_OR_SELF);
87         }
88         else
89         {
90             file = null;
91         }
92
93         // Return a wrapper around the file
94
return new DelegateFileObject(name, this, file);
95     }
96
97     /**
98      * Adds a junction to this file system.
99      */

100     public void addJunction(final String JavaDoc junctionPoint,
101                             final FileObject targetFile)
102         throws FileSystemException
103     {
104         final FileName junctionName = getFileSystemManager().resolveName(getRootName(), junctionPoint);
105
106         // Check for nested junction - these are not supported yet
107
if (getJunctionForFile(junctionName) != null)
108         {
109             throw new FileSystemException("vfs.impl/nested-junction.error", junctionName);
110         }
111
112         try
113         {
114             // Add to junction table
115
junctions.put(junctionName, targetFile);
116
117             // Attach to file
118
final DelegateFileObject junctionFile = (DelegateFileObject) getFileFromCache(junctionName);
119             if (junctionFile != null)
120             {
121                 junctionFile.setFile(targetFile);
122             }
123
124             // Create ancestors of junction point
125
FileName childName = junctionName;
126             boolean done = false;
127             for (FileName parentName = childName.getParent();
128                  !done && parentName != null;
129                  childName = parentName, parentName = parentName.getParent())
130             {
131                 DelegateFileObject file = (DelegateFileObject) getFileFromCache(parentName);
132                 if (file == null)
133                 {
134                     file = new DelegateFileObject(parentName, this, null);
135                     putFileToCache(file);
136                 }
137                 else
138                 {
139                     done = file.exists();
140                 }
141                 
142                 // As this is the parent of our junction it has to be a folder
143
file.attachChild(childName, FileType.FOLDER);
144             }
145
146             // TODO - attach all cached children of the junction point to their real file
147
}
148         catch (final Exception JavaDoc e)
149         {
150             throw new FileSystemException("vfs.impl/create-junction.error", junctionName, e);
151         }
152     }
153
154     /**
155      * Removes a junction from this file system.
156      */

157     public void removeJunction(final String JavaDoc junctionPoint)
158         throws FileSystemException
159     {
160         final FileName junctionName = getFileSystemManager().resolveName(getRootName(), junctionPoint);
161         junctions.remove(junctionName);
162
163         // TODO - remove from parents of junction point
164
// TODO - detach all cached children of the junction point from their real file
165
}
166
167     /**
168      * Locates the junction point for the junction containing the given file.
169      */

170     private FileName getJunctionForFile(final FileName name)
171     {
172         if (junctions.containsKey(name))
173         {
174             // The name points to the junction point directly
175
return name;
176         }
177
178         // Find matching junction
179
for (Iterator JavaDoc iterator = junctions.keySet().iterator(); iterator.hasNext();)
180         {
181             final FileName junctionPoint = (FileName) iterator.next();
182             if (junctionPoint.isDescendent(name))
183             {
184                 return junctionPoint;
185             }
186         }
187
188         // None
189
return null;
190     }
191 }
192
Popular Tags