KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > filesystems > FileSystem


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 package org.openide.filesystems;
21
22 import java.awt.Image JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.beans.PropertyChangeSupport JavaDoc;
26 import java.beans.PropertyVetoException JavaDoc;
27 import java.beans.VetoableChangeListener JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.Serializable JavaDoc;
30 import java.text.MessageFormat JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33 import org.openide.util.NbBundle;
34 import org.openide.util.actions.SystemAction;
35
36 /** Interface that provides basic information about a virtual
37 * filesystem. Classes that implement it
38 * should follow JavaBean conventions because when a new
39 * instance of a filesystem class is inserted into the system, it should
40 * permit the user to modify it with standard Bean properties.
41 * <P>
42 * Implementing classes should also have associated subclasses of {@link FileObject}.
43 * <p>Although the class is serializable, only the {@link #isHidden hidden state} and {@link #getSystemName system name}
44 * are serialized, and the deserialized object is by default {@link #isValid invalid} (and may be a distinct
45 * object from a valid filesystem in the Repository). If you wish to safely deserialize a file
46 * system, you should after deserialization try to replace it with a filesystem of the
47 * {@link Repository#findFileSystem same name} in the Repository.
48 * @author Jaroslav Tulach
49 */

50 public abstract class FileSystem implements Serializable JavaDoc {
51     /** generated Serialized Version UID */
52     static final long serialVersionUID = -8931487924240189180L;
53
54     /** Property name indicating validity of filesystem. */
55     public static final String JavaDoc PROP_VALID = "valid"; // NOI18N
56

57     /**
58      * Property name indicating whether filesystem is hidden.
59      * @deprecated The property is now hidden.
60      */

61     @Deprecated JavaDoc
62     public static final String JavaDoc PROP_HIDDEN = "hidden"; // NOI18N
63

64     /**
65      * Property name giving internal system name of filesystem.
66      * @deprecated This system name should now be avoided in favor of identifying files persistently by URL.
67      */

68     @Deprecated JavaDoc
69     public static final String JavaDoc PROP_SYSTEM_NAME = "systemName"; // NOI18N
70

71     /** Property name giving display name of filesystem.
72      * @since 2.1
73      */

74     public static final String JavaDoc PROP_DISPLAY_NAME = "displayName"; // NOI18N
75

76     /** Property name giving root folder of filesystem. */
77     public static final String JavaDoc PROP_ROOT = "root"; // NOI18N
78

79     /** Property name giving read-only state. */
80     public static final String JavaDoc PROP_READ_ONLY = "readOnly"; // NOI18N
81

82     /** Property name giving capabilities state. @deprecated No more capabilities. */
83     static final String JavaDoc PROP_CAPABILITIES = "capabilities"; // NOI18N
84

85     /** Used for synchronization purpose*/
86     private static Object JavaDoc internLock = new Object JavaDoc();
87     private transient static ThreadLocal JavaDoc<EventControl> thrLocal = new ThreadLocal JavaDoc<EventControl>();
88
89     /** Empty status */
90     private static final Status STATUS_NONE = new Status() {
91             public String JavaDoc annotateName(String JavaDoc name, Set JavaDoc<? extends FileObject> files) {
92                 return name;
93             }
94
95             public Image JavaDoc annotateIcon(Image JavaDoc icon, int iconType, Set JavaDoc<? extends FileObject> files) {
96                 return icon;
97             }
98         };
99
100     /** is this filesystem valid?
101     * It can be invalid if there is another filesystem with the
102     * same name in the filesystem pool.
103     */

104     transient private boolean valid = false;
105
106     /** True if the filesystem is assigned to pool.
107     * Is modified from Repository methods.
108     */

109     transient boolean assigned = false;
110
111     /**Repository that contains this FileSystem or null*/
112     private transient Repository repository = null;
113     private transient FCLSupport fclSupport;
114
115     /** Describes capabilities of the filesystem.
116     */

117     @Deprecated JavaDoc // have to store it for compat
118
// XXX JDK #6460147: javac still reports it even though @Deprecated, and @SuppressWarnings("deprecation") does not help either
119
private FileSystemCapability capability;
120
121     /** property listener on FileSystemCapability. */
122     private transient PropertyChangeListener JavaDoc capabilityListener;
123
124     /** hidden flag */
125     private boolean hidden = false;
126
127     /** system name */
128     private String JavaDoc systemName = "".intern(); // NOI18N
129

130     /** Utility field used by event firing mechanism. */
131     private transient ListenerList<FileStatusListener> fileStatusList;
132     private transient ListenerList<VetoableChangeListener JavaDoc> vetoableChangeList;
133     private transient PropertyChangeSupport JavaDoc changeSupport;
134
135     /** Default constructor. */
136     public FileSystem() {
137     }
138
139     /** Should check for external modifications. All existing FileObjects will be
140      * refreshed. For folders it should reread the content of disk,
141      * for data file it should check for the last time the file has been modified.
142      *
143      * The default implementation is to do nothing, in contradiction to the rest
144      * of the description. Unless subclasses override it, the method does not work.
145      *
146      * @param expected should the file events be marked as expected change or not?
147      * @see FileEvent#isExpected
148      * @since 2.16
149      */

150     public void refresh(boolean expected) {
151     }
152
153     /** Test whether filesystem is valid.
154     * Generally invalidity would be caused by a name conflict in the filesystem pool.
155     * @return true if the filesystem is valid
156     */

157     public final boolean isValid() {
158         return valid;
159     }
160
161     /** Setter for validity. Accessible only from filesystem pool.
162     * @param v the new value
163     */

164     final void setValid(boolean v) {
165         if (v != valid) {
166             valid = v;
167             firePropertyChange(
168                 PROP_VALID, (!v) ? Boolean.TRUE : Boolean.FALSE, v ? Boolean.TRUE : Boolean.FALSE, Boolean.FALSE
169             );
170         }
171     }
172
173     /** Set hidden state of the object.
174      * A hidden filesystem is not presented to the user in the Repository list (though it may be present in the Repository Settings list).
175     *
176     * @param hide <code>true</code> if the filesystem should be hidden
177      * @deprecated This property is now useless.
178     */

179     @Deprecated JavaDoc
180     public final void setHidden(boolean hide) {
181         if (hide != hidden) {
182             hidden = hide;
183             firePropertyChange(PROP_HIDDEN, (!hide) ? Boolean.TRUE : Boolean.FALSE, hide ? Boolean.TRUE : Boolean.FALSE);
184         }
185     }
186
187     /** Getter for the hidden property.
188      * @deprecated This property is now useless.
189     */

190     @Deprecated JavaDoc
191     public final boolean isHidden() {
192         return hidden;
193     }
194
195     /** Tests whether filesystem will survive reloading of system pool.
196     * If true then when
197     * {@link Repository} is reloading its content, it preserves this
198     * filesystem in the pool.
199     * <P>
200     * This can be used when the pool contains system level and user level
201     * filesystems. The system ones should be preserved when the user changes
202     * the content (for example when he is loading a new project).
203     * <p>The default implementation returns <code>false</code>.
204     *
205     * @return true if the filesystem should be persistent
206      * @deprecated This property is long since useless.
207     */

208     @Deprecated JavaDoc
209     protected boolean isPersistent() {
210         return false;
211     }
212
213     /** Provides a name for the system that can be presented to the user.
214     * <P>
215     * This call should <STRONG>never</STRONG> be used to attempt to identify the file root
216     * of the filesystem. On some systems it may happen to look the same but this is a
217     * coincidence and may well change in the future. Either check whether
218     * you are working with a {@link LocalFileSystem} or similar implementation and use
219     * {@link LocalFileSystem#getRootDirectory}; or better, try
220     * {@link FileUtil#toFile} which is designed to do this correctly.
221     * <p><strong>Note:</strong> for most purposes it is probably a bad idea to use
222     * this method. Instead look at {@link FileUtil#getFileDisplayName}.
223     * @return user presentable name of the filesystem
224     */

225     public abstract String JavaDoc getDisplayName();
226
227     /** Internal (system) name of the filesystem.
228     * Should uniquely identify the filesystem, as it will
229     * be used during serialization of its files. The preferred way of doing this is to concatenate the
230     * name of the filesystem type (e.g. the class) and the textual form of its parameters.
231     * <P>
232     * A change of the system name should be interpreted as a change of the internal
233     * state of the filesystem. For example, if the root directory is moved to different
234     * location, one should rebuild representations for all files
235     * in the system.
236     * <P>
237     * This call should <STRONG>never</STRONG> be used to attempt to identify the file root
238     * of the filesystem. On Unix systems it may happen to look the same but this is a
239     * coincidence and may well change in the future. Either check whether
240     * you are working with a {@link LocalFileSystem} or similar implementation and use
241     * {@link LocalFileSystem#getRootDirectory}; or better, try
242     * {@link FileUtil#toFile} which is designed to do this correctly.
243     * @return string with system name
244      * @deprecated The system name should now be avoided in favor of identifying files persistently by URL.
245     */

246     @Deprecated JavaDoc
247     public final String JavaDoc getSystemName() {
248         return systemName;
249     }
250
251     /** Changes system name of the filesystem.
252     * This property is bound and constrained: first of all
253     * all vetoable listeners are asked whether they agree with the change. If so,
254     * the change is made and all change listeners are notified of
255     * the change.
256     *
257     * <p><em>Warning:</em> this method is protected so that only subclasses can change
258     * the system name.
259     *
260     * @param name new system name
261     * @exception PropertyVetoException if the change is not allowed by a listener
262      * @deprecated The system name should now be avoided in favor of identifying files persistently by URL.
263     */

264     @Deprecated JavaDoc
265     protected final void setSystemName(String JavaDoc name) throws PropertyVetoException JavaDoc {
266         synchronized (Repository.class) {
267             if (systemName.equals(name)) {
268                 return;
269             }
270
271             // I must be the only one who works with system pool (that is listening)
272
// on this interface
273
fireVetoableChange(PROP_SYSTEM_NAME, systemName, name);
274
275             String JavaDoc old = systemName;
276             systemName = name.intern();
277
278             firePropertyChange(PROP_SYSTEM_NAME, old, systemName);
279
280             /** backward compatibility for FileSystems that don`t fire
281              * PROP_DISPLAY_NAME*/

282             firePropertyChange(PROP_DISPLAY_NAME, null, null);
283         }
284     }
285
286     /** Returns <code>true</code> if the filesystem is default.
287      * @see Repository#getDefaultFileSystem
288     */

289     public final boolean isDefault() {
290         return this == ExternalUtil.getRepository().getDefaultFileSystem();
291     }
292
293     /** Test if the filesystem is read-only or not.
294     * @return true if the system is read-only
295     */

296     public abstract boolean isReadOnly();
297
298     /** Getter for root folder in the filesystem.
299     *
300     * @return root folder of whole filesystem
301     */

302     public abstract FileObject getRoot();
303
304     /** Finds file in the filesystem by name.
305     * <P>
306     * The default implementation converts dots in the package name into slashes,
307     * concatenates the strings, adds any extension prefixed by a dot and calls
308     * the {@link #findResource findResource} method.
309     *
310     * <p><em>Note:</em> when both of <code>name</code> and <code>ext</code> are <CODE>null</CODE> then name and
311     * extension should be ignored and scan should look only for a package.
312     *
313     * @param aPackage package name where each package component is separated by a dot
314     * @param name name of the file (without dots) or <CODE>null</CODE> if
315     * one wants to obtain a folder (package) and not a file in it
316     * @param ext extension of the file (without leading dot) or <CODE>null</CODE> if one needs
317     * a package and not a file
318     *
319     * @return a file object that represents a file with the given name or
320     * <CODE>null</CODE> if the file does not exist
321     * @deprecated Please use the <a HREF="@org-netbeans-api-java@/org/netbeans/api/java/classpath/ClassPath.html">ClassPath API</a> instead, or use {@link #findResource} if you are not interested in classpaths.
322     */

323     @Deprecated JavaDoc
324     public FileObject find(String JavaDoc aPackage, String JavaDoc name, String JavaDoc ext) {
325         assert FileUtil.assertDeprecatedMethod();
326
327         StringBuffer JavaDoc bf = new StringBuffer JavaDoc();
328
329         // append package and name
330
if (!aPackage.equals("")) { // NOI18N
331

332             String JavaDoc p = aPackage.replace('.', '/');
333             bf.append(p);
334             bf.append('/');
335         }
336
337         // append name
338
if (name != null) {
339             bf.append(name);
340         }
341
342         // append extension if there is one
343
if (ext != null) {
344             bf.append('.');
345             bf.append(ext);
346         }
347
348         return findResource(bf.toString());
349     }
350
351     /** Finds a file given its full resource path.
352     * @param name the resource path, e.g. "dir/subdir/file.ext" or "dir/subdir" or "dir"
353     * @return a file object with the given path or
354     * <CODE>null</CODE> if no such file exists
355     */

356     public abstract FileObject findResource(String JavaDoc name);
357
358     /** Returns an array of actions that can be invoked on any file in
359     * this filesystem.
360     * These actions should preferably
361     * support the {@link org.openide.util.actions.Presenter.Menu Menu},
362     * {@link org.openide.util.actions.Presenter.Popup Popup},
363     * and {@link org.openide.util.actions.Presenter.Toolbar Toolbar} presenters.
364     *
365     * @return array of available actions
366     */

367     public abstract SystemAction[] getActions();
368
369     public SystemAction[] getActions(Set JavaDoc<FileObject> foSet) {
370         return this.getActions();
371     }
372
373     /** Reads object from stream and creates listeners.
374     * @param in the input stream to read from
375     * @exception IOException error during read
376     * @exception ClassNotFoundException when class not found
377     */

378     private void readObject(java.io.ObjectInputStream JavaDoc in)
379     throws java.io.IOException JavaDoc, java.lang.ClassNotFoundException JavaDoc {
380         in.defaultReadObject();
381
382         if (capability != null) {
383             capability.addPropertyChangeListener(getCapabilityChangeListener());
384         }
385     }
386
387     public String JavaDoc toString() {
388         return getSystemName() + "[" + super.toString() + "]"; // NOI18N
389
}
390
391     /** Allows filesystems to set up the environment for external execution
392     * and compilation.
393     * Each filesystem can add its own values that
394     * influence the environment. The set of operations that can modify
395     * environment is described by the {@link Environment} interface.
396     * <P>
397     * The default implementation throws an exception to signal that it does not
398     * support external compilation or execution.
399     *
400     * @param env the environment to setup
401     * @exception EnvironmentNotSupportedException if external execution
402     * and compilation cannot be supported
403     * @deprecated Please use the <a HREF="@org-netbeans-api-java@/org/netbeans/api/java/classpath/ClassPath.html">ClassPath API</a> instead.
404     */

405     @Deprecated JavaDoc
406     public void prepareEnvironment(Environment env) throws EnvironmentNotSupportedException {
407         throw new EnvironmentNotSupportedException(this);
408     }
409
410     /** Get a status object that can annotate a set of files by changing the names or icons
411     * associated with them.
412     * <P>
413     * The default implementation returns a status object making no modifications.
414     *
415     * @return the status object for this filesystem
416     */

417     public Status getStatus() {
418         return STATUS_NONE;
419     }
420
421     /** The object describing capabilities of this filesystem.
422     * Subclasses cannot override it.
423      * @deprecated Capabilities are no longer used.
424     */

425     @Deprecated JavaDoc
426     public final FileSystemCapability getCapability() {
427         if (capability == null) {
428             capability = new FileSystemCapability.Bean();
429             capability.addPropertyChangeListener(getCapabilityChangeListener());
430         }
431
432         return capability;
433     }
434
435     /** Allows subclasses to change a set of capabilities of the
436     * filesystem.
437     * @param capability the capability to use
438      * @deprecated Capabilities are no longer used.
439     */

440     @Deprecated JavaDoc
441     protected final void setCapability(FileSystemCapability capability) {
442         if (this.capability != null) {
443             this.capability.removePropertyChangeListener(getCapabilityChangeListener());
444         }
445
446         this.capability = capability;
447
448         if (this.capability != null) {
449             this.capability.addPropertyChangeListener(getCapabilityChangeListener());
450         }
451     }
452
453     /** Executes atomic action. The atomic action represents a set of
454     * operations constituting one logical unit. It is guaranteed that during
455     * execution of such an action no events about changes in the filesystem
456     * will be fired.
457     * <P>
458     * <em>Warning:</em> the action should not take a significant amount of time, and should finish as soon as
459     * possible--otherwise all event notifications will be blocked.
460     * <p><strong>Warning:</strong> do not be misled by the name of this method;
461     * it does not require the filesystem to treat the changes as an atomic block of
462     * commits in the database sense! That is, if an exception is thrown in the middle
463     * of the action, partial results will not be undone (in general this would be
464     * impossible to implement for all filesystems anyway).
465     * @param run the action to run
466     * @exception IOException if there is an <code>IOException</code> thrown in the actions' {@link AtomicAction#run run}
467     * method
468     */

469     public final void runAtomicAction(final AtomicAction run)
470     throws IOException JavaDoc {
471         getEventControl().runAtomicAction(run);
472     }
473
474     /**
475      * Begin of block, that should be performed without firing events.
476      * Firing of events is postponed after end of block .
477      * There is strong necessity to use always both methods: beginAtomicAction
478      * and finishAtomicAction. It is recomended use it in try - finally block.
479      * @param run Events fired from this atomic action will be marked as events
480      * that were fired from this run.
481      */

482     void beginAtomicAction(FileSystem.AtomicAction run) {
483         getEventControl().beginAtomicAction(run);
484     }
485
486     void beginAtomicAction() {
487         beginAtomicAction(null);
488     }
489
490     /**
491      * End of block, that should be performed without firing events.
492      * Firing of events is postponed after end of block .
493      * There is strong necessity to use always both methods: beginAtomicAction
494      * and finishAtomicAction. It is recomended use it in try - finally block.
495      */

496     void finishAtomicAction() {
497         getEventControl().finishAtomicAction();
498     }
499
500     /**
501      * Inside atomicAction adds an event dispatcher to the queue of FS events
502      * and firing of events is postponed. If not event handlers are called directly.
503      * @param run dispatcher to run
504      */

505     void dispatchEvent(EventDispatcher run) {
506         getEventControl().dispatchEvent(run);
507     }
508
509     /** returns property listener on FileSystemCapability. */
510     private synchronized PropertyChangeListener JavaDoc getCapabilityChangeListener() {
511         if (capabilityListener == null) {
512             capabilityListener = new PropertyChangeListener JavaDoc() {
513                         public void propertyChange(java.beans.PropertyChangeEvent JavaDoc propertyChangeEvent) {
514                             firePropertyChange(
515                                 PROP_CAPABILITIES, propertyChangeEvent.getOldValue(), propertyChangeEvent.getNewValue()
516                             );
517                         }
518                     };
519         }
520
521         return capabilityListener;
522     }
523
524     private final EventControl getEventControl() {
525         EventControl evnCtrl = thrLocal.get();
526
527         if (evnCtrl == null) {
528             thrLocal.set(evnCtrl = new EventControl());
529         }
530
531         return evnCtrl;
532     }
533
534     /** Registers FileStatusListener to receive events.
535     * The implementation registers the listener only when getStatus () is
536     * overriden to return a special value.
537     *
538     * @param listener The listener to register.
539     */

540     public final void addFileStatusListener(FileStatusListener listener) {
541         synchronized (internLock) {
542             // JST: Ok? Do not register listeners when the fs cannot change status?
543
if (getStatus() == STATUS_NONE) {
544                 return;
545             }
546
547             if (fileStatusList == null) {
548                 fileStatusList = new ListenerList<FileStatusListener>();
549             }
550
551             fileStatusList.add(listener);
552         }
553     }
554
555     /** Removes FileStatusListener from the list of listeners.
556      *@param listener The listener to remove.
557      */

558     public final void removeFileStatusListener(FileStatusListener listener) {
559         if (fileStatusList == null) {
560             return;
561         }
562
563         fileStatusList.remove(listener);
564     }
565
566     /** Notifies all registered listeners about change of status of some files.
567     *
568     * @param event The event to be fired
569     */

570     protected final void fireFileStatusChanged(FileStatusEvent event) {
571         if (fileStatusList == null) {
572             return;
573         }
574
575         List JavaDoc<FileStatusListener> listeners = fileStatusList.getAllListeners();
576         dispatchEvent(new FileStatusDispatcher(listeners, event));
577     }
578
579     /** Adds listener for the veto of property change.
580     * @param listener the listener
581     */

582     public final void addVetoableChangeListener(VetoableChangeListener JavaDoc listener) {
583         synchronized (internLock) {
584             if (vetoableChangeList == null) {
585                 vetoableChangeList = new ListenerList<VetoableChangeListener JavaDoc>();
586             }
587
588             vetoableChangeList.add(listener);
589         }
590     }
591
592     /** Removes listener for the veto of property change.
593     * @param listener the listener
594     */

595     public final void removeVetoableChangeListener(VetoableChangeListener JavaDoc listener) {
596         if (vetoableChangeList == null) {
597             return;
598         }
599
600         vetoableChangeList.remove(listener);
601     }
602
603     /** Fires property vetoable event.
604     * @param name name of the property
605     * @param o old value of the property
606     * @param n new value of the property
607     * @exception PropertyVetoException if an listener vetoed the change
608     */

609     protected final void fireVetoableChange(String JavaDoc name, Object JavaDoc o, Object JavaDoc n)
610     throws PropertyVetoException JavaDoc {
611         if (vetoableChangeList == null) {
612             return;
613         }
614
615         PropertyChangeEvent JavaDoc e = null;
616
617         for (VetoableChangeListener JavaDoc l : vetoableChangeList.getAllListeners()) {
618             if (e == null) {
619                 e = new PropertyChangeEvent JavaDoc(this, name, o, n);
620             }
621
622             l.vetoableChange(e);
623         }
624     }
625
626     /** Registers PropertyChangeListener to receive events.
627     *@param listener The listener to register.
628     */

629     public final void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
630         synchronized (internLock) {
631             if (changeSupport == null) {
632                 changeSupport = new PropertyChangeSupport JavaDoc(this);
633             }
634         }
635
636         changeSupport.addPropertyChangeListener(listener);
637     }
638
639     /** Removes PropertyChangeListener from the list of listeners.
640     *@param listener The listener to remove.
641     */

