KickJava   Java API By Example, From Geeks To Geeks.

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


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.PropertyVetoException JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.lang.ref.Reference JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.text.MessageFormat JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.EventObject JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.logging.Level JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38 import javax.swing.Action JavaDoc;
39 import org.openide.actions.CopyAction;
40 import org.openide.actions.CutAction;
41 import org.openide.actions.DeleteAction;
42 import org.openide.actions.PasteAction;
43 import org.openide.actions.PropertiesAction;
44 import org.openide.actions.ToolsAction;
45 import org.openide.filesystems.FileEvent;
46 import org.openide.filesystems.FileObject;
47 import org.openide.filesystems.FileStateInvalidException;
48 import org.openide.filesystems.Repository;
49 import org.openide.filesystems.URLMapper;
50 import org.openide.nodes.Children;
51 import org.openide.nodes.Node;
52 import org.openide.nodes.Node.Property;
53 import org.openide.nodes.Node.PropertySet;
54 import org.openide.nodes.PropertySupport;
55 import org.openide.nodes.Sheet;
56 import org.openide.util.HelpCtx;
57 import org.openide.util.actions.SystemAction;
58
59 /** For representing data shadows with broken link to original file.
60 * Since 1.13 it extends MultiDataObject.
61 * @author Ales Kemr
62 */

