KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > gui > filechooser > FolderFileWrapper


1 package net.suberic.pooka.gui.filechooser;
2 import javax.swing.*;
3 import java.io.*;
4 import javax.mail.*;
5 import net.suberic.pooka.Pooka;
6
7 // TODO make StoreFileWrapper for selecting from available stores
8
// --jphekman
9

10
11 /**
12  * This wraps a Folder or Store in a File object.
13  */

14 public class FolderFileWrapper extends File {
15   private Folder folder;
16   private FolderFileWrapper parent;
17   private FolderFileWrapper[] children = null;
18   private String JavaDoc path;
19   private Object JavaDoc mRunLock = null;
20   
21   /**
22    * Creates a new FolderFileWrapper from a Folder. This should only
23    * be used for direct children of the Folder.
24    */

25   public FolderFileWrapper(Folder f, FolderFileWrapper p) {
26     super(f.getName());
27     folder = f;
28     parent = p;
29     path = f.getName();
30     mRunLock = p.getRunLock();
31     if (Pooka.isDebug())
32       if (p != null)
33     System.out.println("creating FolderFileWrapper from parent '" + p.getAbsolutePath() + "' from folder '" + f.getName() + "'");
34       else
35     System.out.println("creating FolderFileWrapper from parent 'null' from folder '" + f.getName() + "'");
36   }
37   
38   /**
39    * Creates a new FolderFileWrapper from a Folder with the given path
40    * and parent. This is used for making relative paths to files, i.e.
41    * a child of '/foo' called 'bar/baz'.
42    */

43   public FolderFileWrapper(Folder f, FolderFileWrapper p, String JavaDoc filePath) {
44     super(f.getName());
45     folder = f;
46     parent = p;
47     mRunLock = p.getRunLock();
48     path = filePath;
49     if (Pooka.isDebug())
50       if (p != null)
51     System.out.println("creating FolderFileWrapper from parent '" + p.getAbsolutePath() + "' called '" + filePath + "'");
52       else
53     System.out.println("creating FolderFileWrapper from parent 'null' called '" + filePath + "'");
54   }
55
56   /**
57    * Creates a new FolderFileWrapper from a Folder with the given path
58    * and parent. This is used for making relative paths to files, i.e.
59    * a child of '/foo' called 'bar/baz'.
60    */

61   public FolderFileWrapper(Folder f, String JavaDoc filePath, Object JavaDoc pRunLock) {
62     super(f.getName());
63     folder = f;
64     parent = null;
65     mRunLock = pRunLock;
66     path = filePath;
67     if (Pooka.isDebug())
68     System.out.println("creating FolderFileWrapper from parent 'null' called '" + filePath + "'");
69   }
70   
71   /**
72    * returns true.
73    */

74   public boolean canRead() {
75     return true;
76   }
77   
78   /**
79    * returns true.
80    */

81   public boolean canWrite() {
82     return true;
83   }
84   
85   /**
86    * If the wrapped Folder does not exist, creates the new Folder
87    * and returns true. If it does exist, returns false. If a
88    * MessagingException is thrown, wraps it with an IOException.
89    */

90   public boolean createNewFile() {
91     try {
92       if (folder.exists())
93     return false;
94       else {
95     folder.create(Folder.HOLDS_MESSAGES);
96     return true;
97       }
98     } catch (MessagingException me) {
99       System.out.println("caught exception: " + me.getMessage());
100       me.printStackTrace();
101       return false;
102     }
103   }
104   
105   
106   /**
107    * Attempts to delete the Folder.
108    */

109   public boolean delete() {
110     try {
111       return folder.delete(true);
112     } catch (MessagingException me) {
113       System.out.println("caughed exception: " + me.getMessage());
114       me.printStackTrace();
115       return false;
116     }
117   }
118   
119   /**
120    * A no-op; we're not deleting any Mail folders on exit.
121    */

122   public void deleteOnExit() {
123   }
124   
125   /**
126    * Equals if the underlying Folder objects are equal.
127    */

128   public boolean equals(Object JavaDoc obj) {
129     if (obj instanceof FolderFileWrapper)
130       return ( folder == ((FolderFileWrapper)obj).folder );
131     else
132       return false;
133   }
134   
135   /**
136    * Returns folder.exists().
137    */

138   public boolean exists() {
139     try {
140       return folder.exists();
141     } catch (MessagingException me) {
142       return false;
143     }
144   }
145   
146   /**
147    * Returns this object.
148    */

149   public File getAbsoluteFile() {
150     if (Pooka.isDebug())
151       System.out.println("calling getAbsoluteFile() on " + getAbsolutePath());
152     if (this.isAbsolute())
153       return this;
154     else
155       return new FolderFileWrapper(getFolder(), getRoot(), getAbsolutePath());
156   }
157   
158   /**
159    * returns the root of this tree.
160    */

161   private FolderFileWrapper getRoot() {
162     FolderFileWrapper parent = this;
163     while (parent.getParent() != null) {
164       parent = (FolderFileWrapper)parent.getParentFile();
165     }
166     return parent;
167   }
168   
169   /**
170    * Returns the Folder's full name. It does this recursively, by calling
171    * the this on the parent and then appending this name.
172    */

173   public String JavaDoc getAbsolutePath() {
174     if (Pooka.isDebug())
175       System.out.println("calling getAbsolutePath() on " + path);
176     
177     if (isAbsolute()) {
178       if (Pooka.isDebug())
179     System.out.println("returning " + getPath());
180       return getPath();
181     }
182     else {
183       if (parent != null) {
184     String JavaDoc parentPath = parent.getAbsolutePath();
185     if (parentPath != "/") {
186       if (Pooka.isDebug())
187         System.out.println("returning parentPath + slash + getPath() (" + parentPath + "/" + getPath() + ")");
188       
189       return parentPath + "/" + getPath();
190     } else {
191       if (Pooka.isDebug())
192         System.out.println("returning just slash + getPath() (/" + getPath() + ")");
193       return "/" + getPath();
194     }
195       } else {
196     if (Pooka.isDebug())
197       System.out.println("returning just /.");
198     return "/";
199       }
200     }
201   }
202   
203   /**
204    * returns this.
205    */

206   public File getCanonicalFile() {
207     return this;
208   }
209   
210   /**
211    * returns getAbsolutePath();
212    */

213   public String JavaDoc getCanonicalPath() {
214     return getAbsolutePath();
215   }
216   
217   /**
218    * Returns the Folder's name.
219    */

220   public String JavaDoc getName() {
221     String JavaDoc name = folder.getName();
222     if (name == null || name.length() < 1) {
223       // this is probably a store.
224
return path;
225     }
226     return name;
227   }
228   
229   /**
230    * Returns the parent's name.
231    */

232   public String JavaDoc getParent() {
233     if (parent != null)
234       return parent.getAbsolutePath();
235     else
236       return null;
237   }
238   
239   /**
240    * This returns the parent Folder as a FolderFileWrapper.
241    */

242   public File getParentFile() {
243     return parent;
244   }
245   
246   /**
247    * Returns the filePath variable.
248    */

249   public String JavaDoc getPath() {
250     return path;
251   }
252   
253   /**
254    * Returns true if this is an absolute reference, false otherwise.
255    */

256   public boolean isAbsolute() {
257     return (parent == null);
258   }
259   
260   /**
261    * Tests to see if this can act as a directory.
262    */

263   public boolean isDirectory() {
264     try {
265       return ((folder.getType() & Folder.HOLDS_FOLDERS) != 0);
266     } catch (MessagingException me) {
267       return false;
268     }
269   }
270   
271   /**
272    * Tests to see if we should call this a File.
273    */

274   public boolean isFile() {
275     try {
276       return ((folder.getType() & Folder.HOLDS_MESSAGES) != 0);
277     } catch (MessagingException me) {
278       return false;
279     }
280   }
281   
282   /**
283    * Returns false.
284    */

285   public boolean isHidden() {
286     return false;
287   }
288   
289   /**
290    * Returns 0.
291    */

292   public long lastModified() {
293     return 0;
294   }
295   
296   /**
297    * returns the children of the File.
298    */

299   public String JavaDoc[] list() {
300     if (isDirectory()) {
301       if (children == null)
302     loadChildren();
303       if (children != null) {
304     String JavaDoc[] returnValue = new String JavaDoc[children.length];
305     for (int i = 0; i < children.length; i++) {
306       returnValue[i] = children[i].getName();
307     }
308     return returnValue;
309       }
310     }
311     
312     return null;
313     
314   }
315   
316   /**
317    * Returns the children of the File, filterd by the FilenameFilter.
318    */

319   public String JavaDoc[] list(FilenameFilter filter) {
320     String JavaDoc[] children = list();
321     String JavaDoc[] matching = new String JavaDoc[children.length];
322     int retValueCounter = 0;
323     for (int i = 0; i < children.length; i++) {
324       if (filter.accept(this, children[i])) {
325     matching[retValueCounter++] = children[i];
326       }
327     }
328     
329     String JavaDoc[] returnValue = new String JavaDoc[retValueCounter];
330     
331     for (int i = 0; i < retValueCounter; i++)
332       returnValue[i] = matching[i];
333     
334     return returnValue;
335   }
336   
337   /**
338    * This returns the children of the File as Files.
339    */

340   public File[] listFiles() {
341     if (Pooka.isDebug()) {
342       System.out.println("Running listFiles() on '" + getAbsolutePath() + "'");
343       //Thread.dumpStack();
344
}
345     
346     if (isDirectory()) {
347       if (children == null) {
348     if (Pooka.isDebug()) {
349       System.out.println("about to load children.");
350     }
351     loadChildren();
352       }
353       
354       if (children != null)
355     return children;
356     }
357     
358     return new FolderFileWrapper[0];
359   }
360   
361   public File[] listFiles(FileFilter filter) {
362     if (Pooka.isDebug())
363       System.out.println("Running listFiles(FileFilter) on '" + getAbsolutePath() + "'");
364     
365     File[] children = listFiles();
366     File[] matching = new File[children.length];
367     int retValueCounter = 0;
368     for (int i = 0; i < children.length; i++) {
369       if (filter.accept(children[i])) {
370     matching[retValueCounter++] = children[i];
371       }
372     }
373     
374     File[] returnValue = new File[retValueCounter];
375     
376     for (int i = 0; i < retValueCounter; i++)
377       returnValue[i] = matching[i];
378     
379     return returnValue;
380   }
381   
382   public File[] listFiles(FilenameFilter filter) {
383     if (Pooka.isDebug())
384       System.out.println("Running listFiles(FilenameFilter) on '" + getAbsolutePath() + "'");
385     
386     File[] children = listFiles();
387     File[] matching = new File[children.length];
388     int retValueCounter = 0;
389     for (int i = 0; i < children.length; i++) {
390       if (filter.accept(this, children[i].getName())) {
391     matching[retValueCounter++] = children[i];
392       }
393     }
394     
395     File[] returnValue = new File[retValueCounter];
396     
397     for (int i = 0; i < retValueCounter; i++)
398       returnValue[i] = matching[i];
399     
400     return returnValue;
401   }
402   
403   /**
404    * This creates a new directory.
405    */

406   public boolean mkdir() {
407     try {
408       if (folder.exists())
409     return false;
410       else {
411     folder.create(Folder.HOLDS_FOLDERS);
412     return true;
413       }
414     } catch (MessagingException me) {
415       return false;
416     }
417   }
418   
419   /**
420    * This creates a new directory, also creating any higher-level
421    * directories if needed.
422    */

423   public boolean mkdirs() {
424     try {
425       if (folder.exists())
426     return false;
427       
428       boolean create = true;
429       if (!parent.exists())
430     create = parent.mkdirs();
431       
432       if (create) {
433     folder.create(Folder.HOLDS_FOLDERS);
434     return true;
435       } else
436     return false;
437     } catch (MessagingException me) {
438       return false;
439     }
440   }
441   
442   
443   /**
444    * This renames the underlying Folder.
445    */

446   public boolean renameTo(File dest) {
447     try {
448       if (dest instanceof FolderFileWrapper) {
449     boolean returnValue = folder.renameTo(((FolderFileWrapper)dest).getFolder());
450     if (parent != null)
451       parent.refreshChildren();
452     return returnValue;
453       } else
454     return false;
455     } catch (MessagingException me) {
456       Pooka.getUIFactory().showError(Pooka.getProperty("error.renamingFolder", "Error renaming folder ") + getName(), me);
457       return false;
458     }
459   }
460   
461   /**
462    * This returns the wrapped Folder.
463    */

464   public Folder getFolder() {
465     return folder;
466   }
467   
468   /**
469    * This loads the children of the Folder.
470    */

471   private synchronized void loadChildren() {
472     synchronized(getRunLock()) {
473     if (Pooka.isDebug()) {
474       System.out.println(Thread.currentThread().getName() + ": calling loadChildren() on " + getAbsolutePath());
475       //Thread.dumpStack();
476
}
477     
478     if (children == null) {
479       if (Pooka.isDebug()) {
480     System.out.println(Thread.currentThread().getName() + ": children is null on " + getAbsolutePath() + ". loading children.");
481       }
482       if (isDirectory() || ! exists()) {
483     try {
484       if (Pooka.isDebug())
485         System.out.println(Thread.currentThread().getName() + ": checking for connection.");
486       
487       if (!folder.getStore().isConnected()) {
488         if (Pooka.isDebug()) {
489           System.out.println(Thread.currentThread().getName() + ": parent store of " + getAbsolutePath() + " is not connected. reconnecting.");
490         }
491         folder.getStore().connect();
492       } else {
493         if (Pooka.isDebug())
494           System.out.println(Thread.currentThread().getName() + ": connection is ok.");
495       }
496       
497       
498       if (Pooka.isDebug())
499         System.out.println(Thread.currentThread().getName() + ": calling folder.list()");
500       Folder[] childList = folder.list();
501
502       if (parent == null) {
503         // add for namespaces.
504
try {
505           Folder[] namespaces = folder.getStore().getSharedNamespaces();
506           if (namespaces != null && namespaces.length > 0) {
507         Folder[] newChildList = new Folder[childList.length + namespaces.length];
508         System.arraycopy(namespaces, 0, newChildList, 0, namespaces.length);
509         System.arraycopy(childList, 0, newChildList, namespaces.length, childList.length);
510         childList = newChildList;
511           }
512         } catch (Exception JavaDoc e) {
513           // FIXME do nothing for now.
514
}
515       }
516       if (Pooka.isDebug())
517         System.out.println(Thread.currentThread().getName() + ": folder.list() returned " + childList + "; creating new folderFileWrapper.");
518       
519       FolderFileWrapper[] tmpChildren = new FolderFileWrapper[childList.length];
520       for (int i = 0; i < childList.length; i++) {
521         if (Pooka.isDebug())
522           System.out.println(Thread.currentThread().getName() + ": calling new FolderFileWrapper for " + childList[i].getName() + " (entry # " + i);
523         
524         tmpChildren[i] = new FolderFileWrapper(childList[i], this);
525       }
526       
527       children = tmpChildren;
528     } catch (MessagingException me) {
529       if (Pooka.isDebug())
530         System.out.println("caught exception during FolderFileWrapper.loadChildren() on " + getAbsolutePath() + ".");
531       me.printStackTrace();
532     }
533       }
534     }
535     }
536   }
537
538   /**
539    * This refreshes the children of the Folder.
540    */

541   public synchronized void refreshChildren() {
542     synchronized(getRunLock()) {
543       if (Pooka.isDebug()) {
544     System.out.println(Thread.currentThread().getName() + ": calling refreshChildren() on " + getAbsolutePath());
545     //Thread.dumpStack();
546
}
547       
548       if (children == null) {
549     if (Pooka.isDebug()) {
550       System.out.println(Thread.currentThread().getName() + ": children is null on " + getAbsolutePath() + ". calling loadChildren().");
551     }
552     loadChildren();
553       } else {
554     if (isDirectory() || ! exists()) {
555       try {
556         if (Pooka.isDebug())
557           System.out.println(Thread.currentThread().getName() + ": checking for connection.");
558         
559         if (!folder.getStore().isConnected()) {
560           if (Pooka.isDebug()) {
561         System.out.println(Thread.currentThread().getName() + ": parent store of " + getAbsolutePath() + " is not connected. reconnecting.");
562           }
563           folder.getStore().connect();
564         } else {
565           if (Pooka.isDebug())
566         System.out.println(Thread.currentThread().getName() + ": connection is ok.");
567         }
568         
569         
570         if (Pooka.isDebug())
571           System.out.println(Thread.currentThread().getName() + ": calling folder.list()");
572         Folder[] childList = folder.list();
573         if (Pooka.isDebug())
574           System.out.println(Thread.currentThread().getName() + ": folder.list() returned " + childList + "; creating new folderFileWrapper.");
575         
576         FolderFileWrapper[] tmpChildren = new FolderFileWrapper[childList.length];
577         for (int i = 0; i < childList.length; i++) {
578           if (Pooka.isDebug())
579         System.out.println(Thread.currentThread().getName() + ": calling new FolderFileWrapper for " + childList[i].getName() + " (entry # " + i);
580           
581           // yeah, this is n! or something like that. shouldn't matter--
582
// if we have somebody running with that many folders, or with
583
// that slow of a machine, we're in trouble anyway.
584

585           //try to get a match.
586
boolean found = false;
587           for (int j = 0; ! found && j < children.length; j++) {
588         if (children[j].getName().equals(childList[i].getName())) {
589           tmpChildren[i] = children[j];
590           found = true;
591         }
592           }
593           
594           if (! found) {
595         tmpChildren[i] = new FolderFileWrapper(childList[i], this);
596           }
597         }
598         
599         children = tmpChildren;
600       } catch (MessagingException me) {
601         Pooka.getUIFactory().showError(Pooka.getProperty("error.refreshingFolder", "error refreshing folder's children: "), me);
602       }
603     }
604       }
605     }
606     
607   }
608   
609   /* Only accepts relative filenames. */
610   public FolderFileWrapper getFileByName(String JavaDoc filename) {
611     
612     if (Pooka.isDebug())
613       System.out.println("calling getFileByName(" + filename + ") on folder " + getName() + " (" + getPath() + ") (abs " + getAbsolutePath() + ")");
614     
615     String JavaDoc origFilename = new String JavaDoc(filename);
616     if (filename == null || filename.length() < 1 || (filename.equals("/") && getParentFile() == null)) {
617       if (Pooka.isDebug())
618     System.out.println("returning this for getFileByName()");
619       return this;
620     }
621     
622     if (this.isAbsolute(filename))
623       {
624     return null; // FIXME error
625
}
626     
627     // strip out the /'s
628

629     String JavaDoc subdirFile = null;
630     
631     int dirMarker = filename.indexOf('/');
632     while (dirMarker == 0) {
633       filename = filename.substring(1);
634       dirMarker = filename.indexOf('/');
635     }
636     
637     // divide into first component and rest of components
638
if (dirMarker > 0) {
639       subdirFile = filename.substring(dirMarker + 1);
640       filename=filename.substring(0, dirMarker);
641     }
642     
643     FolderFileWrapper currentFile = getChildFile(filename);
644     if (currentFile != null && subdirFile != null) {
645       // recurse with rest of components
646
FolderFileWrapper tmp = currentFile.getFileByName(subdirFile);
647       // tmp.path = origFilename;
648

649       if (Pooka.isDebug())
650     System.out.println("created file " + tmp.getName() + " (" + tmp.getPath() + ") (abs " + tmp.getAbsolutePath() + ") from string " + origFilename + " on folder " + getName() + " (" + getPath() + ") (abs " + getAbsolutePath() + ")");
651       
652       return tmp;
653       
654     } else {
655       return currentFile;
656     }
657     
658   }
659   
660   FolderFileWrapper getChildFile(String JavaDoc filename) {
661     if (Pooka.isDebug())
662       System.out.println("calling getChildFile on " + getName() + " with filename " + filename);
663     
664     if (children == null)
665       loadChildren();
666     
667     if (children != null) {
668       for (int i = 0; i < children.length; i++) {
669     if (children[i].getName().equals(filename))
670       return children[i];
671       }
672       
673       FolderFileWrapper[] newChildren = new FolderFileWrapper[children.length +1];
674       for (int i = 0; i < children.length; i++)
675     newChildren[i] = children[i];
676       
677       try {
678     newChildren[children.length] = new FolderFileWrapper(folder.getFolder(filename), this);
679       } catch (MessagingException me) {
680       }
681       
682       children = newChildren;
683       return children[children.length -1];
684     }
685     
686     return this;
687     
688   }
689   
690   private boolean isAbsolute(String JavaDoc filename) {
691     return filename.startsWith("/");
692   }
693   
694   public String JavaDoc filenameAsRelativeToRoot(String JavaDoc filename) {
695     String JavaDoc relative = filename;
696     while (relative.length() > 0 & isAbsolute (relative)) {
697       relative = relative.substring(1);
698     }
699     
700     return relative;
701   }
702
703   /**
704    * Returns the object that we use for a run lock.
705    */

706   public Object JavaDoc getRunLock() {
707     return mRunLock;
708   }
709   
710 }
711
Popular Tags