642     public final void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
643         if (changeSupport != null) {
644             changeSupport.removePropertyChangeListener(listener);
645         }
646     }
647
648     /** Fires property change event.
649     * @param name name of the property
650     * @param o old value of the property
651     * @param n new value of the property
652     */

653     protected final void firePropertyChange(String JavaDoc name, Object JavaDoc o, Object JavaDoc n) {
654         firePropertyChange(name, o, n, null);
655     }
656
657     final void firePropertyChange(String JavaDoc name, Object JavaDoc o, Object JavaDoc n, Object JavaDoc propagationId) {
658         if (changeSupport == null) {
659             return;
660         }
661
662         if ((o != null) && (n != null) && o.equals(n)) {
663             return;
664         }
665
666         PropertyChangeEvent JavaDoc e = new PropertyChangeEvent JavaDoc(this, name, o, n);
667         e.setPropagationId(propagationId);
668         changeSupport.firePropertyChange(e);
669     }
670
671     /** Notifies this filesystem that it has been added to the repository.
672     * Various initialization tasks could go here. The default implementation does nothing.
673     * <p>Note that this method is <em>advisory</em> and serves as an optimization
674     * to avoid retaining resources for too long etc. Filesystems should maintain correct
675     * semantics regardless of whether and when this method is called.
676     */

