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