001: /*
002: * Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
003: *
004: * This file is part of TransferCM.
005: *
006: * TransferCM is free software; you can redistribute it and/or modify it under the
007: * terms of the GNU General Public License as published by the Free Software
008: * Foundation; either version 2 of the License, or (at your option) any later
009: * version.
010: *
011: * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
012: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
013: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
014: * details.
015: *
016: * You should have received a copy of the GNU General Public License along with
017: * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
018: * Fifth Floor, Boston, MA 02110-1301 USA
019: */
020:
021: package com.methodhead.res;
022:
023: import com.methodhead.tree.Tree;
024: import java.io.File;
025: import com.methodhead.tree.FoldingTreeNode;
026: import java.util.Comparator;
027: import java.util.Arrays;
028:
029: public class FileTree extends Tree {
030:
031: // constructors /////////////////////////////////////////////////////////////
032:
033: // constants ////////////////////////////////////////////////////////////////
034:
035: // classes //////////////////////////////////////////////////////////////////
036:
037: // methods //////////////////////////////////////////////////////////////////
038:
039: /**
040: * Instantiates and initializes a new node for <tt>path</tt> and
041: * <tt>dir</tt>.
042: */
043: protected FoldingTreeNode newNode(String path) {
044:
045: FoldingTreeNode node = new FoldingTreeNode();
046: node.setOpened(false);
047: node.setIconHint("dir");
048:
049: updateNode(node, path);
050:
051: return node;
052: }
053:
054: /**
055: * Updates the label and url of <tt>node</tt> for <tt>path</tt> and
056: * <tt>dir</tt>.
057: */
058: protected void updateNode(FoldingTreeNode node, String path) {
059:
060: //
061: // get the file name
062: //
063: String fileName = path;
064: int i = path.lastIndexOf("/");
065: if (i != -1) {
066: fileName = path.substring(i + 1);
067: }
068:
069: //
070: // update the node
071: //
072: node.setLabel(fileName);
073: node.setUrl("listFiles.do?path=" + path);
074: }
075:
076: /**
077: * Recursively builds nodes for <tt>path</tt> and <tt>dir</tt> and its
078: * subdirectories.
079: */
080: protected FoldingTreeNode buildNode(String path, File dir) {
081:
082: FoldingTreeNode node = newNode(path);
083:
084: //
085: // get directory files
086: //
087: File[] files = dir.listFiles();
088:
089: if (files == null)
090: throw new ResException("Could list files for path \""
091: + path + "\".");
092:
093: //
094: // sort the files
095: //
096: Arrays.sort(files, new Comparator() {
097: public int compare(Object o1, Object o2) {
098: return ((File) o1).getName().compareToIgnoreCase(
099: ((File) o2).getName());
100: }
101: });
102:
103: //
104: // recurse into directories
105: //
106: for (int i = 0; i < files.length; i++) {
107: if (files[i].isDirectory())
108: node.add(buildNode(path + "/" + files[i].getName(),
109: files[i]));
110: }
111:
112: return node;
113: }
114:
115: /**
116: * Builds a file tree representing the the directories managed by
117: * <tt>fileManager</tt>.
118: */
119: public void build(FileManager fileManager) {
120:
121: //
122: // set up the root node
123: //
124: FoldingTreeNode root = new FoldingTreeNode();
125: root.setOpened(true);
126:
127: //
128: // add nodes for each directory
129: //
130: Directory[] dirs = fileManager.getDirectories();
131:
132: for (int i = 0; i < dirs.length; i++) {
133: FoldingTreeNode node = buildNode(dirs[i].getName(), dirs[i]
134: .getFile());
135:
136: //
137: // force the label to the logical name
138: //
139: node.setLabel(dirs[i].getName());
140:
141: root.add(node);
142: }
143:
144: setRoot(root);
145: }
146:
147: /**
148: * Recurses the tree rooted by <tt>node</tt> searching for the node
149: * corresponding to <tt>path</tt>.
150: */
151: private FoldingTreeNode findNode(String[] path, int index,
152: FoldingTreeNode node) {
153:
154: //
155: // are we on the right path?
156: //
157: if (!path[index].equals(node.getLabel()))
158: return null;
159:
160: //
161: // have we reached the last directory in the path?
162: //
163: if ((index + 1) == path.length)
164: return node;
165:
166: //
167: // recurse into child nodes
168: //
169: for (int i = 0; i < node.getChildCount(); i++) {
170: FoldingTreeNode n = findNode(path, index + 1,
171: (FoldingTreeNode) node.getChildAt(i));
172:
173: if (n != null)
174: return n;
175: }
176:
177: return null;
178: }
179:
180: /**
181: * Returns the node associated with <tt>path</tt>, or <tt>null</tt> if no
182: * such node exists.
183: */
184: public FoldingTreeNode find(String path) {
185:
186: FoldingTreeNode root = (FoldingTreeNode) getRoot();
187:
188: //
189: // no root?
190: //
191: if (root == null)
192: return null;
193:
194: //
195: // no directories?
196: //
197: if (root.getChildCount() == 0)
198: return null;
199:
200: //
201: // split path
202: //
203: String[] pathArr = path.split("/");
204:
205: //
206: // search directories (root node doesn't count)
207: //
208: for (int i = 0; i < root.getChildCount(); i++) {
209: FoldingTreeNode n = findNode(pathArr, 0,
210: (FoldingTreeNode) root.getChildAt(i));
211:
212: if (n != null)
213: return n;
214: }
215:
216: return null;
217: }
218:
219: /**
220: * NOT UNIT TESTED Returns the node associated with <tt>path</tt>, or
221: * <tt>null</tt> if no such node exists.
222: */
223: public FoldingTreeNode find(String path, String file) {
224:
225: return find(path + "/" + file);
226: }
227:
228: /**
229: * Moves any nodes specified by <tt>srcPath</tt> and <tt>srcFiles</tt> to
230: * <tt>destPath</tt>. If <tt>srcFiles</tt> contains a single file name,
231: * <tt>destFile</tt> is assumed to be its new name.
232: */
233: public void move(String srcPath, String[] srcFiles,
234: String destPath, String destFile) {
235:
236: FoldingTreeNode dest = find(destPath);
237:
238: for (int i = 0; i < srcFiles.length; i++) {
239: FoldingTreeNode src = find(srcPath, srcFiles[i]);
240: if (src != null) {
241: moveUnder(dest, src);
242:
243: if (srcFiles.length == 1)
244: updateNode(src, destPath + "/" + destFile);
245: }
246: }
247:
248: sort(dest, new Comparator() {
249: public int compare(Object o1, Object o2) {
250: return ((FoldingTreeNode) o1).getLabel()
251: .compareToIgnoreCase(
252: ((FoldingTreeNode) o2).getLabel());
253: }
254: });
255: }
256:
257: /**
258: * Copies any nodes specified by <tt>srcPath</tt> and <tt>srcFiles</tt> to
259: * <tt>destPath</tt>. If <tt>srcFiles</tt> contains a single file name,
260: * <tt>destFile</tt> is assumed to be its new name.
261: */
262: public void copy(String srcPath, String[] srcFiles,
263: String destPath, String destFile) {
264:
265: FoldingTreeNode dest = find(destPath);
266:
267: for (int i = 0; i < srcFiles.length; i++) {
268: FoldingTreeNode src = find(srcPath, srcFiles[i]);
269: if (src != null) {
270: FoldingTreeNode copy = (FoldingTreeNode) copy(src);
271: insertUnder(dest, copy);
272:
273: if (srcFiles.length == 1)
274: updateNode(copy, destPath + "/" + destFile);
275: }
276: }
277:
278: sort(dest, new Comparator() {
279: public int compare(Object o1, Object o2) {
280: return ((FoldingTreeNode) o1).getLabel()
281: .compareToIgnoreCase(
282: ((FoldingTreeNode) o2).getLabel());
283: }
284: });
285: }
286:
287: /**
288: * Deletes any nodes specified by <tt>srcPath</tt> and <tt>srcFiles</tt>.
289: */
290: public void delete(String srcPath, String[] srcFiles) {
291:
292: for (int i = 0; i < srcFiles.length; i++) {
293: FoldingTreeNode src = find(srcPath, srcFiles[i]);
294: if (src != null) {
295: remove(src);
296: }
297: }
298: }
299:
300: /**
301: * Deletes any nodes specified by <tt>srcPath</tt> and <tt>srcFiles</tt>.
302: */
303: public void create(String path, String file, boolean isDir) {
304:
305: FoldingTreeNode dest = find(path);
306:
307: if (isDir) {
308: if (dest == null)
309: throw new ResException("Couldn't find node for path \""
310: + path + "\"");
311:
312: FoldingTreeNode n = newNode(path + "/" + file);
313: insertUnder(dest, n);
314:
315: sort(dest, new Comparator() {
316: public int compare(Object o1, Object o2) {
317: return ((FoldingTreeNode) o1).getLabel()
318: .compareToIgnoreCase(
319: ((FoldingTreeNode) o2).getLabel());
320: }
321: });
322: }
323: }
324:
325: // properties ///////////////////////////////////////////////////////////////
326:
327: // attributes ///////////////////////////////////////////////////////////////
328: }
|