677     public void addNotify() {
678     }
679
680     /** Notifies this filesystem that it has been removed from the repository.
681     * Concrete filesystem implementations could perform clean-up here.
682     * The default implementation does nothing.
683     * <p>Note that this method is <em>advisory</em> and serves as an optimization
684     * to avoid retaining resources for too long etc. Filesystems should maintain correct
685     * semantics regardless of whether and when this method is called.
686     */

687     public void removeNotify() {
688     }
689
690     /** Getter for the resource string
691     * @param s the resource name
692     * @return the resource
693     */

694     static String JavaDoc getString(String JavaDoc s) {
695         /*This call to getBundle should ensure that currentClassLoader is not used to load resources from.
696          This should prevent from deadlock, that occured: one waits for FileObject and has resource,
697          second one waits for resource and has FileObject*/

698         return NbBundle.getBundle(
699             "org.openide.filesystems.Bundle", java.util.Locale.getDefault(), FileSystem.class.getClassLoader()
700         ).getString(s);
701     }
702
703     /** Creates message for given string property with one parameter.
704     * @param s resource name
705     * @param obj the parameter to the message
706     * @return the string for that text
707     */

708     static String JavaDoc getString(String JavaDoc s, Object JavaDoc obj) {
709         return MessageFormat.format(getString(s), new Object JavaDoc[] { obj });
710     }
711
712     /** Creates message for given string property with two parameters.
713     * @param s resource name
714     * @param obj1 the parameter to the message
715     * @param obj2 the parameter to the message
716     * @return the string for that text
717     */

