source: trunk/gli/src/org/greenstone/gatherer/file/FileNode.java@ 11762

Last change on this file since 11762 was 11762, checked in by mdewsnip, 18 years ago

Fixed a bug where filtering the workspace tree before opening the "Local Filespace" node would cause an exception on Unix.

  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
Line 
1package org.greenstone.gatherer.file;
2
3import java.io.*;
4import java.util.ArrayList;
5import java.util.Enumeration;
6import javax.swing.*;
7import javax.swing.filechooser.*;
8import javax.swing.tree.*;
9import org.greenstone.gatherer.DebugStream;
10import org.greenstone.gatherer.util.ArrayTools;
11
12
13public abstract class FileNode
14 implements MutableTreeNode
15{
16 protected boolean allows_children = true;
17 protected ArrayList child_nodes = null;
18 protected ArrayList child_nodes_unfiltered = null;
19 protected File file = null;
20 protected FileSystemModel model = null;
21 protected MutableTreeNode parent = null;
22
23
24 public FileNode(File file)
25 {
26 this.file = file;
27
28 // Files cannot have children
29 if (file != null && file.isFile()) {
30 // Cache this result to prevent unceasing missing disk messages being thrown if the
31 // removable media was, um, removed after directory mapped
32 this.allows_children = false;
33 }
34 }
35
36
37 /** Returns the children of the node as an Enumeration. */
38 public Enumeration children()
39 {
40 return new FileEnumeration();
41 }
42
43
44 /** Returns true if the receiver allows children. */
45 public boolean getAllowsChildren()
46 {
47 return allows_children;
48 }
49
50
51 /** Returns the child TreeNode at index childIndex. */
52 public TreeNode getChildAt(int index)
53 {
54 return (TreeNode) child_nodes.get(index);
55 }
56
57
58 /** Returns the number of children TreeNodes the receiver contains. */
59 public int getChildCount()
60 {
61 map();
62
63 // Use the number of (filtered) child nodes
64 if (child_nodes != null) {
65 return child_nodes.size();
66 }
67
68 return 0;
69 }
70
71
72 /** Returns the index of node in the receivers children. */
73 public int getIndex(TreeNode node)
74 {
75 if (child_nodes != null) {
76 return child_nodes.indexOf(node);
77 }
78
79 return -1;
80 }
81
82
83 /** Returns the parent TreeNode of the receiver. */
84 public TreeNode getParent()
85 {
86 return parent;
87 }
88
89
90 /** Adds child to the receiver at index. */
91 public void insert(MutableTreeNode child, int index)
92 {
93 DebugStream.println("Insert " + child + " in " + this + " at index " + index + " [Model: " + model + "]");
94 if (child == null) {
95 return;
96 }
97
98 try {
99 FileNode child_node = (FileNode) child;
100 child_nodes.add(index, child_node);
101 child_node.model = model;
102 child_node.parent = this;
103 }
104 catch (Exception exception) {
105 DebugStream.printStackTrace(exception);
106 }
107 }
108
109
110 /** Returns true if the receiver is a leaf. */
111 public boolean isLeaf()
112 {
113 return (allows_children == false);
114 }
115
116
117 /** Removes the child at index from the receiver. */
118 public void remove(int index)
119 {
120 if (index >= 0 && index < child_nodes.size()) {
121 child_nodes.remove(index);
122 }
123 }
124
125
126 /** Removes node from the receiver. */
127 public void remove(MutableTreeNode node)
128 {
129 remove(getIndex(node));
130 }
131
132
133 /** Removes the receiver from its parent. */
134 public void removeFromParent()
135 {
136 parent.remove(this);
137 parent = null;
138 }
139
140
141 /** Resets the user object of the receiver to object. */
142 public void setUserObject(Object object) {
143 try {
144 file = (File) object;
145 }
146 catch (Exception exception) {
147 DebugStream.printStackTrace(exception);
148 }
149 }
150
151
152 // -------------------------------------------------------------------------------
153
154
155 public void add(MutableTreeNode child)
156 {
157 insert(child, child_nodes.size());
158 }
159
160
161 protected abstract FileNode addChildNode(File file);
162
163
164 /** Compare two FileNodes for equality. */
165 public boolean equals(FileNode node)
166 {
167 if (node == null) {
168 // Definitely not a match
169 return false;
170 }
171
172 if (file != null) {
173 return file.equals(node.getFile());
174 }
175 else {
176 return toString().equals(node.toString());
177 }
178 }
179
180
181 /** Retrieve the file node at the given index, regardless of filters set. */
182 public FileNode getChildAtUnfiltered(int index)
183 {
184 if (index >= 0 && index < size()) {
185 return (FileNode) child_nodes_unfiltered.get(index);
186 }
187 return null;
188 }
189
190
191 public File getFile() {
192 return file;
193 }
194
195
196 /** Retrieves the tree path from the root node to this node. */
197 public TreeNode[] getPath() {
198 int count = 0;
199 TreeNode current = this;
200 while(current != null) {
201 count++;
202 current = current.getParent();
203 }
204 TreeNode[] path = new TreeNode[count];
205 current = this;
206 while(current != null) {
207 path[count - 1] = current;
208 count--;
209 current = current.getParent();
210 }
211 return path;
212 }
213
214
215 public boolean isFileSystemRoot() {
216 if (file != null) {
217 return FileSystemView.getFileSystemView().isFileSystemRoot(file);
218 }
219 else {
220 return false;
221 }
222 }
223
224
225 /** Overridden if necessary by subclasses. */
226 public boolean isInLoadedCollection()
227 {
228 return false;
229 }
230
231
232 /** Overridden if necessary by subclasses. */
233 public boolean isReadOnly()
234 {
235 return false;
236 }
237
238
239 public void map()
240 {
241 // If this node has already been mapped, don't bother doing it again
242 if (child_nodes != null) {
243 return;
244 }
245 child_nodes = new ArrayList();
246
247 // General case, only map if children are allowed
248 if (file != null && getAllowsChildren()) {
249 File[] files = file.listFiles();
250 if (files != null && files.length > 0) {
251 // Sort the child files
252 ArrayTools.sort(files);
253
254 // Now add them to child_nodes_unfiltered
255 child_nodes_unfiltered = new ArrayList();
256 for (int i = 0; i < files.length; i++) {
257 FileNode child_node = this.addChildNode(files[i]);
258 child_nodes_unfiltered.add(child_node);
259 }
260
261 // Apply the filters set in the model
262 FileFilter[] filters = model.getFilters();
263 for (int i = 0; filters != null && i < filters.length; i++) {
264 files = ArrayTools.filter(files, filters[i].filter, filters[i].exclude);
265 }
266
267 // Add the files left after filtering to child_nodes
268 for (int i = 0, j = 0; (i < child_nodes_unfiltered.size() && j < files.length); i++) {
269 // Use the FileNode object in child_nodes_unfiltered rather than creating another
270 FileNode file_node = (FileNode) child_nodes_unfiltered.get(i);
271 if (file_node.getFile().equals(files[j])) {
272 child_nodes.add(file_node);
273 j++;
274 }
275 }
276 }
277
278 model.nodeStructureChanged(this);
279 }
280 }
281
282
283 public void refresh()
284 {
285 unmap();
286 map();
287 }
288
289
290 public void setModel(FileSystemModel model) {
291 this.model = model;
292 }
293
294 public void setParent(MutableTreeNode parent) {
295 this.parent = parent;
296 }
297
298
299 /** Return the total number of child files for the file this node represents, irrespective of filters set. */
300 public int size() {
301 if (child_nodes_unfiltered != null) {
302 return child_nodes_unfiltered.size();
303 }
304 return 0;
305 }
306
307
308 public String toString()
309 {
310 if (isFileSystemRoot()) {
311 return file.getAbsolutePath();
312 }
313 else {
314 return file.getName();
315 }
316 }
317
318
319 /** Unmap this node's children. */
320 public void unmap()
321 {
322 DebugStream.println("Unmapping " + this + "...");
323 child_nodes_unfiltered = null;
324 child_nodes = null;
325 }
326
327
328 private class FileEnumeration
329 implements Enumeration
330 {
331 private int index = 0;
332
333 /** Tests if this enumeration contains more elements. */
334 public boolean hasMoreElements() {
335 return (index < child_nodes.size());
336 }
337
338 /** Returns the next element of this enumeration if this enumeration object has at least one more element to provide. */
339 public Object nextElement() {
340 Object result = null;
341 if (index < child_nodes.size()) {
342 result = child_nodes.get(index);
343 index++;
344 }
345 return result;
346 }
347 }
348}
Note: See TracBrowser for help on using the repository browser.