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

Last change on this file since 4366 was 4366, checked in by kjdon, 21 years ago

re-tabbed the code for java

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