KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > masterfs > MasterFileSystem


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.modules.masterfs;
22
23 import java.io.*;
24 import org.netbeans.modules.masterfs.providers.*;
25 import org.netbeans.modules.masterfs.providers.AnnotationProvider;
26 import org.openide.filesystems.*;
27 import org.openide.util.NbBundle;
28 import org.openide.util.actions.SystemAction;
29 import org.openide.util.Utilities;
30
31 import java.awt.*;
32 import java.beans.PropertyVetoException JavaDoc;
33 import java.io.File JavaDoc;
34 import java.io.Serializable JavaDoc;
35 import java.util.*;
36 import org.openide.util.Exceptions;
37
38 /**
39  * Implementation of FileSystem, that allows to host filesystems, that can be mounted
40  * and unmounted.
41  *
42  * @author Radek Matous
43  */

44 final public class MasterFileSystem extends FileSystem implements FileStatusListener {
45     /** generated Serialized Version UID */
46     private static final long serialVersionUID = -97134851800761145L;
47     //transient ArrayList rootChilds;
48
transient private static MasterFileSystem instance;
49     transient private final StatusImpl status = new StatusImpl();
50
51     static MasterFileSystem getDefault() {
52         boolean init = false;
53         synchronized (MasterFileSystem.class) {
54             if (instance == null) {
55                 instance = new MasterFileSystem();
56                 init = true;
57             }
58             
59         }
60         if (init) {
61             ProviderCall.init();
62         }
63         return instance;
64     }
65     
66     public static MasterFileSystem settingsFactory(FileObject inst) {
67         return getDefault();
68     }
69
70     private MasterFileSystem() {
71         init();
72     }
73
74     private Object JavaDoc writeReplace () {
75         return new Replace ();
76     }
77
78     private void init() {
79         try {
80             setSystemName(getClass().getName()); //NOI18N
81
} catch (PropertyVetoException JavaDoc pvx) {
82             ///nobody can`t have registered VetoableChangeListener, so no exception
83
// can`t be fired
84
}
85         registerFileStatusListener();
86     }
87
88     private void registerFileStatusListener() {
89         Enumeration en = MountTable.getDefault().geAllFileSystems();
90         while (en.hasMoreElements()) {
91             FileSystem fs = (FileSystem) en.nextElement();
92             fs.addNotify();
93             fs.addFileStatusListener(this);
94         }
95     }
96
97     public String JavaDoc getDisplayName() {
98         return NbBundle.getMessage(MasterFileSystem.class, "LBL_this_computer");
99     }
100
101     // XXX should be a MasterFileSystemBeanInfo that hides this property (hidden=true)!
102
public boolean isReadOnly() {
103         return false;
104     }
105
106     public FileObject getRoot() {
107         return Cache.getDefault().getOrCreate(ResourcePath.getRoot());
108     }
109     
110     public FileObject findResource(String JavaDoc name) {
111         ResourcePath resPath = new ResourcePath (name);
112         FileObject retVal = Cache.getDefault().get(resPath);
113         if (Utilities.getOperatingSystem() == Utilities.OS_VMS) {
114             if (retVal == null) retVal = getStepByStepVMS(resPath);
115         } else {
116             if (retVal == null) retVal = getStepByStep(resPath);
117         }
118         return retVal;
119     }
120
121     /**
122      * May look strange. BUT: Every call of getFileObject tries to mount
123      * filesystem, that may be requested to provide delegates.
124      */

125     private FileObject getStepByStep(ResourcePath resPath) {
126         FileObject retVal = getRoot();
127         Enumeration elems = resPath.getElements();
128         while (elems.hasMoreElements()) {
129             String JavaDoc nameExt = (String JavaDoc)elems.nextElement();
130             retVal = retVal.getFileObject(nameExt);
131            if (retVal == null) return null;
132         }
133         return retVal;
134     }
135
136     /** Returns the root for OpenVMS platform given the path
137      * @param name the path to search root from
138      * @return the root
139      */

140     private static String JavaDoc findVMSRoot(String JavaDoc name) {
141          if (name.length() > 0) {
142              StringTokenizer stok = new StringTokenizer(name, "/");
143              String JavaDoc rootName = "";
144              while (stok.hasMoreTokens()) {
145                  rootName += "/" + stok.nextToken();
146                  if (new File JavaDoc(rootName).exists()) {
147                     return rootName;
148                  }
149              }
150          }
151          return null;
152     }
153     
154     /** Returns the root for OpenVMS platform. The root is in the form
155      * of "/<device name>".
156      * @param name name of the file specification to extract the root from
157      * @return the FileObject instance representing the root directory
158      */

159      private static FileObject getRootForVMS(String JavaDoc name) {
160          return Cache.getDefault().getOrCreate(new ResourcePath(name));
161     }
162     
163     /**
164      * May look strange. BUT: Every call of getFileObject tries to mount
165      * filesystem, that may be requested to provide delegates.
166      */

167     private static FileObject getStepByStepVMS(ResourcePath resPath) {
168         //On OpenVMS platform, the root is not "/"
169
//
170
String JavaDoc root = findVMSRoot(resPath.getNormalizedPath());
171         if (root == null)
172             return null;
173         
174         FileObject retVal = getRootForVMS(root);
175         //Get the part of the path that begins after the root
176
//
177
ResourcePath subPath = new ResourcePath(
178             resPath.getNormalizedPath().substring(root.length()));
179         Enumeration elems = subPath.getElements();
180        
181         while (elems.hasMoreElements()) {
182             String JavaDoc nameExt = (String JavaDoc)elems.nextElement();
183             //"000000" needs to be filtered out on OpenVMS platform
184
//
185
if (nameExt.equals("000000"))
186                 continue;
187             retVal = retVal.getFileObject(nameExt);
188             if (retVal == null) return null;
189         }
190         return retVal;
191     }
192
193     
194     public void addNotify() {
195     }
196
197     public void removeNotify() {
198         Cache.getDefault().clear();
199     }
200
201
202     public void refresh(boolean expected) {
203         Enumeration en = MountTable.getDefault().geAllFileSystems();
204         while (en.hasMoreElements()) {
205             FileSystem fs = (FileSystem) en.nextElement();
206             fs.refresh(expected);
207         }
208     }
209
210
211     public SystemAction[] getActions() {
212         return getEmptyActions();
213     }
214
215     private SystemAction[] getEmptyActions() {
216         return new SystemAction[]{};
217     }
218
219     public SystemAction[] getActions(java.util.Set JavaDoc foSet) {
220         SystemAction[] some = status.getActions (foSet);
221         if (some != null) {
222             return some;
223         }
224         
225         SyncSection.getDefault().enterSection();
226         try {
227             //check if all fileobjects come from the same filesystem
228
MasterFileObject hfo = getUniqueMasterFileObject(foSet);
229             if (hfo == null) return getEmptyActions();
230
231             FileSystem firstFs = getDelegateFileSystem(hfo.getDelegate().get());
232             FileSystem secondFs = getDelegateFileSystem(hfo.getDelegate().getPrefered());
233             if (firstFs == null) return getEmptyActions();
234
235             if (secondFs != firstFs ) {
236                 return mergeActionsFromBothDelegates(foSet, firstFs, secondFs);
237             }
238
239             return firstFs.getActions(Utils.transformToDelegates(foSet, false));
240         } finally {
241             SyncSection.getDefault().finishSection();
242         }
243     }
244
245     private static FileSystem getDelegateFileSystem(FileObject foDel) {
246         if (foDel == null) return null;
247         FileSystem fsDel = null;
248         try {
249             fsDel = foDel.getFileSystem();
250         } catch (FileStateInvalidException e) {
251             return null;
252         }
253         return fsDel;
254     }
255
256     private static MasterFileObject getUniqueMasterFileObject(Set hfoSet) {
257         MasterFileObject retVal = null;
258         FileSystem lastFs = null;
259         for (Iterator it = hfoSet.iterator(); it.hasNext();) {
260             Object JavaDoc o = it.next();
261             if (!(o instanceof MasterFileObject)) return null;
262
263             retVal = (MasterFileObject) o;
264             FileObject deleg = retVal.getDelegate().get();
265             if (deleg == null) continue;
266             FileSystem fs = getDelegateFileSystem(deleg);
267             if (fs == null) continue;
268
269             if (lastFs != null && lastFs != fs) return null;
270             lastFs = fs;
271         }
272         return retVal;
273     }
274
275     private SystemAction[] mergeActionsFromBothDelegates(Set hfoSet, FileSystem firstFs, FileSystem secondFs) {
276         Set mergedActions = new HashSet(hfoSet.size());
277
278         Set firstSet = Utils.transformToDelegates(hfoSet, false);
279         SystemAction[] firstActions = firstFs.getActions(firstSet);
280         mergedActions.addAll(Arrays.asList(firstActions));
281
282         Set secondSet = Utils.transformToDelegates(hfoSet, true);
283         SystemAction[] secondActions = secondFs.getActions(secondSet);
284         mergedActions.addAll(Arrays.asList(secondActions));
285
286         return (SystemAction[]) mergedActions.toArray(new SystemAction[mergedActions.size()]);
287     }
288
289
290     /** Notifies listener about change in annotataion of a few files.
291      * @param ev event describing the change
292      */

293     public void annotationChanged(final FileStatusEvent ev) {
294         /** Ugly piece of code, that relies on impl. of FileStatusEvent and its
295          * usage of Set of FileObjects. Adopted from TreeFS.
296          */

297         HashSet set = new HashSet(1) {
298             public boolean contains(Object JavaDoc o) {
299                 if (o instanceof MasterFileObject) {
300                     MasterFileObject fo = (MasterFileObject) o;
301                     FileObject deleg = fo.getDelegate().get();
302                     return deleg != null && ev.hasChanged(deleg);
303                 }
304                 return false;
305             }
306         };
307
308
309         fireFileStatusChanged(new FileStatusEvent(
310                 this, set, ev.isIconChange(), ev.isNameChange()
311         ));
312     }
313
314
315     public FileSystem.Status getStatus() {
316         return status;
317     }
318
319     final void fireFileStatus (FileStatusEvent event) {
320         fireFileStatusChanged(event);
321     }
322
323     
324     static final class StatusImpl implements FileSystem.HtmlStatus,
325     org.openide.util.LookupListener, org.openide.filesystems.FileStatusListener {
326         /** result with providers */
327         private org.openide.util.Lookup.Result annotationProviders;
328         private Collection previousProviders;
329         {
330             annotationProviders = org.openide.util.Lookup.getDefault ().lookup (
331                 new org.openide.util.Lookup.Template (AnnotationProvider.class)
332             );
333             annotationProviders.addLookupListener (this);
334             resultChanged (null);
335         }
336
337         public ProvidedExtensions getExtensions() {
338             Collection c = (previousProviders != null) ?
339                 Collections.unmodifiableCollection(previousProviders) : Collections.EMPTY_LIST;
340             return new ProvidedExtensionsProxy(c);
341         }
342         
343         public void resultChanged (org.openide.util.LookupEvent ev) {
344             java.util.Collection JavaDoc now = annotationProviders.allInstances ();
345             java.util.Collection JavaDoc add;
346             
347             if (previousProviders != null) {
348                 add = new HashSet (now);
349                 add.removeAll (previousProviders);
350                 
351                 HashSet toRemove = new HashSet(previousProviders);
352                 toRemove.removeAll (now);
353                 java.util.Iterator JavaDoc it = toRemove.iterator ();
354                 while (it.hasNext ()) {
355                     AnnotationProvider ap = (AnnotationProvider)it.next ();
356                     ap.removeFileStatusListener (this);
357                 }
358             
359             } else {
360                 add = now;
361             }
362
363             
364             
365             java.util.Iterator JavaDoc it = add.iterator ();
366             while (it.hasNext ()) {
367                 AnnotationProvider ap = (AnnotationProvider)it.next ();
368                 try {
369                     ap.addFileStatusListener (this);
370                 } catch (java.util.TooManyListenersException JavaDoc ex) {
371                     Exceptions.printStackTrace(ex);
372                 }
373             }
374             
375             previousProviders = now;
376         }
377
378         public SystemAction[] getActions(java.util.Set JavaDoc foSet) {
379             
380             javax.swing.Action JavaDoc[] retVal = null;
381             java.util.Iterator JavaDoc it = annotationProviders.allInstances ().iterator ();
382             while (retVal == null && it.hasNext ()) {
383                 AnnotationProvider ap = (AnnotationProvider)it.next ();
384                 retVal = ap.actions (foSet);
385             }
386             if (retVal != null) {
387                 // right now we handle just SystemAction, it can be changed if necessary
388
SystemAction[] ret = new SystemAction[retVal.length];
389                 for (int i = 0; i < retVal.length; i++) {
390                     if (retVal[i] instanceof SystemAction) {
391                         ret[i] = (SystemAction)retVal[i];
392                     }
393                 }
394                 return ret;
395             }
396             return null;
397         }
398         
399         public void annotationChanged (org.openide.filesystems.FileStatusEvent ev) {
400             if (ev.getSource () != MasterFileSystem.getDefault ()) {
401                 throw new IllegalStateException JavaDoc ("The source must be master fs and not : " + ev.getSource ()); // NOI18N
402
}
403             MasterFileSystem.getDefault ().fireFileStatusChanged (ev);
404         }
405         
406         private FileSystem getDelegateFileSystem (Set files) {
407             FileSystem retVal = null;
408            Iterator it = files.iterator();
409            if (it.hasNext()) {
410                 MasterFileObject mfo = (MasterFileObject)it.next();
411                 retVal = mfo.getDelegateFileSystem();
412                 
413            }
414            return retVal;
415         }
416         
417         public Image annotateIcon(Image icon, int iconType, Set files) {
418             Image retVal = null;
419             
420             Iterator it = annotationProviders.allInstances ().iterator ();
421             while (retVal == null && it.hasNext ()) {
422                 AnnotationProvider ap = (AnnotationProvider)it.next ();
423                 retVal = ap.annotateIcon (icon, iconType, files);
424             }
425             if (retVal != null) {
426                 return retVal;
427             }
428             
429             
430             retVal = icon;
431             FileSystem fs = getDelegateFileSystem(files);
432             if (fs != null) {
433                 Set transformedSet = new LazySet (files);
434                 retVal = fs.getStatus().annotateIcon(icon, iconType, transformedSet);
435             }
436             
437             return retVal;
438         }
439
440         public String JavaDoc annotateName(String JavaDoc name, Set files) {
441             String JavaDoc retVal = null;
442             Iterator it = annotationProviders.allInstances ().iterator ();
443             while (retVal == null && it.hasNext ()) {
444                 AnnotationProvider ap = (AnnotationProvider)it.next ();
445                 retVal = ap.annotateName (name, files);
446             }
447             if (retVal != null) {
448                 return retVal;
449             }
450             retVal = name;
451             
452             Set transformedSet = new LazySet (files);
453             FileSystem fs = getDelegateFileSystem(files);
454             if (fs != null) {
455                 retVal = fs.getStatus().annotateName(name, transformedSet);
456             }
457             return retVal;
458         }
459
460         public String JavaDoc annotateNameHtml(String JavaDoc name, Set files) {
461             String JavaDoc retVal = null;
462             Iterator it = annotationProviders.allInstances ().iterator ();
463             while (retVal == null && it.hasNext ()) {
464                 AnnotationProvider ap = (AnnotationProvider)it.next ();
465                 retVal = ap.annotateNameHtml (name, files);
466             }
467             return retVal;
468         }
469     }
470     
471     private static final class Replace implements Serializable JavaDoc {
472         static final long serialVersionUID = 50485340814380L;
473         
474         public Object JavaDoc readResolve () {
475             return MasterFileSystem.getDefault();
476         }
477     } // end of Replace
478

479     final static class LazySet implements Set {
480         private Set obj_files;
481         private boolean initialized = false;
482         private Iterator it = null;
483         
484         LazySet(Set obj_files) {
485             this.obj_files = obj_files;
486         }
487         
488         synchronized private void lazyInitialization() {
489             if (!initialized) {
490                 Set transformedSet = Utils.transformSet(obj_files);
491                 obj_files = transformedSet;
492                 initialized = true;
493             }
494         }
495         
496         public boolean add(Object JavaDoc o) {
497             throw new UnsupportedOperationException JavaDoc ();
498         }
499         
500         public boolean addAll(Collection c) {
501             throw new UnsupportedOperationException JavaDoc ();
502         }
503         
504         public void clear() {
505             throw new UnsupportedOperationException JavaDoc ();
506         }
507         
508         public boolean contains(Object JavaDoc o) {
509             lazyInitialization();
510             return obj_files.contains(o);
511         }
512         
513         public boolean containsAll(Collection c) {
514             lazyInitialization();
515             return obj_files.containsAll(c);
516         }
517         
518         public boolean isEmpty() {
519             lazyInitialization();
520             return obj_files.isEmpty();
521         }
522         
523         public Iterator iterator() {
524             if (initialized) {
525                 it = obj_files.iterator();
526             } else {
527                 it = new Iterator() {
528                     private final Iterator originalIterator = obj_files.iterator();
529
530                     public void remove() {
531                         throw new UnsupportedOperationException JavaDoc ();
532                     }
533
534                     public Object JavaDoc next() {
535                         MasterFileObject mfo = (MasterFileObject)originalIterator.next();
536                         return mfo.getDelegate().get (true);
537                     }
538
539                     public boolean hasNext() {
540                         return originalIterator.hasNext();
541                     }
542
543                 };
544             }
545             
546             return it;
547         }
548         
549         public boolean remove(Object JavaDoc o) {
550             lazyInitialization();
551             return obj_files.remove(o);
552         }
553         
554         public boolean removeAll(Collection c) {
555             lazyInitialization();
556             return obj_files.removeAll(c);
557         }
558         
559         public boolean retainAll(Collection c) {
560             lazyInitialization();
561             return obj_files.retainAll(c);
562         }
563         
564         public int size() {
565             lazyInitialization();
566             return obj_files.size();
567         }
568         
569         public Object JavaDoc[] toArray() {
570             lazyInitialization();
571             return obj_files.toArray();
572         }
573         
574         public Object JavaDoc[] toArray(Object JavaDoc[] a) {
575             lazyInitialization();
576             return obj_files.toArray(a);
577         }
578     }
579 }
580
Popular Tags