diff --git a/projects/viztool/src/java/com/samskivert/viztool/Driver.java b/projects/viztool/src/java/com/samskivert/viztool/Driver.java index d3bf8a4f..aa3bb400 100644 --- a/projects/viztool/src/java/com/samskivert/viztool/Driver.java +++ b/projects/viztool/src/java/com/samskivert/viztool/Driver.java @@ -1,5 +1,5 @@ // -// $Id: Driver.java,v 1.14 2001/12/01 06:22:18 mdb Exp $ +// $Id: Driver.java,v 1.15 2001/12/03 08:34:53 mdb Exp $ // // viztool - a tool for visualizing collections of java classes // Copyright (C) 2001 Michael Bayne @@ -39,18 +39,19 @@ public class Driver public static void main (String[] args) { if (args.length < 1) { - System.err.println("Usage: Driver [-print] package_root"); + System.err.println(USAGE); System.exit(-1); } // parse our arguments - String pkgroot = null; + String pkgroot = ""; + String regexp = null; boolean print = false; for (int i = 0; i < args.length; i++) { if (args[i].equals("-print")) { print = true; - } else if (pkgroot == null) { - pkgroot = args[i]; + } else if (regexp == null) { + regexp = args[i]; } } @@ -69,9 +70,17 @@ public class Driver FontPicker.init(print); // and finally generate the visualization - PackageEnumerator penum = new PackageEnumerator(pkgroot, enum, true); + FilterEnumerator fenum = null; + try { + fenum = new RegexpEnumerator(regexp, enum); + } catch (Exception e) { + Log.warning("Invalid package regular expression " + + "[regexp=" + regexp + ", error=" + e + "]."); + System.exit(-1); + } + // Visualizer viz = new HierarchyVisualizer(pkgroot, penum); - Visualizer viz = new SummaryVisualizer(pkgroot, penum); + Visualizer viz = new SummaryVisualizer(pkgroot, fenum); if (print) { // we use the print system to render things @@ -113,4 +122,11 @@ public class Driver frame.setVisible(true); } } + + protected static final String USAGE = + "Usage: Driver [-mode hier|sum] [-print] package_regexp " + + "[package_root]\n" + + " hier = class hierarchy visualization\n" + + " sum = class summary visualization\n" + ; } diff --git a/projects/viztool/src/java/com/samskivert/viztool/DriverTask.java b/projects/viztool/src/java/com/samskivert/viztool/DriverTask.java new file mode 100644 index 00000000..887c1465 --- /dev/null +++ b/projects/viztool/src/java/com/samskivert/viztool/DriverTask.java @@ -0,0 +1,160 @@ +// +// $Id: DriverTask.java,v 1.1 2001/12/03 08:34:53 mdb Exp $ +// +// viztool - a tool for visualizing collections of java classes +// Copyright (C) 2001 Michael Bayne +// +// 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.1 of the License, 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; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.viztool; + +import java.io.File; +import java.io.IOException; + +import java.util.ArrayList; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import org.apache.tools.ant.types.CommandlineJava; +import org.apache.tools.ant.types.Path; + +import com.samskivert.swing.util.SwingUtil; + +import com.samskivert.viztool.enum.ClassEnumerator; +import com.samskivert.viztool.enum.FilterEnumerator; +import com.samskivert.viztool.enum.RegexpEnumerator; +import com.samskivert.viztool.util.FontPicker; + +/** + * The viztool ant task. It takes the following arguments: + * + *
+ * pkgroot = the base package from which names will be shortened
+ * classes = a regular expression matching the classes to be visualized
+ * visualizer = the classname of the visualizer to be used
+ * 
+ * + * The task should contain an embedded <classpath> element to + * provide the classpath over which we will iterate, looking for matching + * classes. + */ +public class DriverTask extends Task +{ + public void setVisualizer (String vizclass) + { + _vizclass = vizclass; + } + + public void setPkgroot (String pkgroot) + { + _pkgroot = pkgroot; + } + + public void setClasses (String classes) + { + _classes = classes; + } + + public Path createClasspath () + { + return _cmdline.createClasspath(project).createPath(); + } + + /** + * Performs the actual work of the task. + */ + public void execute () throws BuildException + { + // initialize the font picker + FontPicker.init(false); + + // create the classloader we'll use to load the visualized classes + Path classpath = _cmdline.getClasspath(); + ClassLoader cl = new AntClassLoader(null, project, classpath, false); + + // scan the classpath and determine which classes will be + // visualized + ClassEnumerator enum = new ClassEnumerator(classpath.toString()); + FilterEnumerator fenum = null; + try { + fenum = new RegexpEnumerator(_classes, enum); + } catch (Exception e) { + throw new BuildException("Invalid package regular expression " + + "[classes=" + _classes + "].", e); + } + + ArrayList classes = new ArrayList(); + while (fenum.hasNext()) { + String cname = (String)fenum.next(); + // skip inner classes, the visualizations pick those up + // themselves + if (cname.indexOf("$") != -1) { + continue; + } + try { + classes.add(cl.loadClass(cname)); + } catch (Throwable t) { + log("Unable to introspect class [class=" + cname + + ", error=" + t + "]."); + } + } + +// // remove the packages on our exclusion list +// String expkg = System.getProperty("exclude"); +// if (expkg != null) { +// StringTokenizer tok = new StringTokenizer(expkg, ":"); +// while (tok.hasMoreTokens()) { +// pkgset.remove(tok.nextToken()); +// } +// } + + // now create our visualizer and go to work + Visualizer viz = null; + try { + viz = (Visualizer)Class.forName(_vizclass).newInstance(); + } catch (Throwable t) { + throw new BuildException("Unable to instantiate visualizer " + + "[vizclass=" + _vizclass + + ", error=" + t + "]."); + } + + viz.setPackageRoot(_pkgroot); + viz.setClasses(classes.iterator()); + + VizFrame frame = new VizFrame(viz); + frame.pack(); + SwingUtil.centerWindow(frame); + frame.setVisible(true); + + // prevent ant from kicking the JVM out from under us + synchronized (this) { + while (true) { + try { + wait(); + } catch (InterruptedException ie) { + } + } + } + } + + protected String _vizclass; + protected String _pkgroot; + protected String _classes; + + // use use this for accumulating our classpath + protected CommandlineJava _cmdline = new CommandlineJava(); +} diff --git a/projects/viztool/src/java/com/samskivert/viztool/Visualizer.java b/projects/viztool/src/java/com/samskivert/viztool/Visualizer.java index 77773a2f..93925f77 100644 --- a/projects/viztool/src/java/com/samskivert/viztool/Visualizer.java +++ b/projects/viztool/src/java/com/samskivert/viztool/Visualizer.java @@ -1,5 +1,5 @@ // -// $Id: Visualizer.java,v 1.4 2001/11/30 22:57:31 mdb Exp $ +// $Id: Visualizer.java,v 1.5 2001/12/03 08:34:53 mdb Exp $ // // viztool - a tool for visualizing collections of java classes // Copyright (C) 2001 Michael Bayne @@ -22,6 +22,7 @@ package com.samskivert.viztool; import java.awt.Graphics2D; import java.awt.print.Printable; +import java.util.Iterator; /** * The interface via which the driver accesses whichever visualizer is @@ -29,6 +30,18 @@ import java.awt.print.Printable; */ public interface Visualizer extends Printable { + /** + * Provides the visualizer with the root package which it can use to + * format package names relative to the root package. + */ + public void setPackageRoot (String pkgroot); + + /** + * Provides the visualizer with an iterator over all of the {@link + * Class} instances that it will be visualizing. + */ + public void setClasses (Iterator iterator); + /** * Requests that the visualization lay itself out in pages with the * specified dimensions. Subsequent calls to {@link #print} or {@link diff --git a/projects/viztool/src/java/com/samskivert/viztool/enum/RegexpEnumerator.java b/projects/viztool/src/java/com/samskivert/viztool/enum/RegexpEnumerator.java new file mode 100644 index 00000000..38e240d7 --- /dev/null +++ b/projects/viztool/src/java/com/samskivert/viztool/enum/RegexpEnumerator.java @@ -0,0 +1,46 @@ +// +// $Id: RegexpEnumerator.java,v 1.1 2001/12/03 08:34:53 mdb Exp $ +// +// viztool - a tool for visualizing collections of java classes +// Copyright (C) 2001 Michael Bayne +// +// 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.1 of the License, 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; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.viztool.enum; + +import java.util.Iterator; + +import org.apache.regexp.RE; +import org.apache.regexp.RESyntaxException; + +/** + * The regex enumerator filters classes based on a regular expression. + */ +public class RegexpEnumerator extends FilterEnumerator +{ + public RegexpEnumerator (String regexp, Iterator source) + throws RESyntaxException + { + super(source); + _regexp = new RE(regexp); + } + + protected boolean filterClass (String clazz) + { + return !_regexp.match(clazz); + } + + protected RE _regexp; +} diff --git a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java index e1f62174..83a067b6 100644 --- a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java +++ b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java @@ -1,5 +1,5 @@ // -// $Id: ChainGroup.java,v 1.12 2001/11/30 22:57:31 mdb Exp $ +// $Id: ChainGroup.java,v 1.13 2001/12/03 08:34:53 mdb Exp $ // // viztool - a tool for visualizing collections of java classes // Copyright (C) 2001 Michael Bayne @@ -47,7 +47,7 @@ public class ChainGroup _pkg = pkg; // process the classes provided by our enumerator - _roots = ChainUtil.buildChains(pkgroot, iter); + _roots = ChainUtil.buildChains(pkgroot, pkg, iter); // sort our roots for (int i = 0; i < _roots.size(); i++) { diff --git a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainUtil.java b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainUtil.java index d29db29f..e5710628 100644 --- a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainUtil.java +++ b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainUtil.java @@ -1,5 +1,5 @@ // -// $Id: ChainUtil.java,v 1.7 2001/11/30 22:57:31 mdb Exp $ +// $Id: ChainUtil.java,v 1.8 2001/12/03 08:34:53 mdb Exp $ // // viztool - a tool for visualizing collections of java classes // Copyright (C) 2001 Michael Bayne @@ -32,17 +32,18 @@ import com.samskivert.viztool.Log; 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. + * Builds a list of chains for 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, Iterator iter) + public static ArrayList buildChains ( + String pkgroot, String pkg, Iterator iter) { ArrayList roots = new ArrayList(); - computeRoots(pkgroot, iter, roots); + computeRoots(pkgroot, pkg, iter, roots); return roots; } @@ -84,41 +85,18 @@ public class ChainUtil * Scans the list of classes provided by the supplied iterator and * constructs a hierarchical representation of those classes. */ - protected static - void computeRoots (String pkgroot, Iterator iter, ArrayList roots) + protected static void computeRoots ( + String pkgroot, String pkg, Iterator iter, ArrayList roots) { while (iter.hasNext()) { - insertClass(roots, pkgroot, (String)iter.next(), false); - } - } - - /** - * 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, boolean outpkg) - { - try { - // sanity check - if (!clazz.startsWith(pkgroot)) { - Log.warning("Requested to process class not in target " + - "package [class=" + clazz + - ", pkgroot=" + pkgroot + "]."); - return; + Class clazz = (Class)iter.next(); + String name = clazz.getName(); + // skip classes not in the package in question + if (!name.startsWith(pkg) || + name.substring(pkg.length()+1).indexOf(".") != -1) { + continue; } - - // load and insert the class - insertClass(roots, pkgroot, Class.forName(clazz), outpkg); - - } catch (Exception e) { - Log.warning("Unable to process class [class=" + clazz + - ", error=" + e + "]."); - Log.logStackTrace(e); - - } catch (NoClassDefFoundError ncdfe) { - Log.warning("Unable to load class [class=" + clazz + - ", error=" + ncdfe + "]."); + insertClass(roots, pkgroot, clazz, false); } } diff --git a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java index 276bec2f..f1f3865a 100644 --- a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java +++ b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java @@ -1,5 +1,5 @@ // -// $Id: HierarchyVisualizer.java,v 1.15 2001/11/30 22:57:31 mdb Exp $ +// $Id: HierarchyVisualizer.java,v 1.16 2001/12/03 08:34:53 mdb Exp $ // // viztool - a tool for visualizing collections of java classes // Copyright (C) 2001 Michael Bayne @@ -25,10 +25,12 @@ import java.awt.geom.Rectangle2D; import java.awt.print.*; import java.util.*; +import com.samskivert.util.Comparators; +import com.samskivert.util.CollectionUtil; + import com.samskivert.viztool.Log; import com.samskivert.viztool.Visualizer; import com.samskivert.viztool.enum.PackageEnumerator; -import com.samskivert.util.Comparators; /** * The hierarchy visualizer displays inheritance hierarchies in a compact @@ -37,48 +39,25 @@ import com.samskivert.util.Comparators; */ public class HierarchyVisualizer implements Visualizer { - /** - * 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 iter The enumerator that will return the names of all of the - * classes in the specified package. - */ - public HierarchyVisualizer (String pkgroot, Iterator iter) + // documentation inherited + public void setPackageRoot (String pkgroot) { - // keep track of the package root _pkgroot = pkgroot; + } + // documentation inherited + public void setClasses (Iterator iter) + { // dump all the classes into an array list so that we can // repeatedly scan through the list - while (iter.hasNext()) { - // strip out inner classes, we'll catch those via their - // declaring classes - String name = (String)iter.next(); - if (name.indexOf("$") != -1) { - continue; - } - _classes.add(name); - } - // System.err.println("Scanned " + _classes.size() + " classes."); + CollectionUtil.addAll(_classes, iter); // compile a list of all packages in our collection HashSet pkgset = new HashSet(); iter = _classes.iterator(); while (iter.hasNext()) { - pkgset.add(ChainUtil.pkgFromClass((String)iter.next())); - } - - // remove the packages on our exclusion list - String expkg = System.getProperty("exclude"); - if (expkg != null) { - StringTokenizer tok = new StringTokenizer(expkg, ":"); - while (tok.hasMoreTokens()) { - pkgset.remove(tok.nextToken()); - } + Class cl = (Class)iter.next(); + pkgset.add(ChainUtil.pkgFromClass(cl.getName())); } // sort our package names @@ -93,9 +72,8 @@ public class HierarchyVisualizer implements Visualizer // now create chain groups for each package _groups = new ArrayList(); for (int i = 0; i < _packages.length; i++) { - PackageEnumerator penum = new PackageEnumerator( - _packages[i], _classes.iterator(), false); - _groups.add(new ChainGroup(pkgroot, _packages[i], penum)); + _groups.add(new ChainGroup(_pkgroot, _packages[i], + _classes.iterator())); } } diff --git a/projects/viztool/src/java/com/samskivert/viztool/summary/SummaryVisualizer.java b/projects/viztool/src/java/com/samskivert/viztool/summary/SummaryVisualizer.java index 1425b0dc..46273271 100644 --- a/projects/viztool/src/java/com/samskivert/viztool/summary/SummaryVisualizer.java +++ b/projects/viztool/src/java/com/samskivert/viztool/summary/SummaryVisualizer.java @@ -1,5 +1,5 @@ // -// $Id: SummaryVisualizer.java,v 1.2 2001/12/03 06:14:03 mdb Exp $ +// $Id: SummaryVisualizer.java,v 1.3 2001/12/03 08:34:53 mdb Exp $ // // viztool - a tool for visualizing collections of java classes // Copyright (C) 2001 Michael Bayne @@ -42,41 +42,21 @@ import com.samskivert.viztool.layout.PackedColumnElementLayout; */ public class SummaryVisualizer implements Visualizer { - /** - * Constructs a summary visualizer with the supplied enumerator as its - * source of classes. If the summary enumerator should be limited to a - * particular set of classes (and it most likely should), a filter - * enumerator should be supplied that returns only the classes to be - * visualized. - * - * @param pkgroot The name of the top-level package in which the - * visualized classes reside. This will be used to shorten the package - * names that are displayed. - * @param iter The enumerator that will return the names of the - * classes for which visualization is desired. - */ - public SummaryVisualizer (String pkgroot, Iterator iter) + // documentation inherited + public void setPackageRoot (String pkgroot) { - // keep track of the package root _pkgroot = pkgroot; + } - // create our class summaries + // documentation inherited + public void setClasses (Iterator iter) + { + // remove any old summaries + _summaries.clear(); + + // create the new summaries while (iter.hasNext()) { - // strip out inner classes, we'll catch those via their - // declaring classes - String name = (String)iter.next(); - if (name.indexOf("$") != -1) { - continue; - } - - // add a class summary instance for this class - try { - Class subject = Class.forName(name); - _summaries.add(new ClassSummary(subject, this)); - } catch (Throwable t) { - Log.warning("Unable to introspect class [class=" + name + - ", error=" + t + "]."); - } + _summaries.add(new ClassSummary((Class)iter.next(), this)); } } @@ -235,7 +215,7 @@ public class SummaryVisualizer implements Visualizer } } - protected String _pkgroot; + protected String _pkgroot = ""; protected ArrayList _summaries = new ArrayList(); protected ArrayList _pages; protected PageFormat _format;