/* PackagesTreeModel Copyright (C) 1999-2002 Jochen Hoenicke. * * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package net.sf.jode.swingui; import net.sf.jode.decompiler.Options; import net.sf.jode.bytecode.ClassPath; ///#def JAVAX_SWING javax.swing import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeModelEvent; ///#enddef ///#def COLLECTIONEXTRA java.lang import java.lang.Comparable; ///#enddef ///#def COLLECTIONS java.util import java.util.Arrays; import java.util.TreeSet; import java.util.HashSet; import java.util.Set; import java.util.HashMap; import java.util.Map; ///#enddef import java.util.Enumeration; import java.util.NoSuchElementException; public class PackagesTreeModel implements TreeModel { Map cachedChildrens = new HashMap(); Main main; class TreeElement implements Comparable { String fullName; String name; boolean leaf; public TreeElement(String prefix, String name, boolean isLeaf) { this.fullName = prefix+name; this.name = name; this.leaf = isLeaf; } public String getFullName() { return fullName; } public String getName() { return name; } public boolean isLeaf() { return leaf; } public String toString() { return name; } public int compareTo(Object o) { TreeElement other = (TreeElement) o; if (leaf != other.leaf) // files come after directories return leaf ? 1 : -1; return fullName.compareTo(other.fullName); } public boolean equals(Object o) { return (o instanceof TreeElement) && fullName.equals(((TreeElement)o).fullName); } public int hashCode() { return fullName.hashCode(); } } TreeElement root = new TreeElement("", "", false); Set listeners = new HashSet(); public PackagesTreeModel(Main main) { this.main = main; } public void rebuild() { cachedChildrens.clear(); TreeModelListener[] ls; synchronized (listeners) { ls = (TreeModelListener[]) listeners.toArray(new TreeModelListener[listeners.size()]); } TreeModelEvent ev = new TreeModelEvent(this, new Object[] { root }); for (int i=0; i< ls.length; i++) ls[i].treeStructureChanged(ev); main.reselect(); } public TreeElement[] getChildrens(TreeElement parent) { ClassPath classPath = main.getClassPath(); TreeElement[] result = (TreeElement[]) cachedChildrens.get(parent); if (result == null) { TreeSet v = new TreeSet(); String prefix = parent == root ? "" : parent.getFullName() + "."; Enumeration enumeration = classPath.listClassesAndPackages(parent.getFullName()); while (enumeration.hasMoreElements()) { //insert sorted and remove double elements; String name = (String)enumeration.nextElement(); String fqn = prefix + name; boolean isClass = !classPath.isPackage(fqn); if (isClass && Options.skipClass(classPath.getClassInfo(fqn))) continue; TreeElement newElem = new TreeElement(prefix, name, isClass); v.add(newElem); } result = (TreeElement[]) v.toArray(new TreeElement[v.size()]); cachedChildrens.put(parent, result); } return result; } public void addTreeModelListener(TreeModelListener l) { listeners.add(l); } public void removeTreeModelListener(TreeModelListener l) { listeners.remove(l); } public void valueForPathChanged(TreePath path, Object newValue) { // we don't allow values } public Object getChild(Object parent, int index) { return getChildrens((TreeElement) parent)[index]; } public int getChildCount(Object parent) { return getChildrens((TreeElement) parent).length; } public int getIndexOfChild(Object parent, Object child) { TreeElement[] childrens = getChildrens((TreeElement) parent); int i = Arrays.binarySearch(childrens, child); if (i >= 0) return i; throw new NoSuchElementException (((TreeElement)parent).getFullName() + "." + child); } public Object getRoot() { return root; } public boolean isLeaf(Object node) { return ((TreeElement) node).isLeaf(); } public boolean isValidClass(Object node) { return ((TreeElement) node).isLeaf(); } public TreePath getPath(String fullName) { if (fullName == null || fullName.length() == 0) return new TreePath(root); int pos = -1; int length = 2; while ((pos = fullName.indexOf('.', pos+1)) != -1) length++; TreeElement[] path = new TreeElement[length]; path[0] = root; int i = 0; pos = -1; next_component: while (pos < fullName.length()) { int start = pos+1; pos = fullName.indexOf('.', start); if (pos == -1) pos = fullName.length(); String component = fullName.substring(start, pos); TreeElement[] childs = getChildrens(path[i]); for (int j=0; j< childs.length; j++) { if (childs[j].getName().equals(component)) { path[++i] = childs[j]; continue next_component; } } return null; } return new TreePath(path); } public String getFullName(Object node) { return ((TreeElement) node).getFullName(); } }