KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > DirectoryTreeModel


1 /*
2  * DirectoryTreeModel.java
3  *
4  * Copyright (C) 2000-2003 Peter Graves
5  * $Id: DirectoryTreeModel.java,v 1.3 2003/05/20 00:37:48 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.util.Arrays JavaDoc;
25 import java.util.Comparator JavaDoc;
26 import java.util.Vector JavaDoc;
27 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
28 import javax.swing.tree.DefaultTreeModel JavaDoc;
29 import javax.swing.tree.TreeNode JavaDoc;
30
31 public class DirectoryTreeModel extends DefaultTreeModel JavaDoc
32 {
33     private static final boolean ignoreCase = Platform.isPlatformWindows();
34
35     private static DirectoryTreeModel localTreeModel;
36     private static Vector JavaDoc remoteModels;
37
38     private File rootFile; // Will be null for local tree.
39

40     private DirectoryTreeModel(TreeNode JavaDoc root)
41     {
42         super(root);
43     }
44
45     private DirectoryTreeModel(TreeNode JavaDoc root, File f)
46     {
47         super(root);
48         rootFile = f;
49     }
50
51     private File getRootFile()
52     {
53         return rootFile;
54     }
55
56     private static DirectoryTreeModel getLocalDirectoryTreeModel(File file)
57     {
58         if (localTreeModel == null)
59             setLocalRoot(scanRoot(file));
60         return localTreeModel;
61     }
62
63     public static DirectoryTreeModel getTreeModel(File file)
64     {
65         if (file.isLocal())
66             return getLocalDirectoryTreeModel(file);
67         DirectoryTreeModel model;
68         File rootFile = file.getRoot();
69         if (remoteModels != null) {
70             for (int i = 0; i < remoteModels.size(); i++) {
71                 model = (DirectoryTreeModel) remoteModels.get(i);
72                 if (rootFile.equals(model.getRootFile()))
73                     return model;
74             }
75         }
76         DefaultMutableTreeNode JavaDoc root =
77             new DefaultMutableTreeNode JavaDoc(new DirectoryTreeElement(rootFile));
78         model = new DirectoryTreeModel(root, rootFile);
79         addChildren(rootFile, root);
80         if (remoteModels == null)
81             remoteModels = new Vector JavaDoc();
82         remoteModels.add(model);
83         return model;
84     }
85
86     private static synchronized void setLocalRoot(DefaultMutableTreeNode JavaDoc root)
87     {
88         if (localTreeModel != null)
89             localTreeModel.setRoot(root);
90         else
91             localTreeModel = new DirectoryTreeModel(root);
92     }
93
94     public void rescan(File file)
95     {
96         setRoot(scanRoot(file));
97     }
98
99     private static DefaultMutableTreeNode JavaDoc scanRoot(File file)
100     {
101         DefaultMutableTreeNode JavaDoc root = null;
102         if (Platform.isPlatformWindows()) {
103             File[] roots = File.listRoots();
104             if (roots != null) {
105                 root = new DefaultMutableTreeNode JavaDoc("Local");
106                 for (int i = 0; i < roots.length; i++) {
107                     DefaultMutableTreeNode JavaDoc child =
108                         new DefaultMutableTreeNode JavaDoc(new DirectoryTreeElement(roots[i]));
109                     root.insert(child, root.getChildCount());
110                     if (roots[i].equals(file.getRoot()))
111                         addChildren(roots[i], child);
112                 }
113             } else {
114                 root = new DefaultMutableTreeNode JavaDoc(new DirectoryTreeElement(file.getRoot()));
115                 addChildren(file.getRoot(), root);
116             }
117         } else {
118             // Unix.
119
File f = file.getRoot();
120             root = new DefaultMutableTreeNode JavaDoc(new DirectoryTreeElement(file.getRoot()));
121             addChildren(f, root);
122         }
123         return root;
124     }
125
126     private static void addChildren(File parent, DefaultMutableTreeNode JavaDoc node)
127     {
128         File[] list = parent.listFiles();
129         if (list == null)
130             return;
131         Arrays.sort(list,
132             ignoreCase ? ciFileNameComparator : csFileNameComparator);
133         for (int i = 0; i < list.length; i++) {
134             File f = list[i];
135             if (f.isDirectory() && !f.isLink()) {
136                 DefaultMutableTreeNode JavaDoc child =
137                     new DefaultMutableTreeNode JavaDoc(new DirectoryTreeElement(f));
138                 node.insert(child, node.getChildCount());
139             }
140         }
141     }
142
143     public DefaultMutableTreeNode JavaDoc getNode(File file)
144     {
145         return getNode((DefaultMutableTreeNode JavaDoc) getRoot(), file);
146     }
147
148     private static DefaultMutableTreeNode JavaDoc getNode(DefaultMutableTreeNode JavaDoc root, File file)
149     {
150         if (root == null || file == null)
151             return null;
152         DefaultMutableTreeNode JavaDoc currentNode = root;
153         while (true) {
154             DefaultMutableTreeNode JavaDoc node = findMatchingChild(currentNode, file);
155             if (node == null)
156                 return null;
157             DirectoryTreeElement treeElement =
158                 (DirectoryTreeElement) node.getUserObject();
159             File f = treeElement.getFile();
160             expandNode(node, f);
161             if (file.canonicalPath().equals(f.canonicalPath()))
162                 return node;
163             currentNode = node;
164         }
165     }
166
167     // Find child that is ancestor of file (so to speak).
168
private static DefaultMutableTreeNode JavaDoc findMatchingChild(
169         DefaultMutableTreeNode JavaDoc parent, File file)
170     {
171         if (file != null) {
172             for (int i = 0; i < parent.getChildCount(); i++) {
173                 DefaultMutableTreeNode JavaDoc node =
174                     (DefaultMutableTreeNode JavaDoc) parent.getChildAt(i);
175                 DirectoryTreeElement treeElement =
176                     (DirectoryTreeElement) node.getUserObject();
177                 File f = treeElement.getFile();
178                 if (file.canonicalPath().equals(f.canonicalPath()))
179                     return node;
180                 String JavaDoc prefix = f.canonicalPath();
181                 if (!prefix.endsWith(f.getSeparator()))
182                     prefix += f.getSeparator();
183                 if (file.canonicalPath().startsWith(prefix))
184                     return node;
185             }
186         }
187         return null;
188     }
189
190     public static void expandNode(DefaultMutableTreeNode JavaDoc node, File file)
191     {
192         if (node.getChildCount() == 0) {
193             File[] list = file.listFiles();
194             if (list == null)
195                 return;
196             Arrays.sort(list,
197                 ignoreCase ? ciFileNameComparator : csFileNameComparator);
198             for (int i = 0; i < list.length; i++) {
199                 File f = list[i];
200                 if (f.isLink())
201                     continue;
202                 else if (f.isDirectory()) {
203                     DefaultMutableTreeNode JavaDoc child =
204                         new DefaultMutableTreeNode JavaDoc(new DirectoryTreeElement(f));
205                     node.insert(child, node.getChildCount());
206                 }
207             }
208         }
209     }
210
211     // Case-sensitive filename comparator (Unix).
212
private final static Comparator JavaDoc csFileNameComparator = new Comparator JavaDoc() {
213         public int compare(Object JavaDoc o1, Object JavaDoc o2)
214         {
215             String JavaDoc name1 = ((File)o1).getName();
216             String JavaDoc name2 = ((File)o2).getName();
217             return name1.compareTo(name2);
218         }
219     };
220
221     // Case-insensitive filename comparator (Windows).
222
private final static Comparator JavaDoc ciFileNameComparator = new Comparator JavaDoc() {
223         public int compare(Object JavaDoc o1, Object JavaDoc o2)
224         {
225             String JavaDoc name1 = ((File)o1).getName();
226             String JavaDoc name2 = ((File)o2).getName();
227             return name1.compareToIgnoreCase(name2);
228         }
229     };
230 }
231
Popular Tags