718     static String JavaDoc getString(String JavaDoc s, Object JavaDoc obj1, Object JavaDoc obj2) {
719         return MessageFormat.format(getString(s), new Object JavaDoc[] { obj1, obj2 });
720     }
721
722     /** Creates message for given string property with three parameters.
723     * @param s resource name
724     * @param obj1 the parameter to the message
725     * @param obj2 the parameter to the message
726     * @param obj3 the parameter to the message
727     * @return the string for that text
728     */

729     static String JavaDoc getString(String JavaDoc s, Object JavaDoc obj1, Object JavaDoc obj2, Object JavaDoc obj3) {
730         return MessageFormat.format(getString(s), new Object JavaDoc[] { obj1, obj2, obj3 });
731     }
732
733     /** getter for Repository
734     * @return Repository that contains this FileSystem or null if FileSystem
735     * is not part of any Repository
736     */

737     final Repository getRepository() {
738         return repository;
739     }
740
741     void setRepository(Repository rep) {
742         repository = rep;
743     }
744
745     final FCLSupport getFCLSupport() {
746         synchronized (FCLSupport.class) {
747             if (fclSupport == null) {
748                 fclSupport = new FCLSupport();
749             }
750         }
751
752         return fclSupport;
753     }
754
755     /** Add new listener to this object.
756     * @param fcl the listener
757     * @since 2.8
758     */

