KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > group > ErrorNode


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.group;
22
23 import java.io.IOException JavaDoc;
24 import java.text.MessageFormat JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import org.openide.ErrorManager;
29 import org.openide.actions.DeleteAction;
30 import org.openide.actions.PropertiesAction;
31 import org.openide.actions.ToolsAction;
32 import org.openide.filesystems.FileAttributeEvent;
33 import org.openide.filesystems.FileChangeAdapter;
34 import org.openide.filesystems.FileChangeListener;
35 import org.openide.filesystems.FileEvent;
36 import org.openide.filesystems.FileObject;
37 import org.openide.filesystems.FileSystem;
38 import org.openide.filesystems.Repository;
39 import org.openide.loaders.DataObject;
40 import org.openide.nodes.AbstractNode;
41 import org.openide.nodes.Children;
42 import org.openide.util.NbBundle;
43 import org.openide.util.actions.SystemAction;
44
45 /** Node representing a broken link. */
46 class ErrorNode extends AbstractNode {
47
48     /**
49      * pattern for names of nodes - when expanded, contains the name
50      * of a non-existing file (broken link)
51      *
52      * @see #nodeNameSimple
53      */

54     private static MessageFormat JavaDoc nodeNameTemplate;
55     /**
56      * name of nodes whose target file name is unknown
57      *
58      * @see #nodeNameTemplate
59      */

60     private static String JavaDoc nodeNameSimple;
61
62     /** group this node's link pertains to */
63     private final GroupShadow group;
64     /** name of a non-existing file */
65     private final String JavaDoc linkName;
66     /**
67      * list of possible parent folders of this node's broken link
68      *
69      * @see #setFolderListening
70      */

71     private FileObject[] parentFolders;
72     /**
73      * <code>FileChangeListener</code> which listens for events
74      * about new created files
75      *
76      * @see #fileCreated
77      */

78     private FileChangeListener fileCreationListener;
79
80
81     /** Creates a new <code>ErrorNode</code>. */
82     public ErrorNode(GroupShadow group) {
83         this(group, null);
84     }
85
86     /**
87      * Creates a new <code>ErrorNode</code>.
88      *
89      * @param linkName broken link (name of a non-existing file)
90      */

91     public ErrorNode(GroupShadow group, String JavaDoc linkName) {
92         super(Children.LEAF);
93
94         this.group = group;
95         this.linkName = linkName;
96
97         systemActions = new SystemAction[] {
98                             SystemAction.get(DeleteAction.class),
99                             null,
100                             SystemAction.get(ToolsAction.class),
101                             SystemAction.get(PropertiesAction.class)
102                         };
103
104         if (linkName != null) {
105             if (nodeNameTemplate == null) {
106                 nodeNameTemplate = new MessageFormat JavaDoc(NbBundle.getMessage(
107                         ErrorNode.class,
108                         "FMT_brokenLinkWithTarget")); //NOI18N
109
}
110             setDisplayName(nodeNameTemplate.format(new Object JavaDoc[] {linkName}));
111             try {
112                 startFolderListening();
113             } catch (Exception JavaDoc ex) {
114                 ErrorManager.getDefault().notify(ErrorManager.ERROR, ex);
115             }
116         } else {
117             if (nodeNameSimple == null) {
118                 nodeNameSimple = NbBundle.getMessage(
119                         ErrorNode.class,
120                         "FMT_brokenLinkWithoutTarget"); //NOI18N
121
}
122             setDisplayName(nodeNameSimple);
123         }
124     }
125
126     /** Destroys node. */
127     public void destroy() throws IOException JavaDoc {
128         boolean modified = false;
129         List JavaDoc list = new ArrayList JavaDoc(group.readLinks());
130         for (Iterator JavaDoc i = list.iterator(); i.hasNext(); ) {
131             String JavaDoc name = (String JavaDoc) i.next();
132             if (name.equals(this.linkName)) {
133                 i.remove();
134                 modified = true;
135             }
136         }
137         if (modified) {
138             group.writeLinks(list);
139         }
140
141         cancelFolderListening();
142     }
143
144     /**
145      * @return always <code>true</code>
146      */

147     public boolean canDestroy() {
148         return true;
149     }
150
151     /**
152      * Starts listening on all folders which could contain a file
153      * matching the broken link's name, so that the broken link can
154      * automatically become a regular link when such file appears.
155      *
156      * @see #cancelFolderListening
157      */

158     private void startFolderListening() {
159         // This link is invalid but its parent could be a valid folder.
160
// So we could watch it creating a new file...
161
int index = linkName.lastIndexOf('/');
162
163         if (index > 0) {
164             String JavaDoc folder = linkName.substring(0, index);
165             DataObject dobj;
166             try {
167                 dobj = GroupShadow.getDataObjectByName(folder, group.getPrimaryFile());
168             } catch (IOException JavaDoc ex) {
169                 return;
170             }
171             if (dobj == null) {
172                 return;
173             }
174             parentFolders = new FileObject[] {dobj.getPrimaryFile()};
175         } else { // use filesystems' folders
176
FileSystem[] fs = Repository.getDefault().toArray();
177             parentFolders = new FileObject[fs.length];
178             for (int i = 0; i < fs.length; i++) {
179                 parentFolders[i] = fs[i].getRoot();
180             }
181         }
182
183         fileCreationListener = new FileChangeAdapter() {
184                 public void fileDataCreated(FileEvent fe) {
185                     fileCreated(GroupShadow.getLinkName(fe.getFile()));
186                 }
187             };
188         for (int i = 0; i < parentFolders.length; i++) {
189             parentFolders[i].addFileChangeListener(fileCreationListener);
190         }
191     }
192
193     /**
194      * Stops listening on folders which could contain a file matching
195      * the broken link's name.
196      *
197      * @see #startFolderListening
198      */

199     private void cancelFolderListening() {
200         if (parentFolders != null) {
201             for (int i = 0; i < parentFolders.length; i++) {
202                 parentFolders[i].removeFileChangeListener(fileCreationListener);
203             }
204             parentFolders = null;
205             fileCreationListener = null;
206         }
207     }
208
209     /**
210      * Checks whether a given file name is equal to the name of this node's
211      * broken links and updates the link if the names are equal.
212      * <p>
213      * This method is called when a file which could match this node's broken
214      * link is created.
215      *
216      * @param fileName name of the file that was just created,
217      * relative to the root of the filesystem
218      * @see #startFolderListening
219      */

220     private void fileCreated(String JavaDoc newFileName) {
221         if (newFileName.equals(linkName)) {
222             cancelFolderListening();
223             GroupNodeChildren children
224                     = (GroupNodeChildren) group.getNodeDelegate().getChildren();
225             children.update();
226         }
227     }
228     
229 }
230
Popular Tags