63 final class BrokenDataShadow extends MultiDataObject {
64     /** Name of original fileobject */
65     private URL JavaDoc url;
66         
67     /** Constructs new broken data shadow for given primary file.
68     *
69     * @param fo the primary file
70     * @param loader the loader that created the object
71     */

72     public BrokenDataShadow (
73         FileObject fo, MultiFileLoader loader
74     ) throws DataObjectExistsException {
75         super (fo, loader);
76         
77         try {
78             url = DataShadow.readURL(fo);
79         } catch (IOException JavaDoc ex) {
80             try {
81                 url = new URL JavaDoc("file",null,"/UNKNOWN"); //NOI18N
82
} catch (MalformedURLException JavaDoc ex2) {
83                 Logger.getLogger(BrokenDataShadow.class.getName()).log(Level.WARNING, null, ex2);
84             }
85         }
86         enqueueBrokenDataShadow(this);
87     }
88         
89     /** Map of <String(nameoffileobject), DataShadow> */
90     private static Map JavaDoc<String JavaDoc, Set JavaDoc<Reference JavaDoc<BrokenDataShadow>>> allDataShadows;
91     
92     private static final long serialVersionUID = -3046981691235483810L;
93     
94     /** Getter for the Set that contains all DataShadows. */
95     static synchronized Map JavaDoc<String JavaDoc, Set JavaDoc<Reference JavaDoc<BrokenDataShadow>>> getDataShadowsSet() {
96        if (allDataShadows == null) {
97            allDataShadows = new HashMap JavaDoc<String JavaDoc, Set JavaDoc<Reference JavaDoc<BrokenDataShadow>>>();
98        }
99         return allDataShadows;
100     }
101     
102     private static synchronized void enqueueBrokenDataShadow(BrokenDataShadow ds) {
103         Map JavaDoc<String JavaDoc, Set JavaDoc<Reference JavaDoc<BrokenDataShadow>>> m = getDataShadowsSet ();
104         
105         String JavaDoc prim = ds.getUrl().toExternalForm();
106         Reference JavaDoc<BrokenDataShadow> ref = new DataShadow.DSWeakReference<BrokenDataShadow>(ds);
107         Set JavaDoc<Reference JavaDoc<BrokenDataShadow>> s = m.get (prim);
108         if (s == null) {
109             s = java.util.Collections.<Reference JavaDoc<BrokenDataShadow>>singleton (ref);
110             getDataShadowsSet ().put (prim, s);
111         } else {
112             if (! (s instanceof HashSet JavaDoc)) {
113                 s = new HashSet JavaDoc<Reference JavaDoc<BrokenDataShadow>> (s);
114                 getDataShadowsSet ().put (prim, s);
115             }
116             s.add (ref);
117         }
118     }
119
120     /** @return all active DataShadows or null */
121     private static synchronized List JavaDoc<BrokenDataShadow> getAllDataShadows() {
122         if (allDataShadows == null || allDataShadows.isEmpty()) {
123             return null;
124         }
125         
126         List JavaDoc<BrokenDataShadow> ret = new ArrayList JavaDoc<BrokenDataShadow>(allDataShadows.size());
127         Iterator JavaDoc<Set JavaDoc<Reference JavaDoc<BrokenDataShadow>>> it = allDataShadows.values ().iterator();
128         while (it.hasNext()) {
129             Set JavaDoc<Reference JavaDoc<BrokenDataShadow>> ref = it.next();
130             Iterator JavaDoc<Reference JavaDoc<BrokenDataShadow>> refs = ref.iterator ();
131             while (refs.hasNext ()) {
132                 Reference JavaDoc<BrokenDataShadow> r = refs.next ();
133                 BrokenDataShadow shadow = r.get();
134                 if (shadow != null) {
135                     ret.add(shadow);
136                 }
137             }
138         }
139         
140         return ret;
141     }
142     
143     /** Checks whether a change of the given dataObject
144      * does not revalidate a BrokenDataShadow
145      */

146     static void checkValidity(EventObject JavaDoc ev) {
147         DataObject src = null;
148         if (ev instanceof OperationEvent) {
149             src = ((OperationEvent)ev).getObject();
150         }
151         
152         FileObject file;
153         if (src != null) {
154             file = src.getPrimaryFile ();
155         } else {
156             if (ev instanceof FileEvent) {
157                 file = ((FileEvent)ev).getFile();
158             } else {
159                 return;
160             }
161         }
162         
163         // #43315 hotfix: disable validity checking for non-SFS filesystem
164
try {
165             if (!file.getFileSystem().equals(
166                     Repository.getDefault().getDefaultFileSystem())) {
167                 return;
168             }
169         } catch (FileStateInvalidException e) {
170             // something wrong, exit
171
DataObject.LOG.log(Level.WARNING, e.toString(), e);
172             return;
173         }
174         
175         synchronized (BrokenDataShadow.class) {
176             if (allDataShadows == null || allDataShadows.isEmpty ()) return;
177         }
178         
179         String JavaDoc key;
180         try {
181             key = file.getURL().toExternalForm();
182         } catch (FileStateInvalidException ex) {
183             // OK, exit
184
return;
185         }
186         
187         Set JavaDoc shadows = null;
188         synchronized (BrokenDataShadow.class) {
189             if (allDataShadows == null || allDataShadows.isEmpty ()) return;
190             
191             if (src != null) {
192                 shadows = (Set JavaDoc)allDataShadows.get(key);
193                 if (shadows == null) {
194                     // we know the source of the event and there are no
195
// shadows with such original
196
return;
197                 }
198             }
199         }
200         
201         
202         List JavaDoc all = getAllDataShadows();
203         if (all == null) {
204             return;
205         }
206         
207         int size = all.size();
208         for (int i = 0; i < size; i++) {
209             Object JavaDoc obj = all.get(i);
210             ((BrokenDataShadow) obj).refresh();
211         }
212     }
213     
214     /** Constructs new broken data shadow for given primary file.
215     * @param fo the primary file
216     */

217     private BrokenDataShadow (FileObject fo) throws DataObjectExistsException {
218         this (fo, (MultiFileLoader)DataLoaderPool.getShadowLoader ());
219     }
220     
221     /* Getter for delete action.
222     * @return true if the object can be deleted
223     */

224     public boolean isDeleteAllowed() {
225         return getPrimaryFile().canWrite();
226     }
227
228     /* Check if link to original file is still broken */
229     public void refresh() {
230         try {
231             if (URLMapper.findFileObject(getUrl()) != null) {
232                 /* Link to original file was repaired */
233                 this.setValid(false);
234             }
235         } catch (PropertyVetoException JavaDoc e) {
236             e.printStackTrace();
237         }
238     }
239     
240     /* Getter for copy action.
241     * @return true if the object can be copied
242     */

243     public boolean isCopyAllowed() {
244         return true;
245     }
246
247     /* Getter for move action.
248     * @return true if the object can be moved
249     */

250     public boolean isMoveAllowed() {
251         return getPrimaryFile().canWrite();
252     }
253
254     /* Getter for rename action.
255     * @return true if the object can be renamed
256     */

257     public boolean isRenameAllowed () {
258         return getPrimaryFile().canWrite();
259     }
260
261     /* Help context for this object.
262     * @return help context
263     */

264     public HelpCtx getHelpCtx() {
265         return HelpCtx.DEFAULT_HELP;
266     }
267
268     /* Creates node delegate.
269     */

270     protected Node createNodeDelegate () {
271         return new BrokenShadowNode (this);
272     }
273
274     URL JavaDoc getUrl() {
275         return url;
276     }
277
278     /** Node for a broken shadow object. */
279     private static final class BrokenShadowNode extends DataNode {
280         
281         /** message to create name of node */
282         private static MessageFormat JavaDoc format;
283         
284         /** the sheet computed for this node or null */
285         private Sheet sheet;
286
287         private static final String JavaDoc ICON_NAME = "org/openide/loaders/brokenShadow.gif"; // NOI18N
288

289         /** Create a node.
290          * @param broken data shadow
291          */

292         public BrokenShadowNode (BrokenDataShadow par) {
293             super (par,Children.LEAF);
294             setIconBaseWithExtension(ICON_NAME);
295         }
296         
297         /** Get the display name for the node.
298          * A filesystem may {@link org.openide.filesystems.FileSystem#getStatus specially alter} this.
299          * @return the desired name
300         */

301         public String JavaDoc getDisplayName () {
302             if (format == null) {
303                 format = new MessageFormat JavaDoc (DataObject.getString ("FMT_brokenShadowName"));
304             }
305             return format.format (createArguments ());
306         }
307         
308         public Action JavaDoc[] getActions(boolean context) {
309             return new Action JavaDoc[] {
310                         SystemAction.get (CutAction.class),
311                         SystemAction.get (CopyAction.class),
312                         SystemAction.get (PasteAction.class),
313                         null,
314                         SystemAction.get (DeleteAction.class),
315                         null,
316                         SystemAction.get (ToolsAction.class),
317                         SystemAction.get (PropertiesAction.class)
318                     };
319         }
320     
321         /** Returns modified properties of the original node.
322         * @return property sets
323         */

324         public PropertySet[] getPropertySets () {
325             if (sheet == null) {
326                 sheet = cloneSheet ();
327             }
328             return sheet.toArray ();
329         }
330         
331         /** Clones the property sheet of original node.
332         */

333         private Sheet cloneSheet () {
334             PropertySet[] sets = super.getPropertySets ();
335
336             Sheet s = new Sheet ();
337             for (int i = 0; i < sets.length; i++) {
338                 Sheet.Set ss = new Sheet.Set ();
339                 ss.put (sets[i].getProperties ());
340                 ss.setName (sets[i].getName ());
341                 ss.setDisplayName (sets[i].getDisplayName ());
342                 ss.setShortDescription (sets[i].getShortDescription ());
343
344                 // modifies the set if it contains name of object property
345
modifySheetSet (ss);
346                 
347                 s.put (ss);
348             }
349
350             return s;
351         }
352         
353         /** Modifies the sheet set to contain name of property and name of
354         * original object.
355         */

356         private void modifySheetSet (Sheet.Set ss) {
357             Property p = ss.remove (DataObject.PROP_NAME);
358             if (p != null) {
359                 p = new PropertySupport.Name (this);
360                 ss.put (p);
361
362                 p = new Name ();
363                 ss.put (p);
364             }
365         }
366         
367         /** Creates arguments for given shadow node */
368         private Object JavaDoc[] createArguments () {
369             return new Object JavaDoc[] {
370                        getDataObject().getName ()
371                    };
372         }
373     
374         /** Class for original name property of broken link
375         */

376         private final class Name extends PropertySupport.ReadWrite<String JavaDoc> {
377             
378             public Name () {
379                 super (
380                     "BrokenLink", // NOI18N
381
String JavaDoc.class,
382                     DataObject.getString ("PROP_brokenShadowOriginalName"),
383                     DataObject.getString ("HINT_brokenShadowOriginalName")
384                 );
385             }
386
387             /* Getter */
388             public String JavaDoc getValue () {
389                 BrokenDataShadow bds = (BrokenDataShadow)getDataObject();
390                 return bds.getUrl().toExternalForm();
391             }
392             
393             /* Does nothing, property is readonly */
394             public void setValue (String JavaDoc newLink) {
395                 BrokenDataShadow bds = (BrokenDataShadow)getDataObject();
396                 try {
397                     URL JavaDoc u = new URL JavaDoc(newLink);
398                     DataShadow.writeOriginal(bds.getPrimaryFile(), u);
399                     bds.url = u;
400                 } catch (IOException JavaDoc ex) {
401                     throw (IllegalArgumentException JavaDoc) new IllegalArgumentException JavaDoc(ex.toString()).initCause(ex);
402                 }
403                 bds.refresh ();
404             }
405         }
406         
407     }
408 }
409
Popular Tags