759     public final void addFileChangeListener(FileChangeListener fcl) {
760         getFCLSupport().addFileChangeListener(fcl);
761     }
762
763     /** Remove listener from this object.
764     * @param fcl the listener
765     * @since 2.8
766     */

767     public final void removeFileChangeListener(FileChangeListener fcl) {
768         getFCLSupport().removeFileChangeListener(fcl);
769     }
770
771     /** An action that it is to be called atomically with respect to filesystem event notification.
772     * During its execution (via {@link FileSystem#runAtomicAction runAtomicAction})
773     * no events about changes in filesystems are fired.
774      * <p><strong>Nomenclature warning:</strong> the action is by no means "atomic"
775      * in the usual sense of the word, i.e. either running to completion or rolling
776      * back. There is no rollback support. The actual semantic property here is
777      * close to "isolation" - the action appears as a single operation as far as
778      * listeners are concerned - but not quite, since it is perfectly possible for
779      * some other thread to see half of the action if it happens to run during
780      * that time. Generally it is a mistake to assume that using AtomicAction gives
781      * you any kind of consistency guarantees; rather, it avoids producing change
782      * events too early and thus causing listener code to run before it should.
783     */

784     public static interface AtomicAction {
785         /** Executed when it is guaranteed that no events about changes
786         * in filesystems will be notified.
787         *
788         * @exception IOException if there is an error during execution
789         */

790         public void run() throws IOException JavaDoc;
791     }
792
793     /** Allows a filesystem to annotate a group of files (typically comprising a data object) with additional markers.
794      * <p>This could be useful, for
795     * example, for a filesystem supporting version control.
796     * It could annotate names and icons of data nodes according to whether the files were current, locked, etc.
797     */

