KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > vfs > provider > AbstractFileSystem


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.provider;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.apache.commons.vfs.Capability;
21 import org.apache.commons.vfs.FileListener;
22 import org.apache.commons.vfs.FileName;
23 import org.apache.commons.vfs.FileObject;
24 import org.apache.commons.vfs.FileSelector;
25 import org.apache.commons.vfs.FileSystem;
26 import org.apache.commons.vfs.FileSystemException;
27 import org.apache.commons.vfs.FileSystemManager;
28 import org.apache.commons.vfs.FileSystemOptions;
29 import org.apache.commons.vfs.FilesCache;
30 import org.apache.commons.vfs.VfsLog;
31 import org.apache.commons.vfs.events.AbstractFileChangeEvent;
32 import org.apache.commons.vfs.events.ChangedEvent;
33 import org.apache.commons.vfs.events.CreateEvent;
34 import org.apache.commons.vfs.events.DeleteEventAbstractFile;
35 import org.apache.commons.vfs.util.Messages;
36
37 import java.io.File JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.Collection JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.HashSet JavaDoc;
42 import java.util.Map JavaDoc;
43
44 /**
45  * A partial {@link org.apache.commons.vfs.FileSystem} implementation.
46  *
47  * @author <a HREF="mailto:adammurdoch@apache.org">Adam Murdoch</a>
48  */

