git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1148 379699f6-c40d-0410-875b-85095c16579ebranch_1_1
parent
74acab5ec7
commit
15e5e76033
@ -0,0 +1,270 @@ |
||||
/* HierarchyTreeModel Copyright (C) 1999 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 jode.swingui; |
||||
import jode.Decompiler; |
||||
import jode.bytecode.ClassInfo; |
||||
|
||||
import @JAVAX_SWING@.JProgressBar; |
||||
import @JAVAX_SWING@.tree.TreeModel; |
||||
import @JAVAX_SWING@.tree.TreePath; |
||||
import @JAVAX_SWING@.event.TreeModelListener; |
||||
import @JAVAX_SWING@.event.TreeModelEvent; |
||||
|
||||
import @COLLECTIONEXTRA@.Comparable; |
||||
import @COLLECTIONS@.TreeSet; |
||||
import @COLLECTIONS@.Collection; |
||||
import @COLLECTIONS@.Iterator; |
||||
import @COLLECTIONS@.HashMap; |
||||
import @COLLECTIONS@.Set; |
||||
import @COLLECTIONS@.HashSet; |
||||
|
||||
|
||||
import java.util.Enumeration; |
||||
import java.util.NoSuchElementException; |
||||
|
||||
public class HierarchyTreeModel implements TreeModel, Runnable { |
||||
static final int MAX_PACKAGE_LEVEL = 10; |
||||
TreeElement root = new TreeElement(""); |
||||
Set listeners = new HashSet(); |
||||
JProgressBar progressBar; |
||||
Main main; |
||||
|
||||
class TreeElement implements Comparable { |
||||
String fullName; |
||||
TreeSet childs; |
||||
boolean inClassPath = false; |
||||
|
||||
public TreeElement(String fqn) { |
||||
this.fullName = fqn; |
||||
childs = new TreeSet(); |
||||
} |
||||
|
||||
public String getFullName() { |
||||
return fullName; |
||||
} |
||||
|
||||
public void addChild(TreeElement child) { |
||||
childs.add(child); |
||||
} |
||||
|
||||
public Collection getChilds() { |
||||
return childs; |
||||
} |
||||
|
||||
public String toString() { |
||||
return fullName; |
||||
} |
||||
|
||||
public int compareTo(Object o) { |
||||
TreeElement other = (TreeElement) o; |
||||
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(); |
||||
} |
||||
} |
||||
|
||||
private TreeElement handleClass(HashMap classes, ClassInfo clazz) { |
||||
if (clazz == null) |
||||
return root; |
||||
TreeElement elem = (TreeElement) classes.get(clazz); |
||||
if (elem != null) |
||||
return elem; |
||||
|
||||
elem = new TreeElement(clazz.getName()); |
||||
classes.put(clazz, elem); |
||||
|
||||
if (!clazz.isInterface()) { |
||||
ClassInfo superClazz = clazz.getSuperclass(); |
||||
handleClass(classes, superClazz).addChild(elem); |
||||
} |
||||
ClassInfo[] ifaces = clazz.getInterfaces(); |
||||
for (int i=0; i < ifaces.length; i++) |
||||
handleClass(classes, ifaces[i]).addChild(elem); |
||||
if (ifaces.length == 0 && clazz.isInterface()) |
||||
root.addChild(elem); |
||||
return elem; |
||||
} |
||||
|
||||
public int readPackage(int depth, HashMap classes, String packageName, |
||||
int count) { |
||||
if (depth++ >= MAX_PACKAGE_LEVEL) |
||||
return count; |
||||
String prefix = packageName.length() == 0 ? "" : packageName + "."; |
||||
Enumeration enum = |
||||
ClassInfo.getClassesAndPackages(packageName); |
||||
while (enum.hasMoreElements()) { |
||||
//insert sorted and remove double elements;
|
||||
String name = (String)enum.nextElement(); |
||||
String fqn = prefix + name; |
||||
if (ClassInfo.isPackage(fqn)) { |
||||
count = readPackage(depth, classes, fqn, count); |
||||
} else { |
||||
TreeElement elem = handleClass(classes, |
||||
ClassInfo.forName(fqn)); |
||||
if (progressBar != null) |
||||
progressBar.setValue(++count); |
||||
|
||||
elem.inClassPath = true; |
||||
} |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
public int countClasses(int depth, String packageName) { |
||||
if (depth++ >= MAX_PACKAGE_LEVEL) |
||||
return 0; |
||||
int number = 0; |
||||
String prefix = packageName.length() == 0 ? "" : packageName + "."; |
||||
Enumeration enum = |
||||
ClassInfo.getClassesAndPackages(packageName); |
||||
while (enum.hasMoreElements()) { |
||||
//insert sorted and remove double elements;
|
||||
String name = (String)enum.nextElement(); |
||||
String fqn = prefix + name; |
||||
if (ClassInfo.isPackage(fqn)) { |
||||
number += countClasses(depth, fqn); |
||||
} else { |
||||
number++; |
||||
} |
||||
} |
||||
return number; |
||||
} |
||||
|
||||
public HierarchyTreeModel(Main main) { |
||||
this.main = main; |
||||
this.progressBar = null; |
||||
rebuild(); |
||||
} |
||||
|
||||
public HierarchyTreeModel(Main main, JProgressBar progressBar) { |
||||
this.main = main; |
||||
this.progressBar = progressBar; |
||||
rebuild(); |
||||
} |
||||
|
||||
public void rebuild() { |
||||
Thread t = new Thread(this); |
||||
t.setPriority(Thread.MIN_PRIORITY); |
||||
t.start(); |
||||
} |
||||
|
||||
public void run() { |
||||
if (progressBar != null) { |
||||
progressBar.setMinimum(0); |
||||
progressBar.setMaximum(countClasses(0, "")); |
||||
} |
||||
readPackage(0, new HashMap(), "", 0); |
||||
|
||||
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 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) { |
||||
Iterator iter = ((TreeElement) parent).getChilds().iterator(); |
||||
for (int i=0; i< index; i++) |
||||
iter.next(); |
||||
return iter.next(); |
||||
} |
||||
|
||||
public int getChildCount(Object parent) { |
||||
return ((TreeElement) parent).getChilds().size(); |
||||
} |
||||
|
||||
public int getIndexOfChild(Object parent, Object child) { |
||||
Iterator iter = ((TreeElement) parent).getChilds().iterator(); |
||||
int i=0; |
||||
while (iter.next() != child) |
||||
i++; |
||||
return i; |
||||
} |
||||
|
||||
public Object getRoot() { |
||||
return root; |
||||
} |
||||
|
||||
public boolean isLeaf(Object node) { |
||||
return ((TreeElement) node).getChilds().isEmpty(); |
||||
} |
||||
|
||||
public boolean isValidClass(Object node) { |
||||
return ((TreeElement) node).inClassPath; |
||||
} |
||||
|
||||
public String getFullName(Object node) { |
||||
return ((TreeElement) node).getFullName(); |
||||
} |
||||
|
||||
public TreePath getPath(String fullName) { |
||||
if (fullName == null || fullName.length() == 0) |
||||
return new TreePath(root); |
||||
|
||||
int length = 2; |
||||
ClassInfo ci = ClassInfo.forName(fullName); |
||||
while (ci.getSuperclass() != null) { |
||||
length++; |
||||
ci = ci.getSuperclass(); |
||||
} |
||||
|
||||
TreeElement[] path = new TreeElement[length]; |
||||
path[0] = root; |
||||
int nr = 0; |
||||
next_component: |
||||
while (nr < length-1) { |
||||
ci = ClassInfo.forName(fullName); |
||||
for (int i=2; i < length - nr; i++) |
||||
ci = ci.getSuperclass(); |
||||
Iterator iter = path[nr].getChilds().iterator(); |
||||
while (iter.hasNext()) { |
||||
TreeElement te = (TreeElement) iter.next(); |
||||
if (te.getFullName().equals(ci.getName())) { |
||||
path[++nr] = te; |
||||
continue next_component; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
return new TreePath(path); |
||||
} |
||||
} |
Loading…
Reference in new issue