798     public static interface Status {
799         /** Annotate the name of a file cluster.
800         * @param name the name suggested by default
801         * @param files an immutable set of {@link FileObject}s belonging to this filesystem
802         * @return the annotated name (may be the same as the passed-in name)
803         * @exception ClassCastException if the files in the set are not of valid types
804         */

805         public String JavaDoc annotateName(String JavaDoc name, Set JavaDoc<? extends FileObject> files);
806
807         /** Annotate the icon of a file cluster.
808          * <p>Please do <em>not</em> modify the original; create a derivative icon image,
809          * using a weak-reference cache if necessary.
810         * @param icon the icon suggested by default
811         * @param iconType an icon type from {@link java.beans.BeanInfo}
812         * @param files an immutable set of {@link FileObject}s belonging to this filesystem
813         * @return the annotated icon (may be the same as the passed-in icon)
814         * @exception ClassCastException if the files in the set are not of valid types
815         */

816         public Image JavaDoc annotateIcon(Image JavaDoc icon, int iconType, Set JavaDoc<? extends FileObject> files);
817     }
818
819     /** Extension interface for Status provides HTML-formatted annotations.
820      * Principally this is used to de&euml;mphasize status text by presenting
821      * it in a lighter color, by placing it inside
822      * &lt;font color=!controlShadow&gt; tags. Note that it is preferable to
823      * use logical colors (such as controlShadow) which are resolved by calling
824      * UIManager.getColor(key) &mdash; this way they will always fit with the
825      * look and feel. To use a logical color, prefix the color name with a
826      * ! character.
827      * <p>
828      * Please use only the limited markup subset of HTML supported by the
829      * lightweight HTML renderer.
830      * @see org.openide.awt.HtmlRenderer
831      * @since 4.30
832      */

