DirectoryTreeModel.java :  » IDE » J » org » armedbear » j » Java Open Source

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

package org.armedbear.j;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Vector;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

public class DirectoryTreeModel extends DefaultTreeModel
{
    private static final boolean ignoreCase = Platform.isPlatformWindows();

    private static DirectoryTreeModel localTreeModel;
    private static Vector remoteModels;

    private File rootFile; // Will be null for local tree.

    private DirectoryTreeModel(TreeNode root)
    {
        super(root);
    }

    private DirectoryTreeModel(TreeNode root, File f)
    {
        super(root);
        rootFile = f;
    }

    private File getRootFile()
    {
        return rootFile;
    }

    private static DirectoryTreeModel getLocalDirectoryTreeModel(File file)
    {
        if (localTreeModel == null)
            setLocalRoot(scanRoot(file));
        return localTreeModel;
    }

    public static DirectoryTreeModel getTreeModel(File file)
    {
        if (file.isLocal())
            return getLocalDirectoryTreeModel(file);
        DirectoryTreeModel model;
        File rootFile = file.getRoot();
        if (remoteModels != null) {
            for (int i = 0; i < remoteModels.size(); i++) {
                model = (DirectoryTreeModel) remoteModels.get(i);
                if (rootFile.equals(model.getRootFile()))
                    return model;
            }
        }
        DefaultMutableTreeNode root =
            new DefaultMutableTreeNode(new DirectoryTreeElement(rootFile));
        model = new DirectoryTreeModel(root, rootFile);
        addChildren(rootFile, root);
        if (remoteModels == null)
            remoteModels = new Vector();
        remoteModels.add(model);
        return model;
    }

    private static synchronized void setLocalRoot(DefaultMutableTreeNode root)
    {
        if (localTreeModel != null)
            localTreeModel.setRoot(root);
        else
            localTreeModel = new DirectoryTreeModel(root);
    }

    public void rescan(File file)
    {
        setRoot(scanRoot(file));
    }

    private static DefaultMutableTreeNode scanRoot(File file)
    {
        DefaultMutableTreeNode root = null;
        if (Platform.isPlatformWindows()) {
            File[] roots = File.listRoots();
            if (roots != null) {
                root = new DefaultMutableTreeNode("Local");
                for (int i = 0; i < roots.length; i++) {
                    DefaultMutableTreeNode child =
                        new DefaultMutableTreeNode(new DirectoryTreeElement(roots[i]));
                    root.insert(child, root.getChildCount());
                    if (roots[i].equals(file.getRoot()))
                        addChildren(roots[i], child);
                }
            } else {
                root = new DefaultMutableTreeNode(new DirectoryTreeElement(file.getRoot()));
                addChildren(file.getRoot(), root);
            }
        } else {
            // Unix.
            File f = file.getRoot();
            root = new DefaultMutableTreeNode(new DirectoryTreeElement(file.getRoot()));
            addChildren(f, root);
        }
        return root;
    }

    private static void addChildren(File parent, DefaultMutableTreeNode node)
    {
        File[] list = parent.listFiles();
        if (list == null)
            return;
        Arrays.sort(list,
            ignoreCase ? ciFileNameComparator : csFileNameComparator);
        for (int i = 0; i < list.length; i++) {
            File f = list[i];
            if (f.isDirectory() && !f.isLink()) {
                DefaultMutableTreeNode child =
                    new DefaultMutableTreeNode(new DirectoryTreeElement(f));
                node.insert(child, node.getChildCount());
            }
        }
    }

    public DefaultMutableTreeNode getNode(File file)
    {
        return getNode((DefaultMutableTreeNode) getRoot(), file);
    }

    private static DefaultMutableTreeNode getNode(DefaultMutableTreeNode root, File file)
    {
        if (root == null || file == null)
            return null;
        DefaultMutableTreeNode currentNode = root;
        while (true) {
            DefaultMutableTreeNode node = findMatchingChild(currentNode, file);
            if (node == null)
                return null;
            DirectoryTreeElement treeElement =
                (DirectoryTreeElement) node.getUserObject();
            File f = treeElement.getFile();
            expandNode(node, f);
            if (file.canonicalPath().equals(f.canonicalPath()))
                return node;
            currentNode = node;
        }
    }

    // Find child that is ancestor of file (so to speak).
    private static DefaultMutableTreeNode findMatchingChild(
        DefaultMutableTreeNode parent, File file)
    {
        if (file != null) {
            for (int i = 0; i < parent.getChildCount(); i++) {
                DefaultMutableTreeNode node =
                    (DefaultMutableTreeNode) parent.getChildAt(i);
                DirectoryTreeElement treeElement =
                    (DirectoryTreeElement) node.getUserObject();
                File f = treeElement.getFile();
                if (file.canonicalPath().equals(f.canonicalPath()))
                    return node;
                String prefix = f.canonicalPath();
                if (!prefix.endsWith(f.getSeparator()))
                    prefix += f.getSeparator();
                if (file.canonicalPath().startsWith(prefix))
                    return node;
            }
        }
        return null;
    }

    public static void expandNode(DefaultMutableTreeNode node, File file)
    {
        if (node.getChildCount() == 0) {
            File[] list = file.listFiles();
            if (list == null)
                return;
            Arrays.sort(list,
                ignoreCase ? ciFileNameComparator : csFileNameComparator);
            for (int i = 0; i < list.length; i++) {
                File f = list[i];
                if (f.isLink())
                    continue;
                else if (f.isDirectory()) {
                    DefaultMutableTreeNode child =
                        new DefaultMutableTreeNode(new DirectoryTreeElement(f));
                    node.insert(child, node.getChildCount());
                }
            }
        }
    }

    // Case-sensitive filename comparator (Unix).
    private final static Comparator csFileNameComparator = new Comparator() {
        public int compare(Object o1, Object o2)
        {
            String name1 = ((File)o1).getName();
            String name2 = ((File)o2).getName();
            return name1.compareTo(name2);
        }
    };

    // Case-insensitive filename comparator (Windows).
    private final static Comparator ciFileNameComparator = new Comparator() {
        public int compare(Object o1, Object o2)
        {
            String name1 = ((File)o1).getName();
            String name2 = ((File)o2).getName();
            return name1.compareToIgnoreCase(name2);
        }
    };
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.