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