833     public static interface HtmlStatus extends Status {
834         /** Annotate a name such that the returned value contains HTML markup.
835          * The return value less the HTML content should typically be the same
836          * as the return value from <code>annotateName()</code>. This is used,
837          * for example, by VCS filesystems to de&euml;mphasize the status information
838          * included in the file name by using a light grey font color.
839          * <p>
840          * For consistency with <code>Node.getHtmlDisplayName()</code>,
841          * filesystems that proxy other filesystems (and so must implement
842          * this interface to supply HTML annotations) should return null if
843          * the filesystem they proxy does not provide an implementation of
844          * {@link FileSystem.HtmlStatus}.
845          * @param name the name suggested by default
846          * @param files an immutable set of files belonging to this filesystem
847          * @return the annotated name (XXX may it be the same as the passed-in name or should it then be null?)
848          * @since 4.30
849          * @see org.openide.awt.HtmlRenderer
850          * @see <a HREF="@OPENIDE/LOADERS@/org/openide/loaders/DataNode.html#getHtmlDisplayName()"><code>DataNode.getHtmlDisplayName()</code></a>
851          * @see org.openide.nodes.Node#getHtmlDisplayName
852          **/

853         public String JavaDoc annotateNameHtml(String JavaDoc name, Set JavaDoc<? extends FileObject> files);
854     }
855
856     /** Interface that allows filesystems to set up the Java environment
857     * for external execution and compilation.
858     * Currently just used to append entries to the external class path.
859     * @deprecated Please use the <a HREF="@org-netbeans-api-java@/org/netbeans/api/java/classpath/ClassPath.html">ClassPath API</a> instead.
860     */

