1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs.provider.ram;
18
19 import java.io.BufferedOutputStream;
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.io.Serializable;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.Map;
30
31 import org.apache.commons.vfs.FileName;
32 import org.apache.commons.vfs.FileObject;
33 import org.apache.commons.vfs.FileSystemException;
34 import org.apache.commons.vfs.FileSystemOptions;
35 import org.apache.commons.vfs.FileType;
36 import org.apache.commons.vfs.provider.AbstractFileSystem;
37
38 /***
39 * A RAM File System
40 */
41 public class RamFileSystem extends AbstractFileSystem implements Serializable
42 {
43 /***
44 * Cache of RAM File Data
45 */
46 private Map cache;
47
48 /***
49 * @param rootName
50 * @param fileSystemOptions
51 */
52 protected RamFileSystem(FileName rootName,
53 FileSystemOptions fileSystemOptions)
54 {
55 super(rootName, null, fileSystemOptions);
56 this.cache = Collections.synchronizedMap(new HashMap());
57
58 RamFileData rootData = new RamFileData(rootName) ;
59 rootData.setType(FileType.FOLDER);
60 rootData.setLastModified(System.currentTimeMillis());
61 this.cache.put(rootName, rootData);
62 }
63
64
65
66
67
68
69 protected FileObject createFile(FileName name) throws Exception
70 {
71 RamFileObject file = new RamFileObject(name, this);
72 return file;
73 }
74
75
76
77
78
79
80 protected void addCapabilities(Collection caps)
81 {
82 caps.addAll(RamFileProvider.capabilities);
83 }
84
85 /***
86 * @param name
87 * @return children
88 */
89 String[] listChildren(FileName name)
90 {
91 RamFileData data = (RamFileData) this.cache.get(name);
92 Collection children = data.getChildren();
93
94 String[] names = new String[children.size()];
95
96 int pos = 0 ;
97 Iterator iter = children.iterator() ;
98 while (iter.hasNext())
99 {
100 RamFileData childData = (RamFileData) iter.next();
101 names[pos] = childData.getName().getBaseName();
102 pos++;
103 }
104
105 return names;
106 }
107
108 /***
109 * Delete a file
110 *
111 * @param file
112 * @throws FileSystemException
113 */
114 void delete(RamFileObject file) throws FileSystemException
115 {
116
117 if (file.getParent()==null) {
118 throw new FileSystemException("unable to delete root");
119 }
120
121
122 this.cache.remove(file.getName());
123
124 RamFileObject parent = (RamFileObject) this.resolveFile(file
125 .getParent().getName());
126 parent.getData().removeChild(file.getData());
127 parent.close();
128
129 file.getData().clear();
130 file.close();
131 }
132
133 /***
134 * Saves a file
135 *
136 * @param file
137 * @throws FileSystemException
138 */
139 void save(final RamFileObject file) throws FileSystemException
140 {
141
142
143 if (file.getData().getName() == null)
144 {
145 throw new FileSystemException(new IllegalStateException(
146 "The data has no name. " + file));
147 }
148
149
150 if (file.getName().getDepth() > 0)
151 {
152 RamFileData parentData = (RamFileData) this.cache.get(file
153 .getParent().getName());
154
155 if (!parentData.hasChildren(file.getData()))
156 {
157 RamFileObject parent = (RamFileObject) file.getParent();
158 parent.getData().addChild(file.getData());
159 parent.close();
160 }
161 }
162
163 cache.put(file.getName(), file.getData());
164 file.getData().updateLastModified();
165 file.close();
166 }
167
168 /***
169 * @param from
170 * @param to
171 * @throws FileSystemException
172 */
173 void rename(RamFileObject from, RamFileObject to)
174 throws FileSystemException
175 {
176 if (!this.cache.containsKey(from.getName()))
177 {
178 throw new FileSystemException("File does not exist: "
179 + from.getName());
180 }
181
182
183 to.getData().setBuffer(from.getData().getBuffer());
184 to.getData().setLastModified(from.getData().getLastModified());
185 to.getData().setType(from.getData().getType());
186
187 this.save(to);
188 this.delete(from);
189 }
190
191 public void attach(RamFileObject fo)
192 {
193 if (fo.getName() == null)
194 {
195 throw new IllegalArgumentException("Null argument");
196 }
197 RamFileData data = (RamFileData) this.cache.get(fo.getName());
198 if (data == null)
199 {
200 data = new RamFileData(fo.getName());
201 }
202 fo.setData(data);
203 }
204
205 /***
206 * Import a Tree
207 *
208 * @param file
209 * @throws FileSystemException
210 */
211 public void importTree(File file) throws FileSystemException
212 {
213 FileObject fileFo = getFileSystemManager().toFileObject(file);
214 this.toRamFileObject(fileFo, fileFo);
215 }
216
217 /***
218 * Import the given file with the name relative to the given root
219 *
220 * @param fo
221 * @param root
222 * @throws FileSystemException
223 */
224 void toRamFileObject(FileObject fo, FileObject root)
225 throws FileSystemException
226 {
227 RamFileObject memFo = (RamFileObject) this.resolveFile(fo.getName()
228 .getPath().substring(root.getName().getPath().length()));
229 if (fo.getType().hasChildren())
230 {
231
232 memFo.createFolder();
233
234 FileObject[] fos = fo.getChildren();
235 for (int i = 0; i < fos.length; i++)
236 {
237 FileObject child = fos[i];
238 this.toRamFileObject(child, root);
239 }
240 }
241 else if (fo.getType().equals(FileType.FILE))
242 {
243
244 try
245 {
246 InputStream is = fo.getContent().getInputStream();
247 try
248 {
249 OutputStream os = new BufferedOutputStream(memFo
250 .getOutputStream(), 512);
251 int i;
252 while ((i = is.read()) != -1)
253 {
254 os.write(i);
255 }
256 os.flush();
257 os.close();
258 }
259 finally
260 {
261 try
262 {
263 is.close();
264 }
265 catch (IOException e)
266 {
267
268 ;
269 }
270 }
271 }
272 catch (IOException e)
273 {
274 throw new FileSystemException(e.getClass().getName() + " "
275 + e.getMessage());
276 }
277 }
278 else
279 {
280 throw new FileSystemException("File is not a folder nor a file "
281 + memFo);
282 }
283 }
284
285 /***
286 * @return Returns the size of the FileSystem
287 */
288 int size()
289 {
290 int size = 0;
291 Iterator iter = cache.values().iterator();
292 while (iter.hasNext())
293 {
294 RamFileData data = (RamFileData) iter.next();
295 size += data.size();
296 }
297 return size;
298 }
299
300 /***
301 * Close the RAMFileSystem
302 */
303 public void close()
304 {
305 this.cache = null;
306 super.close();
307 }
308 }