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

Last change on this file since 5785 was 5785, checked in by mdewsnip, 21 years ago

Commented out about 60 unused functions.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
Line 
1package org.greenstone.gatherer.file;
2
3import java.io.*;
4import java.util.*;
5import javax.swing.*;
6import javax.swing.filechooser.*;
7import javax.swing.tree.*;
8import org.greenstone.gatherer.Dictionary;
9import org.greenstone.gatherer.Gatherer;
10import org.greenstone.gatherer.file.FileFilter;
11import org.greenstone.gatherer.file.FileSystemModel;
12import org.greenstone.gatherer.util.ArrayTools;
13import org.greenstone.gatherer.util.StaticStrings;
14import org.greenstone.gatherer.util.Utility;
15
16public class FileNode
17 implements MutableTreeNode {
18
19 static final private int FALSE = 0;
20 static final private int TRUE = 1;
21 static final private int UNKNOWN = 2;
22
23 private ArrayList children;
24 private boolean children_readonly = true;
25 private boolean readonly = true;
26 private File file;
27 private FileSystemModel model;
28 private int allows_children = UNKNOWN;
29 private MutableTreeNode parent;
30 private String title;
31
32 public FileNode(File file) {
33 ///ystem.err.println("New FileNode(" + file.getAbsolutePath() + ")");
34 this.file = file;
35 }
36
37 public FileNode(File file, boolean readonly) {
38 this(file);
39 this.children_readonly = readonly;
40 this.readonly = readonly;
41 }
42
43 public FileNode(File file, FileSystemModel model) {
44 this(file);
45 this.model = model;
46 }
47
48 public FileNode(File file, FileSystemModel model, boolean readonly) {
49 this(file, readonly);
50 this.model = model;
51 }
52
53 public FileNode(File file, FileSystemModel model, String title) {
54 this(file, model);
55 this.title = title;
56 }
57
58 public FileNode(File file, String title) {
59 this(file);
60 this.title = title;
61 }
62
63 public FileNode(File file, String title, boolean readonly) {
64 this(file, readonly);
65 this.title = title;
66 }
67
68 public FileNode(File file, FileSystemModel model, String title, boolean readonly) {
69 this(file, model, readonly);
70 this.title = title;
71 }
72
73 /** The special 'dummy' root node, that is not based on a particular file, but instead holds several special directory mappings. */
74 public FileNode(String title) {
75 this.children = new ArrayList();
76 this.title = title;
77 }
78
79 /** Returns the children of the receiver as an Enumeration. */
80 public Enumeration children() {
81 return new FileEnumeration();
82 }
83
84 /** Compare two filenodes for equality. */
85 public boolean equals(FileNode node) {
86 boolean result = false;
87 if(node != null) {
88 if(file != null) {
89 result = (file.equals(node.getFile()));
90 }
91 else {
92 result = toString().equals(node.toString());
93 }
94 }
95 return result;
96 }
97
98 /** 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. */
99 public boolean getAllowsChildren() {
100 if(readonly) {
101 if(allows_children == UNKNOWN) {
102 // If the file is non-null but doesn't exist (as is the case for removable media), return true anyway.
103 if(file != null) {
104 if(isFileSystemRoot()) {
105 allows_children = TRUE;
106 }
107 else if(file.exists() && file.isDirectory()) {
108 allows_children = TRUE;
109 }
110 // Any mapped directories always allow children.
111 else if(getParent() != null && getParent().getParent() == null) {
112 allows_children = TRUE;
113 }
114 else {
115 allows_children = FALSE;
116 }
117 }
118 // Allows children is always true for dummy nodes.
119 else {
120 allows_children = TRUE;
121 }
122 }
123 return (allows_children == TRUE);
124 }
125 else {
126 return (file == null || file.isDirectory());
127 }
128 }
129
130 /** Returns the child TreeNode at index childIndex. */
131 public TreeNode getChildAt(int index) {
132 TreeNode result = null;
133 map();
134 if(0 <= index && index < children.size()) {
135 result = (TreeNode) children.get(index);
136 }
137 else {
138 result = new DefaultMutableTreeNode("Error");
139 }
140 return result;
141 }
142
143 /** Returns the number of children TreeNodes the receiver contains. */
144 public int getChildCount() {
145 int size = 0;
146 // We don't automatically map if this is a system root, or we risk the 50,000 Disk not found error messages of death.
147 if(isFileSystemRoot()) {
148 size = 1; // Size is always non-zero for a system root
149 }
150 else {
151 map();
152 }
153 ///ystem.err.println(this + ".getChildCount() = " + children.size());
154 if(children != null) {
155 size = children.size();
156 }
157 return size;
158 }
159
160 public File getFile() {
161 return file;
162 }
163
164 /** Retrieve the icon the system thinks should be assigned to this node. If this node has no file then the icon will be null. */
165 public ImageIcon getIcon() {
166 return null;
167 }
168
169 /** Returns the index of node in the receivers children. */
170 public int getIndex(TreeNode node) {
171 map();
172 return children.indexOf(node);
173 }
174
175 /** Returns the parent TreeNode of the receiver. */
176 public TreeNode getParent() {
177 return parent;
178 }
179
180 /** Retrieves the tree path from the root node to this node. */
181 public TreeNode[] getPath() {
182 int count = 0;
183 TreeNode current = this;
184 while(current != null) {
185 count++;
186 current = current.getParent();
187 }
188 TreeNode[] path = new TreeNode[count];
189 current = this;
190 while(current != null) {
191 path[count - 1] = current;
192 count--;
193 current = current.getParent();
194 }
195 return path;
196 }
197
198 public void insert(MutableTreeNode child) {
199 insert(child, children.size());
200 }
201
202 /** Adds child to the receiver at index. */
203 public void insert(MutableTreeNode child, int index) {
204 ///ystem.err.println("Insert " + child + " in " + this + " at index " + index + " [Model: " + model + "]");
205 //map();
206 try {
207 children.add(index, child);
208 // Set parent and model.
209 FileNode new_child = (FileNode) child;
210 new_child.setModel(model);
211 new_child.setParent(this);
212 new_child.setReadOnly(readonly);
213 }
214 catch(Exception error) {
215 error.printStackTrace();
216 }
217 }
218
219 /** Returns true if the receiver is a leaf. */
220 public boolean isLeaf() {
221 return !getAllowsChildren();
222 }
223
224 public boolean isReadOnly() {
225 return readonly;
226 }
227
228 public boolean isFileSystemRoot() {
229 boolean result = false;
230 if(file != null) {
231 result = FileSystemView.getFileSystemView().isFileSystemRoot(file);
232 }
233 return result;
234 }
235
236 public void map() {
237 if(children == null) {
238 children = new ArrayList();
239 // Super Special Case: if the name of this node is the Tree.World string, then we actually map the collections installed in greenstone. The file in this case will actually by the collect directory of greenstone.
240 if(file == null && title.equals(Dictionary.get("Tree.World"))) {
241 ///atherer.println("Map the 'Greenstone Collections' node.");
242 // For each of the children directories, which are collections...
243 File start = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path));
244 File cols[] = start.listFiles();
245 ArrayTools.sort(cols);
246 // We add their import directories, but only if its not our current collection, nor the model collection.
247 for(int i = 0; cols != null && i < cols.length; i++) {
248 if(!cols[i].getName().equals(StaticStrings.MODEL_COLLECTION_NAME) && (!Gatherer.c_man.ready() || !Gatherer.c_man.getCollectionDirectory().equals(cols[i].getAbsolutePath()))) {
249 File dirs[] = cols[i].listFiles();
250 ArrayTools.sort(dirs);
251 File import_dir = new File(cols[i], StaticStrings.IMPORT_FOLDER);
252 if(import_dir.exists()) {
253 FileNode collection_root = new FileNode(import_dir, cols[i].getName(), true);
254 collection_root.setParent(this);
255 collection_root.setModel(model);
256 children.add(collection_root);
257 collection_root = null;
258 }
259 import_dir = null;
260 dirs = null;
261 }
262 }
263 cols = null;
264 model.nodeStructureChanged(this);
265 }
266 // General case: Only map if there are no children.
267 else if(file != null && getAllowsChildren()) {
268 File[] files = file.listFiles();
269 if(files != null && files.length > 0) {
270 ArrayTools tools = new ArrayTools();
271 // Apply the filters set in the model.
272 //if(model != null) {
273 FileFilter[] filters = model.getFilters();
274 for(int i = 0; filters != null && i < filters.length; i++) {
275 files = tools.filter(files, filters[i].filter, filters[i].exclude);
276 }
277 //}
278 // If this node just happens to be the greenstone collection directory
279 if(Gatherer.c_man != null && Gatherer.c_man.ready() && file.equals(new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)))) {
280 // Preclude the directory of any open collection
281 String collection_name = Gatherer.c_man.getCollection().getName();
282 for(int j = 0; j < files.length; j++) {
283 ///ystem.err.println("Does " + files[j].getName() + " equal " + collection_name + "?");
284 if(files[j].getName().equals(collection_name)) {
285 // Remove the offending directory
286 files = ArrayTools.remove(files, j);
287 }
288 }
289 }
290 // Finally remove any files whose canonical path do not match their absolute one (ie symbolic links). We only do this test under linux, because under windows there is no such thing as a symbolic link, and instead we suffer difficulties with the 16bit truncated file paths not being the same as the canonical ones (i.e Program Files => Progra~1).
291 /* This test to eliminate infinite recursions causes more problems than it solves
292 if(!Utility.isWindows()) {
293 for(int k = files.length; k != 0; k--) {
294 try {
295 if(!files[k-1].getAbsolutePath().equals(files[k-1].getCanonicalPath())) {
296 ///ystem.err.println("For file: " + files[k-1].getName());
297 ///ystem.err.println("Absolute Path: " + files[k-1].getAbsolutePath());
298 ///ystem.err.println("Canonical Path: " + files[k-1].getCanonicalPath());
299 files = ArrayTools.remove(files, (k-1));
300 }
301 }
302 catch (IOException exception) {
303 Gatherer.printStackTrace(exception);
304 }
305 }
306 }
307 */
308 // Sort the remaining files.
309 tools.sort(files, true);
310 // Now add them to children.
311 for(int i = 0; i < files.length; i++) {
312 FileNode child = new FileNode(files[i], model, children_readonly);
313 child.setParent(this);
314 children.add(child);
315 }
316 }
317 model.nodeStructureChanged(this);
318 }
319 }
320 }
321
322 /** Removes the child at index from the receiver. */
323 public void remove(int index) {
324 if(0 <= index && index < children.size()) {
325 children.remove(index);
326 }
327 }
328
329 /** Removes node from the receiver. */
330 public void remove(MutableTreeNode node){
331 int index = getIndex(node);
332 if(index != -1) {
333 children.remove(index);
334 }
335 }
336
337 /** Removes the receiver from its parent. */
338 public void removeFromParent() {
339 parent.remove(this);
340 parent = null;
341 }
342
343 /* private void setChildrenReadOnly(boolean children_readonly) {
344 this.children_readonly = children_readonly;
345 } */
346
347 public void setFile(File file) {
348 this.file = file;
349 }
350
351 public void setModel(FileSystemModel model) {
352 this.model = model;
353 }
354
355 public void setParent(MutableTreeNode parent) {
356 this.parent = parent;
357 }
358
359 public void setReadOnly(boolean readonly) {
360 this.readonly = readonly;
361 }
362
363 /** Resets the user object of the receiver to object. */
364 public void setUserObject(Object object) {
365 try {
366 file = (File) object;
367 title = null;
368 }
369 catch(Exception error) {
370 error.printStackTrace();
371 }
372 }
373
374 public String toString() {
375 if(title == null) {
376 if(isFileSystemRoot()) {
377 title = file.getAbsolutePath();
378 }
379 else {
380 title = file.getName();
381 }
382 }
383 return title;
384 }
385
386 /** Unmap this nodes children. */
387 public void unmap() {
388 // You cannot unmap nodes that have no file basis.
389 if(file != null || title.equals(Dictionary.get("Tree.World"))) {
390 ///atherer.println("Unmap: " + this);
391 children = null;
392 }
393 else {
394 ///ystem.err.println("No file for " + this + " - can't unmap.");
395 }
396 }
397
398 private class FileEnumeration
399 implements Enumeration {
400 private int index = 0;
401 /** Tests if this enumeration contains more elements. */
402 public boolean hasMoreElements() {
403 return (index < children.size());
404 }
405 /** Returns the next element of this enumeration if this enumeration object has at least one more element to provide. */
406 public Object nextElement() {
407 Object result = null;
408 if(index < children.size()) {
409 result = children.get(index);
410 index++;
411 }
412 return result;
413 }
414 }
415}
Note: See TracBrowser for help on using the repository browser.