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

Last change on this file since 8791 was 8791, checked in by mdewsnip, 19 years ago

Ooops... left a debug statement in.

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