KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > loaders > OpenSupport


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.loaders;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.beans.PropertyChangeSupport JavaDoc;
25 import java.beans.PropertyVetoException JavaDoc;
26 import java.beans.VetoableChangeListener JavaDoc;
27 import java.beans.VetoableChangeSupport JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.ObjectInputStream JavaDoc;
30 import java.lang.ref.Reference JavaDoc;
31 import java.lang.ref.WeakReference JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.WeakHashMap JavaDoc;
37 import org.openide.cookies.EditCookie;
38 import org.openide.cookies.EditorCookie;
39 import org.openide.cookies.OpenCookie;
40 import org.openide.filesystems.FileStateInvalidException;
41 import org.openide.filesystems.FileSystem;
42 import org.openide.util.NbBundle;
43 import org.openide.util.WeakSet;
44 import org.openide.windows.CloneableOpenSupport;
45 import org.openide.windows.CloneableTopComponent;
46
47 /** Simple support for an openable file.
48 * Can be used either as an {@link org.openide.cookies.OpenCookie},
49 * {@link org.openide.cookies.ViewCookie}, or {@link org.openide.cookies.CloseCookie},
50 * depending on which cookies the subclass implements.
51 *
52 * @author Jaroslav Tulach
53 */

54 public abstract class OpenSupport extends CloneableOpenSupport {
55     /** Entry to work with. */
56     protected MultiDataObject.Entry entry;
57
58     /** New support for a given entry. The file is taken from the
59     * entry and is updated if the entry moves or renames itself.
60     * @param entry entry to create instance from
61     */

62     public OpenSupport (MultiDataObject.Entry entry) {
63         this (entry, new Env (entry.getDataObject ()));
64     }
65     
66     /** Constructor that allows subclasses to provide their own environment.
67     * Used probably only by EditorSupport.
68     *
69     * @param entry the entry to work on
70     * @param env the environment to work on
71     */

72     protected OpenSupport (MultiDataObject.Entry entry, Env env) {
73         super (env);
74         this.entry = entry;
75     }
76     
77
78     /** Message to display when an object is being opened.
79     * @return the message or null if nothing should be displayed
80     */

81     protected String JavaDoc messageOpening () {
82         DataObject obj = entry.getDataObject ();
83
84         return NbBundle.getMessage (OpenSupport.class , "CTL_ObjectOpen", // NOI18N
85
obj.getName(),
86             obj.getPrimaryFile().toString()
87         );
88     }
89     
90
91     /** Message to display when an object has been opened.
92     * @return the message or null if nothing should be displayed
93     */

94     protected String JavaDoc messageOpened () {
95         return NbBundle.getMessage (OpenSupport.class, "CTL_ObjectOpened");
96     }
97
98
99     /** Method to access all editors from subclasses. Needed for compilation by 1.2
100     */

101     final CloneableTopComponent.Ref allEditors () {
102         return allEditors;
103     }
104
105     /** Environment that connects the support together with DataObject.
106     */

107     public static class Env extends Object JavaDoc
108     implements CloneableOpenSupport.Env, java.io.Serializable JavaDoc,
109     PropertyChangeListener JavaDoc, VetoableChangeListener JavaDoc {
110         /** generated Serialized Version UID */
111         static final long serialVersionUID = -1934890789745432531L;
112         /** object to serialize and be connected to*/
113         private DataObject obj;
114         
115         /** support for firing of property changes
116         */

117         private transient PropertyChangeSupport JavaDoc propSupp;
118         /** support for firing of vetoable changes
119         */

120         private transient VetoableChangeSupport JavaDoc vetoSupp;
121
122         // #27587
123
/** Map of FileSystem to its listener (weak reference of it).
124          * One listener per one filesystem for all env's from that fs. */

125         private static final Map JavaDoc<FileSystem, Reference JavaDoc<FileSystemNameListener>> fsListenerMap =
126                 new WeakHashMap JavaDoc<FileSystem, Reference JavaDoc<FileSystemNameListener>>(30);
127         
128         // A private lock
129
private static final Object JavaDoc LOCK_SUPPORT = new Object JavaDoc();
130         
131         /** Constructor. Attaches itself as listener to
132         * the data object so, all property changes of the data object
133         * are also rethrown to own listeners.
134         *
135         * @param obj data object to be attached to
136         */

137         public Env (DataObject obj) {
138             this.obj = obj;
139             init();
140         }
141         
142         private void readObject (ObjectInputStream JavaDoc ois)
143         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
144             ois.defaultReadObject();
145             init();
146         }
147         
148         private void init() {
149             obj.addPropertyChangeListener(org.openide.util.WeakListeners.propertyChange(this, obj));
150
151             // XXX #25400. Ugly patch for being able to react
152
// on change of root directory of filesystem, see more in the issue.
153
final FileSystem fs;
154             try {
155                 fs = obj.getPrimaryFile().getFileSystem();
156             } catch(FileStateInvalidException fsie) {
157                 throw (IllegalStateException JavaDoc) new IllegalStateException JavaDoc("FileSystem is invalid for " + obj.getPrimaryFile() + "!").initCause(fsie); // NOI18N
158
}
159
160             FileSystemNameListener fsListener;
161             boolean initListening = false;
162             synchronized(fsListenerMap) {
163                 Reference JavaDoc<FileSystemNameListener> fsListenerRef = fsListenerMap.get(fs);
164                 fsListener = fsListenerRef == null
165                                 ? null
166                                 : fsListenerRef.get();
167                         
168                 if(fsListener == null) {
169                     // Create listener for that filesystem.
170
fsListener = new FileSystemNameListener();
171                     fsListenerMap.put(fs, new WeakReference JavaDoc<FileSystemNameListener>(fsListener));
172                     initListening = true;
173                 }
174             }
175
176             if(initListening) {
177                 fs.addPropertyChangeListener(fsListener);
178                 fs.addVetoableChangeListener(fsListener);
179             }
180
181             fsListener.add(this);
182             // End of patch #25400.
183
}
184         
185         /** Getter for data object.
186         */

187         protected final DataObject getDataObject () {
188             return obj;
189         }
190
191         /** Adds property listener.
192          */

193         public void addPropertyChangeListener(PropertyChangeListener JavaDoc l) {
194             prop ().addPropertyChangeListener (l);
195         }
196
197         /** Removes property listener.
198          */

199         public void removePropertyChangeListener(PropertyChangeListener JavaDoc l) {
200             prop ().removePropertyChangeListener (l);
201         }
202
203         /** Adds veto listener.
204          */

205         public void addVetoableChangeListener(VetoableChangeListener JavaDoc l) {
206             veto ().addVetoableChangeListener (l);
207         }
208
209         /** Removes veto listener.
210          */

211         public void removeVetoableChangeListener(VetoableChangeListener JavaDoc l) {
212             veto ().removeVetoableChangeListener (l);
213         }
214
215         /** Test whether the support is in valid state or not.
216         * It could be invalid after deserialization when the object it
217         * referenced to does not exist anymore.
218         *
219         * @return true or false depending on its state
220         */

221         public boolean isValid () {
222             return getDataObject ().isValid ();
223         }
224         
225         /** Test whether the object is modified or not.
226          * @return true if the object is modified
227          */

228         public boolean isModified() {
229             return getDataObject ().isModified ();
230         }
231
232         /** Support for marking the environement modified.
233         * @exception IOException if the environment cannot be marked modified
234         * (for example when the file is readonly), when such exception
235         * is the support should discard all previous changes
236         */

237         public void markModified() throws java.io.IOException JavaDoc {
238             getDataObject ().setModified (true);
239         }
240         
241         /** Reverse method that can be called to make the environment
242         * unmodified.
243         */

244         public void unmarkModified() {
245             getDataObject ().setModified (false);
246         }
247         
248         /** Method that allows environment to find its
249          * cloneable open support.
250         * @return the support or null if the environment is not in valid
251         * state and the CloneableOpenSupport cannot be found for associated
252         * data object
253         */

254         public CloneableOpenSupport findCloneableOpenSupport() {
255             OpenCookie oc = getDataObject().getCookie(OpenCookie.class);
256             if (oc != null && oc instanceof CloneableOpenSupport) {
257                 return (CloneableOpenSupport) oc;
258             }
259             EditCookie edc = getDataObject().getCookie(EditCookie.class);
260             if (edc != null && edc instanceof CloneableOpenSupport) {
261                 return (CloneableOpenSupport) edc;
262             }
263             EditorCookie ec = getDataObject().getCookie(EditorCookie.class);
264             if (ec != null && ec instanceof CloneableOpenSupport) {
265                 return (CloneableOpenSupport) ec;
266             }
267             return null;
268         }
269         
270         /** Accepts property changes from DataObject and fires them to
271         * own listeners.
272         */

273         public void propertyChange(PropertyChangeEvent JavaDoc ev) {
274             if (DataObject.PROP_MODIFIED.equals (ev.getPropertyName())) {
275                 if (getDataObject ().isModified ()) {
276                     getDataObject ().addVetoableChangeListener(this);
277                 } else {
278                     getDataObject ().removeVetoableChangeListener(this);
279                 }
280             }
281             
282             firePropertyChange (
283                 ev.getPropertyName (),
284                 ev.getOldValue (),
285                 ev.getNewValue ()
286             );
287         }
288         
289         /** Accepts vetoable changes and fires them to own listeners.
290         */

291         public void vetoableChange(PropertyChangeEvent JavaDoc ev) throws PropertyVetoException JavaDoc {
292             fireVetoableChange (
293                 ev.getPropertyName (),
294                 ev.getOldValue (),
295                 ev.getNewValue ()
296             );
297         }
298         
299         /** Fires property change.
300         * @param name the name of property that changed
301         * @param oldValue old value
302         * @param newValue new value
303         */

304         protected void firePropertyChange (String JavaDoc name, Object JavaDoc oldValue, Object JavaDoc newValue) {
305             prop ().firePropertyChange (name, oldValue, newValue);
306         }
307         
308         /** Fires vetoable change.
309         * @param name the name of property that changed
310         * @param oldValue old value
311         * @param newValue new value
312         */

313         protected void fireVetoableChange (String JavaDoc name, Object JavaDoc oldValue, Object JavaDoc newValue)
314         throws PropertyVetoException JavaDoc {
315             veto ().fireVetoableChange (name, oldValue, newValue);
316         }
317         
318         /** Lazy getter for change support.
319         */

320         private PropertyChangeSupport JavaDoc prop () {
321             synchronized (LOCK_SUPPORT) {
322                 if (propSupp == null) {
323                     propSupp = new PropertyChangeSupport JavaDoc (this);
324                 }
325                 return propSupp;
326             }
327         }
328         
329         /** Lazy getter for veto support.
330         */

331         private VetoableChangeSupport JavaDoc veto () {
332             synchronized (LOCK_SUPPORT) {
333                 if (vetoSupp == null) {
334                     vetoSupp = new VetoableChangeSupport JavaDoc (this);
335                 }
336                 return vetoSupp;
337             }
338         }
339     }
340     
341     
342     /** Listener for <code>FileSystem.PROP_SYSTEM_NAME</code> proeperty. */
343     private static final class FileSystemNameListener
344     implements PropertyChangeListener JavaDoc, VetoableChangeListener JavaDoc {
345         /** Set of Env's interested in changes on fs name. */
346         private final Set JavaDoc<Env> environments = new WeakSet<Env>(30);
347         
348         public FileSystemNameListener() {
349         }
350
351         /** Adds another Env which is interested on fs name changes. */
352         public void add(Env env) {
353             synchronized(environments) {
354                 environments.add(env);
355             }
356         }
357         
358         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
359             if(FileSystem.PROP_SYSTEM_NAME.equals(evt.getPropertyName())) {
360                 Set JavaDoc<Env> envs;
361                 synchronized(environments) {
362                     envs = new HashSet JavaDoc<Env>(environments);
363                 }
364                 
365                 for(Env env: envs){
366                     env.firePropertyChange(DataObject.PROP_VALID,
367                         Boolean.TRUE, Boolean.FALSE);
368                 }
369             }
370         }
371         
372         public void vetoableChange(PropertyChangeEvent JavaDoc evt)
373         throws PropertyVetoException JavaDoc {
374             if(FileSystem.PROP_SYSTEM_NAME.equals(evt.getPropertyName())) {
375                 Set JavaDoc<Env> envs;
376                 synchronized(environments) {
377                     envs = new HashSet JavaDoc<Env>(environments);
378                 }
379                 
380                 for(Env env: envs) {
381                     env.fireVetoableChange(DataObject.PROP_VALID,
382                         Boolean.TRUE, Boolean.FALSE);
383                 }
384             }
385         }
386     } // End of class FileSystemNameListener.
387

388     /** Only for backward compatibility of settings
389     */

390     private static final class Listener extends CloneableTopComponent.Ref {
391         /** generated Serialized Version UID */
392         static final long serialVersionUID = -1934890789745432531L;
393         /** entry to serialize */
394         private MultiDataObject.Entry entry;
395         
396         Listener() {}
397
398         public Object JavaDoc readResolve () {
399             DataObject obj = entry.getDataObject ();
400             OpenSupport os = null;
401             OpenCookie oc = obj.getCookie(OpenCookie.class);
402             if (oc != null && oc instanceof OpenSupport) {
403                 os = (OpenSupport) oc;
404             } else {
405                 EditCookie edc = obj.getCookie(EditCookie.class);
406                 if (edc != null && edc instanceof OpenSupport) {
407                     os = (OpenSupport) edc;
408                 } else {
409                     EditorCookie ec = obj.getCookie(EditorCookie.class);
410                     if (ec != null && ec instanceof OpenSupport) {
411                         os = (OpenSupport) ec;
412                     }
413                 }
414             }
415             if (os == null) {
416                 // problem! no replace!?
417
return this;
418             }
419             // use the editor support's CloneableTopComponent.Ref
420
return os.allEditors ();
421         }
422     }
423 }
424
425
Popular Tags