861     @Deprecated JavaDoc
862     public static abstract class Environment extends Object JavaDoc {
863         public Environment() {
864             assert FileUtil.assertDeprecatedMethod();
865         }
866
867         /** Adds one element to the class path environment variable.
868         * @param classPathElement string representing the one element
869         * @deprecated Please use the <a HREF="@org-netbeans-api-java@/org/netbeans/api/java/classpath/ClassPath.html">ClassPath API</a> instead.
870         */

871         @Deprecated JavaDoc
872         public void addClassPath(String JavaDoc classPathElement) {
873         }
874     }
875
876     /** Class used to notify events for the filesystem.
877     */

878     static abstract class EventDispatcher extends Object JavaDoc implements Runnable JavaDoc {
879         public final void run() {
880             dispatch(false);
881         }
882
883         /** @param onlyPriority if true then invokes only priority listeners
884          * else all listeners are invoked.
885          */

886         protected abstract void dispatch(boolean onlyPriority);
887
888         /** @param propID */
889         protected abstract void setAtomicActionLink(EventControl.AtomicActionLink propID);
890     }
891
892     private static class FileStatusDispatcher extends EventDispatcher {
893         private List JavaDoc<FileStatusListener> listeners;
894         private FileStatusEvent fStatusEvent;
895
896         public FileStatusDispatcher(List JavaDoc<FileStatusListener> listeners, FileStatusEvent fStatusEvent) {
897             this.listeners = listeners;
898             this.fStatusEvent = fStatusEvent;
899         }
900
901         protected void dispatch(boolean onlyPriority) {
902             if (onlyPriority) {
903                 return;
904             }
905
906             for (FileStatusListener fStatusListener : listeners) {
907                 fStatusListener.annotationChanged(fStatusEvent);
908             }
909         }
910
911         protected void setAtomicActionLink(EventControl.AtomicActionLink propID) {
912             /** empty no fireFrom in FileStatusEvent*/
913         }
914     }
915 }
916
Popular Tags