Initial revision of visualizer package which contains the code to take a

list of classes, arrange them in some sensible order and then generate an
output (initially postscript) visualization (diagram).


git-svn-id: https://samskivert.googlecode.com/svn/trunk@161 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2001-07-04 18:24:07 +00:00
parent 893eb64605
commit 1c874bd705
4 changed files with 349 additions and 0 deletions
@@ -0,0 +1,8 @@
//
// $Id: Visualizer.java,v 1.1 2001/07/04 18:24:07 mdb Exp $
package com.samskivert.viztool.viz;
public class Visualizer
{
}
@@ -0,0 +1,128 @@
//
// $Id: Chain.java,v 1.1 2001/07/04 18:24:07 mdb Exp $
package com.samskivert.viztool.viz;
import java.util.ArrayList;
import java.awt.Dimension;
import java.awt.Point;
/**
* A chain is used by the hierarchy visualizer to represent inheritance
* chains.
*/
public class Chain
{
/**
* Constructs a chain with the specified class as its root.
*/
public Chain (Class root)
{
_root = root;
}
/**
* Returns a <code>Dimension</code> instance representing the size of
* this chain (and all contained subchains) in whatever coordinates
* are being used to diagram this chain.
*/
public Dimension getSize ()
{
return _size;
}
/**
* Returns the location of this chain in whatever coordinate system
* that is being used to diagram this chain.
*/
public Point getLocation ()
{
return _location;
}
/**
* Sets the size of this chain.
*
* @see #getSize
*/
public void setSize (int width, int height)
{
_size = new Dimension(width, height);
}
/**
* Sets the location of this chain.
*
* @see #getLocation
*/
public void setLocation (int x, int y)
{
_location = new Point(x, y);
}
/**
* Adds a child to this chain. The specified class is assumed to
* directly inherit from the class that is the root of this chain.
*/
public void addClass (Class child)
{
Chain chain = new Chain(child);
if (!_children.contains(chain)) {
_children.add(chain);
}
}
/**
* Locates the chain for the specified target class and returns it if
* it is a registered child of this chain. Returns null if no child
* chain of this chain contains the specified target class.
*/
public Chain getChain (Class target)
{
if (_root.equals(target)) {
return this;
}
// just do a depth first search because it's fun
for (int i = 0; i < _children.size(); i++) {
Chain chain = ((Chain)_children.get(i)).getChain(target);
if (chain != null) {
return chain;
}
}
return null;
}
public boolean equals (Object other)
{
if (other == null) {
return false;
} else if (other instanceof Chain) {
return ((Chain)other)._root.equals(_root);
} else {
return false;
}
}
public String toString ()
{
StringBuffer out = new StringBuffer();
toString("", out);
return out.toString();
}
protected void toString (String indent, StringBuffer out)
{
out.append(indent).append(_root.getName()).append("\n");
for (int i = 0; i < _children.size(); i++) {
Chain child = (Chain)_children.get(i);
child.toString(indent + " ", out);
}
}
protected Class _root;
protected ArrayList _children = new ArrayList();
protected Dimension _size = new Dimension(0, 0);
protected Point _location = new Point(0, 0);
}
@@ -0,0 +1,158 @@
//
// $Id: ChainUtil.java,v 1.1 2001/07/04 18:24:07 mdb Exp $
package com.samskivert.viztool.viz;
import java.util.ArrayList;
import com.samskivert.viztool.Log;
import com.samskivert.viztool.enum.Enumerator;
/**
* Chain related utility functions.
*/
public class ChainUtil
{
/**
* Builds a list of chains for all the classes enumerated by the
* supplied enumerator. Classes outside the specified package root
* will be ignored except where they are the direct parent of an
* enumerated class inside the package root.
*
* @return an array list containing all of the root chains.
*/
public static ArrayList buildChains (String pkgroot, Enumerator enum)
{
ArrayList roots = new ArrayList();
computeRoots(pkgroot, enum, roots);
return roots;
}
/**
* Looks up the chain that contains the specified target class as it's
* root class in the supplied array list of chains.
*
* @return the matching chain or null if no chain could be found.
*/
public static Chain getChain (ArrayList roots, Class target)
{
// figure out which of our root chains (if any) contains the
// specified class
for (int i = 0; i < roots.size(); i++) {
Chain root = (Chain)roots.get(i);
Chain chain = root.getChain(target);
if (chain != null) {
return chain;
}
}
return null;
}
/**
* Dumps the classes in the supplied array list of chain instances to
* stdout.
*/
public static void dumpClasses (ArrayList roots)
{
for (int i = 0; i < roots.size(); i++) {
Chain root = (Chain)roots.get(i);
System.out.print(root.toString());
}
System.out.flush();
}
/**
* Scans the list of classes provided by the supplied enumerator and
* constructs a hierarchical representation of those classes.
*/
protected static
void computeRoots (String pkgroot, Enumerator enum, ArrayList roots)
{
while (enum.hasMoreClasses()) {
insertClass(roots, pkgroot, enum.nextClass());
}
}
/**
* Loads the supplied class and inserts it into the appropriate
* position in the hierarchy based on its inheritance properties.
*/
protected static
void insertClass (ArrayList roots, String pkgroot, String clazz)
{
try {
// sanity check
if (!clazz.startsWith(pkgroot)) {
Log.warning("Requested to process class not in target " +
"package [class=" + clazz +
", pkgroot=" + pkgroot + "].");
return;
}
// load and insert the class
insertClass(roots, pkgroot, Class.forName(clazz));
} catch (Exception e) {
Log.warning("Unable to process class [class=" + clazz +
", error=" + e + "].");
}
}
/**
* Inserts the specified class into the appropriate position in the
* hierarchy based on its inheritance properties.
*/
protected static
void insertClass (ArrayList roots, String pkgroot, Class target)
{
// insert the parent of this class into the hierarchy
Class parent = target.getSuperclass();
// if we have no parent, we want to insert ourselves as a root
// class
if (parent == null || parent.equals(Object.class)) {
insertRoot(roots, target);
} else {
// if our parent is not in this package, we want to insert it
// into the hierarchy as a root class
if (!parent.getName().startsWith(pkgroot)) {
insertRoot(roots, parent);
}
// and now hang ourselves off of our parent class
Chain chain = getChain(roots, parent);
if (chain == null) {
// if there's no chain for our parent class, we'll need to
// insert it into the hierarchy
insertClass(roots, pkgroot, parent);
// and refetch our chain
chain = getChain(roots, parent);
// sanity check
if (chain == null) {
Log.warning("Chain still doesn't exist even though " +
"we inserted our parent " +
"[class=" + target.getName() +
", parent=" + parent.getName() + "].");
return;
}
}
// add class will ignore our request if this class was already
// added due to some previous operation
chain.addClass(target);
}
}
protected static boolean insertRoot (ArrayList roots, Class root)
{
Chain chroot = new Chain(root);
// make sure no chain already exists for this root
if (!roots.contains(chroot)) {
roots.add(chroot);
return true;
} else {
return false;
}
}
}
@@ -0,0 +1,55 @@
//
// $Id: HierarchyVisualizer.java,v 1.1 2001/07/04 18:24:07 mdb Exp $
package com.samskivert.viztool.viz;
import java.util.ArrayList;
import com.samskivert.viztool.Log;
import com.samskivert.viztool.enum.Enumerator;
/**
* The hierarchy visualizer displays inheritance hierarchies in a compact
* representation so that an entire package can be displayed on a single
* page (or small number of pages).
*/
public class HierarchyVisualizer
{
/**
* Constructs a hierarchy visualizer with the supplied enumerator as
* its source of classes. If the hierarchy enumerator should be
* limited to a particular set of classes, a filter enumerator should
* be supplied that returns only the classes to be visualized.
*
* @param pkgroot The name of the package that is being visualized.
* @param enum The enumerator that will return the names of all of the
* classes in the specified package.
*/
public HierarchyVisualizer (String pkgroot, Enumerator enum)
{
// keep track of these
_pkgroot = pkgroot;
_enum = enum;
// process the classes provided by our enumerator
_roots = ChainUtil.buildChains(pkgroot, enum);
}
/**
* Processes the hierarchy of class chains assigning coordinates to
* all of the chains and subchains so that they can be used to
* generate a visualization.
*/
public void layoutChains (int pointSize)
{
}
public void dumpClasses ()
{
ChainUtil.dumpClasses(_roots);
}
protected String _pkgroot;
protected Enumerator _enum;
protected ArrayList _roots;
}