49 public abstract class AbstractFileSystem
50     extends AbstractVfsComponent
51     implements FileSystem
52 {
53     private final static Log log = LogFactory.getLog(AbstractFileSystem.class);
54
55     private final FileName rootName;
56     private FileObject parentLayer;
57     // private FileObject root;
58
private final Collection JavaDoc caps = new HashSet JavaDoc();
59
60     /**
61      * Map from FileName to FileObject.
62      */

63     // private FilesCache files;
64

65     /**
66      * Map from FileName to an ArrayList of listeners for that file.
67      */

68     private final Map JavaDoc listenerMap = new HashMap JavaDoc();
69
70     /**
71      * FileSystemOptions used for configuration
72      */

73     private final FileSystemOptions fileSystemOptions;
74
75     /**
76      * How many files are activley using the filesystem
77      */

78     private long useCount;
79
80     private FileSystemKey cacheKey;
81
82     /**
83      * open streams counter for this filesystem
84      */

85     private int openStreams;
86
87     protected AbstractFileSystem(final FileName rootName,
88                                  final FileObject parentLayer,
89                                  final FileSystemOptions fileSystemOptions)
90     {
91         // this.parentLayer = parentLayer;
92
this.parentLayer = parentLayer;
93         this.rootName = rootName;
94         this.fileSystemOptions = fileSystemOptions;
95
96         // this.files = null;
97
}
98
99     /**
100      * Initialises this component.
101      */

102     public void init() throws FileSystemException
103     {
104         addCapabilities(caps);
105     }
106
107     /**
108      * Closes this component.
109      */

110     public void close()
111     {
112         closeCommunicationLink();
113
114         parentLayer = null;
115     }
116
117     /**
118      * Close the underlaying link used to access the files
119      */

120     public void closeCommunicationLink()
121     {
122         synchronized (this)
123         {
124             doCloseCommunicationLink();
125         }
126     }
127
128     /**
129      * Close the underlaying link used to access the files
130      */

131     protected void doCloseCommunicationLink()
132     {
133     }
134
135     /**
136      * Creates a file object. This method is called only if the requested
137      * file is not cached.
138      */

139     protected abstract FileObject createFile(final FileName name)
140         throws Exception JavaDoc;
141
142     /**
143      * Adds the capabilities of this file system.
144      */

145     protected abstract void addCapabilities(Collection JavaDoc caps);
146
147     /**
148      * Returns the name of the root of this file system.
149      */

150     public FileName getRootName()
151     {
152         return rootName;
153     }
154
155     /**
156      * Adds a file object to the cache.
157      */

158     protected void putFileToCache(final FileObject file)
159     {
160         getCache().putFile(file);
161         // files.put(file.getName(), file);
162
}
163
164     private FilesCache getCache()
165     {
166         FilesCache files;
167         //if (this.files == null)
168
{
169             files = getContext().getFileSystemManager().getFilesCache();
170             if (files == null)
171             {
172                 throw new RuntimeException JavaDoc(Messages.getString("vfs.provider/files-cache-missing.error"));
173             }
174         }
175
176         return files;
177     }
178
179     /**
180      * Returns a cached file.
181      */

182     protected FileObject getFileFromCache(final FileName name)
183     {
184         return getCache().getFile(this, name);
185         // return (FileObject) files.get(name);
186
}
187
188     /**
189      * remove a cached file.
190      */

191     protected void removeFileFromCache(final FileName name)
192     {
193         getCache().removeFile(this, name);
194     }
195
196     /**
197      * Determines if this file system has a particular capability.
198      */

199     public boolean hasCapability(final Capability capability)
200     {
201         return caps.contains(capability);
202     }
203
204     /**
205      * Retrieves the attribute with the specified name. The default
206      * implementation simply throws an exception.
207      */

208     public Object JavaDoc getAttribute(final String JavaDoc attrName) throws FileSystemException
209     {
210         throw new FileSystemException("vfs.provider/get-attribute-not-supported.error");
211     }
212
213     /**
214      * Sets the attribute with the specified name. The default
215      * implementation simply throws an exception.
216      */

217     public void setAttribute(final String JavaDoc attrName, final Object JavaDoc value)
218         throws FileSystemException
219     {
220         throw new FileSystemException("vfs.provider/set-attribute-not-supported.error");
221     }
222
223     /**
224      * Returns the parent layer if this is a layered file system.
225      */

226     public FileObject getParentLayer() throws FileSystemException
227     {
228         return parentLayer;
229     }
230
231     /**
232      * Returns the root file of this file system.
233      */

234     public FileObject getRoot() throws FileSystemException
235     {
236         return resolveFile(rootName);
237         /*
238         if (root == null)
239         {
240             root = resolveFile(rootName);
241         }
242         return root;
243         */

244     }
245
246     /**
247      * Finds a file in this file system.
248      */

249     public FileObject resolveFile(final String JavaDoc nameStr) throws FileSystemException
250     {
251         // Resolve the name, and create the file
252
final FileName name = getFileSystemManager().resolveName(rootName, nameStr);
253         return resolveFile(name);
254     }
255
256     /**
257      * Finds a file in this file system.
258      */

259     public synchronized FileObject resolveFile(final FileName name) throws FileSystemException
260     {
261         return resolveFile(name, true);
262     }
263
264     private synchronized FileObject resolveFile(final FileName name, final boolean useCache) throws FileSystemException
265     {
266         if (!rootName.getRootURI().equals(name.getRootURI()))
267         {
268             throw new FileSystemException("vfs.provider/mismatched-fs-for-name.error",
269                 new Object JavaDoc[]{
270                     name, rootName, name.getRootURI()});
271         }
272
273         // imario@apache.org ==> use getFileFromCache
274
FileObject file;
275         if (useCache)
276         {
277             file = getFileFromCache(name);
278         }
279         else
280         {
281             file = null;
282         }
283         // FileObject file = (FileObject) files.get(name);
284
if (file == null)
285         {
286             try
287             {
288                 synchronized (this)
289                 {
290                     file = createFile(name);
291                 }
292             }
293             catch (Exception JavaDoc e)
294             {
295                 throw new FileSystemException("vfs.provider/resolve-file.error", name, e);
296             }
297
298             // imario@apache.org ==> use putFileToCache
299
if (useCache)
300             {
301                 putFileToCache(file);
302             }
303             // files.put(name, file);
304
}
305         return file;
306     }
307
308     /**
309      * Creates a temporary local copy of a file and its descendents.
310      */

311     public File replicateFile(final FileObject file,
312                               final FileSelector selector)
313         throws FileSystemException
314     {
315         if (!file.exists())
316         {
317             throw new FileSystemException("vfs.provider/replicate-missing-file.error", file.getName());
318         }
319
320         try
321         {
322             return doReplicateFile(file, selector);
323         }
324         catch (final Exception JavaDoc e)
325         {
326             throw new FileSystemException("vfs.provider/replicate-file.error", file.getName(), e);
327         }
328     }
329
330     /**
331      * Return the FileSystemOptions used to instantiate this filesystem
332      */

333     public FileSystemOptions getFileSystemOptions()
334     {
335         return fileSystemOptions;
336     }
337
338     /**
339      * Return the FileSystemManager used to instantiate this filesystem
340      */

341     public FileSystemManager getFileSystemManager()
342     {
343         return getContext().getFileSystemManager();
344         // return manager;
345
}
346
347     /**
348      * Returns the accuracy of the last modification time
349      *
350      * @return ms 0 perfectly accurate, >0 might be off by this value e.g. sftp 1000ms
351      */

352     public double getLastModTimeAccuracy()
353     {
354         return 0;
355     }
356
357     /**
358      * Creates a temporary local copy of a file and its descendents.
359      */

360     protected File doReplicateFile(final FileObject file,
361                                    final FileSelector selector)
362         throws Exception JavaDoc
363     {
364         return getContext().getReplicator().replicateFile(file, selector);
365     }
366
367     /**
368      * Adds a junction to this file system.
369      */

370     public void addJunction(final String JavaDoc junctionPoint,
371                             final FileObject targetFile)
372         throws FileSystemException
373     {
374         throw new FileSystemException("vfs.provider/junctions-not-supported.error", rootName);
375     }
376
377     /**
378      * Removes a junction from this file system.
379      */

380     public void removeJunction(final String JavaDoc junctionPoint) throws FileSystemException
381     {
382         throw new FileSystemException("vfs.provider/junctions-not-supported.error", rootName);
383     }
384
385     /**
386      * Adds a listener on a file in this file system.
387      */

388     public void addListener(final FileObject file,
389                             final FileListener listener)
390     {
391         synchronized (listenerMap)
392         {
393             ArrayList JavaDoc listeners = (ArrayList JavaDoc) listenerMap.get(file.getName());
394             if (listeners == null)
395             {
396                 listeners = new ArrayList JavaDoc();
397                 listenerMap.put(file.getName(), listeners);
398             }
399             listeners.add(listener);
400         }
401     }
402
403     /**
404      * Removes a listener from a file in this file system.
405      */

406     public void removeListener(final FileObject file,
407                                final FileListener listener)
408     {
409         synchronized (listenerMap)
410         {
411             final ArrayList JavaDoc listeners = (ArrayList JavaDoc) listenerMap.get(file.getName());
412             if (listeners != null)
413             {
414                 listeners.remove(listener);
415             }
416         }
417     }
418
419     /**
420      * Fires a file create event.
421      */

422     public void fireFileCreated(final FileObject file)
423     {
424         fireEvent(new CreateEvent(file));
425     }
426
427     /**
428      * Fires a file delete event.
429      */

430     public void fireFileDeleted(final FileObject file)
431     {
432         fireEvent(new DeleteEventAbstractFile(file));
433     }
434
435     /**
436      * Fires a file changed event. <br />
437      * This will only happen if you monitor the file using {@link org.apache.commons.vfs.FileMonitor}.
438      */

439     public void fireFileChanged(final FileObject file)
440     {
441         fireEvent(new ChangedEvent(file));
442     }
443
444     /**
445      * returns true if no file is using this filesystem
446      */

447     public boolean isReleaseable()
448     {
449         return useCount < 1;
450     }
451
452     void freeResources()
453     {
454     }
455
456     /**
457      * Fires an event.
458      */

459     private void fireEvent(final AbstractFileChangeEvent event)
460     {
461         synchronized (listenerMap)
462         {
463             final FileObject file = event.getFile();
464             final ArrayList JavaDoc listeners = (ArrayList JavaDoc) listenerMap.get(file.getName());
465             if (listeners != null)
466             {
467                 final int count = listeners.size();
468                 for (int i = 0; i < count; i++)
469                 {
470                     final FileListener listener = (FileListener) listeners.get(i);
471                     try
472                     {
473                         event.notify(listener);
474                     }
475                     catch (final Exception JavaDoc e)
476                     {
477                         final String JavaDoc message = Messages.getString("vfs.provider/notify-listener.warn", file);
478                         // getLogger().warn(message, e);
479
VfsLog.warn(getLogger(), log, message, e);
480                     }
481                 }
482             }
483         }
484     }
485
486     void fileDetached(FileObject fileObject)
487     {
488         useCount--;
489     }
490
491     void fileAttached(FileObject fileObject)
492     {
493         useCount++;
494
495     }
496
497     void setCacheKey(FileSystemKey cacheKey)
498     {
499         this.cacheKey = cacheKey;
500     }
501
502     FileSystemKey getCacheKey()
503     {
504         return this.cacheKey;
505     }
506
507     void streamOpened()
508     {
509         synchronized (this)
510         {
511             openStreams++;
512         }
513     }
514
515     void streamClosed()
516     {
517         synchronized (this)
518         {
519             if (openStreams > 0)
520             {
521                 openStreams--;
522                 if (openStreams < 1)
523                 {
524                     notifyAllStreamsClosed();
525                 }
526             }
527         }
528     }
529
530     /**
531      * will be called after all file-objects closed their streams.
532      */

533     protected void notifyAllStreamsClosed()
534     {
535     }
536
537     /**
538      * check if this filesystem has open streams
539      */

540     public boolean isOpen()
541     {
542         synchronized (this)
543         {
544             return openStreams > 0;
545         }
546     }
547 }
548
Popular Tags