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:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user