From 15b5b303bf7e6fa0db82b67a7ed13054ae1c18f6 Mon Sep 17 00:00:00 2001 From: Diomidis Spinellis Date: Tue, 27 Nov 2007 07:40:28 +0000 Subject: [PATCH] Files repocopied to org/umlgraph --- src/gr/spinellis/umlgraph/doclet/.cvsignore | 1 - .../spinellis/umlgraph/doclet/ClassGraph.java | 1129 ----------------- .../spinellis/umlgraph/doclet/ClassInfo.java | 75 -- .../umlgraph/doclet/ClassMatcher.java | 39 - .../umlgraph/doclet/ContextMatcher.java | 202 --- .../umlgraph/doclet/ContextView.java | 109 -- .../umlgraph/doclet/InterfaceMatcher.java | 48 - .../umlgraph/doclet/OptionProvider.java | 58 - src/gr/spinellis/umlgraph/doclet/Options.java | 699 ---------- .../umlgraph/doclet/PackageMatcher.java | 26 - .../umlgraph/doclet/PackageView.java | 69 - .../umlgraph/doclet/PatternMatcher.java | 46 - .../umlgraph/doclet/RelationDirection.java | 51 - .../umlgraph/doclet/RelationPattern.java | 50 - .../umlgraph/doclet/RelationType.java | 10 - .../spinellis/umlgraph/doclet/StringUtil.java | 66 - .../umlgraph/doclet/SubclassMatcher.java | 41 - .../spinellis/umlgraph/doclet/UMLOptions.java | 9 - .../spinellis/umlgraph/doclet/UmlGraph.java | 170 --- .../umlgraph/doclet/UmlGraphDoc.java | 242 ---- src/gr/spinellis/umlgraph/doclet/View.java | 180 --- .../spinellis/umlgraph/doclet/Visibility.java | 44 - .../umlgraph/doclet/WrappedClassDoc.java | 362 ------ .../umlgraph/doclet/WrappedRootDoc.java | 192 --- src/gr/spinellis/umlgraph/test/BasicTest.java | 152 --- src/gr/spinellis/umlgraph/test/DotDiff.java | 308 ----- src/gr/spinellis/umlgraph/test/RunDoc.java | 48 - src/gr/spinellis/umlgraph/test/RunOne.java | 61 - .../umlgraph/test/SimpleFileFilter.java | 35 - src/gr/spinellis/umlgraph/test/TestUtils.java | 136 -- .../spinellis/umlgraph/test/UmlDocTest.java | 160 --- 31 files changed, 4818 deletions(-) delete mode 100644 src/gr/spinellis/umlgraph/doclet/.cvsignore delete mode 100644 src/gr/spinellis/umlgraph/doclet/ClassGraph.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/ClassInfo.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/ClassMatcher.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/ContextMatcher.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/ContextView.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/InterfaceMatcher.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/OptionProvider.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/Options.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/PackageMatcher.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/PackageView.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/PatternMatcher.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/RelationDirection.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/RelationPattern.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/RelationType.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/StringUtil.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/SubclassMatcher.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/UMLOptions.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/UmlGraph.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/UmlGraphDoc.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/View.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/Visibility.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/WrappedClassDoc.java delete mode 100644 src/gr/spinellis/umlgraph/doclet/WrappedRootDoc.java delete mode 100644 src/gr/spinellis/umlgraph/test/BasicTest.java delete mode 100644 src/gr/spinellis/umlgraph/test/DotDiff.java delete mode 100644 src/gr/spinellis/umlgraph/test/RunDoc.java delete mode 100644 src/gr/spinellis/umlgraph/test/RunOne.java delete mode 100644 src/gr/spinellis/umlgraph/test/SimpleFileFilter.java delete mode 100644 src/gr/spinellis/umlgraph/test/TestUtils.java delete mode 100644 src/gr/spinellis/umlgraph/test/UmlDocTest.java diff --git a/src/gr/spinellis/umlgraph/doclet/.cvsignore b/src/gr/spinellis/umlgraph/doclet/.cvsignore deleted file mode 100644 index a953aa4..0000000 --- a/src/gr/spinellis/umlgraph/doclet/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -Version.java diff --git a/src/gr/spinellis/umlgraph/doclet/ClassGraph.java b/src/gr/spinellis/umlgraph/doclet/ClassGraph.java deleted file mode 100644 index 2c608ed..0000000 --- a/src/gr/spinellis/umlgraph/doclet/ClassGraph.java +++ /dev/null @@ -1,1129 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.ConstructorDoc; -import com.sun.javadoc.Doc; -import com.sun.javadoc.FieldDoc; -import com.sun.javadoc.MethodDoc; -import com.sun.javadoc.PackageDoc; -import com.sun.javadoc.Parameter; -import com.sun.javadoc.ParameterizedType; -import com.sun.javadoc.ProgramElementDoc; -import com.sun.javadoc.RootDoc; -import com.sun.javadoc.Tag; -import com.sun.javadoc.Type; -import com.sun.javadoc.TypeVariable; -import com.sun.javadoc.WildcardType; - -/** - * Class graph generation engine - * @depend - - - StringUtil - * @depend - - - Options - * @composed - - * ClassInfo - * @has - - - OptionProvider - * - * @version $Revision$ - * @author Diomidis Spinellis - */ -class ClassGraph { - protected static final char FILE_SEPARATOR = '/'; - enum Font { - NORMAL, ABSTRACT, CLASS, CLASS_ABSTRACT, TAG, PACKAGE - } - enum Align { - LEFT, CENTER, RIGHT - }; - public static Map associationMap = new HashMap(); - static { - associationMap.put(RelationType.ASSOC, "arrowhead=none"); - associationMap.put(RelationType.NAVASSOC, "arrowhead=open"); - associationMap.put(RelationType.HAS, "arrowhead=none, arrowtail=ediamond"); - associationMap.put(RelationType.COMPOSED, "arrowhead=none, arrowtail=diamond"); - associationMap.put(RelationType.DEPEND, "arrowhead=open, style=dashed"); - } - protected Map classnames = new HashMap(); - protected Set rootClasses; - protected OptionProvider optionProvider; - protected PrintWriter w; - protected ClassDoc collectionClassDoc; - protected ClassDoc mapClassDoc; - protected String linePostfix; - protected String linePrefix; - - // used only when generating context class diagrams in UMLDoc, to generate the proper - // relative links to other classes in the image map - protected Doc contextDoc; - - /** - * Create a new ClassGraph.

The packages passed as an - * argument are the ones specified on the command line.

- *

Local URLs will be generated for these packages.

- * @param root The root of docs as provided by the javadoc API - * @param optionProvider The main option provider - * @param contextDoc The current context for generating relative links, may be a ClassDoc - * or a PackageDoc (used by UMLDoc) - */ - public ClassGraph(RootDoc root, OptionProvider optionProvider, Doc contextDoc) { - this.optionProvider = optionProvider; - this.collectionClassDoc = root.classNamed("java.util.Collection"); - this.mapClassDoc = root.classNamed("java.util.Map"); - this.contextDoc = contextDoc; - - // to gather the packages containing specified classes, loop thru them and gather - // package definitions. User root.specifiedPackages is not safe, since the user - // may specify just a list of classes (human users usually don't, but automated tools do) - rootClasses = new HashSet(); - for (ClassDoc classDoc : root.classes()) - rootClasses.add(classDoc.qualifiedName()); - - Options opt = optionProvider.getGlobalOptions(); - if (opt.compact) { - linePrefix = ""; - linePostfix = ""; - } else { - linePrefix = "\t"; - linePostfix = "\n"; - } - } - - - - /** Return the class's name, possibly by stripping the leading path */ - private String qualifiedName(Options opt, String r) { - if (!opt.showQualified) { - // Create readable string by stripping leading path - for (;;) { - int dotpos = r.lastIndexOf('.'); - if (dotpos == -1) break; // Work done! - /* - * Change all occurences of - * "p1.p2.myClass" into - * "myClass" - */ - int start = dotpos; - while (start > 0 && Character.isJavaIdentifierPart(r.charAt(start - 1))) - start--; - r = r.substring(0, start) + r.substring(dotpos + 1); - } - } - return r; - } - - /** - * Escape <, >, and & characters in the string with - * the corresponding HTML entity code. - */ - private String escape(String s) { - final Pattern toEscape = Pattern.compile("[&<>]"); - - if (toEscape.matcher(s).find()) { - StringBuffer sb = new StringBuffer(s); - for (int i = 0; i < sb.length();) { - switch (sb.charAt(i)) { - case '&': - sb.replace(i, i + 1, "&"); - i += "&".length(); - break; - case '<': - sb.replace(i, i + 1, "<"); - i += "<".length(); - break; - case '>': - sb.replace(i, i + 1, ">"); - i += ">".length(); - break; - default: - i++; - } - } - return sb.toString(); - } else - return s; - } - - - /** - * Convert < and > characters in the string to the respective guillemot characters. - */ - private String guillemize(Options opt, String s) { - StringBuffer r = new StringBuffer(s); - for (int i = 0; i < r.length();) - switch (r.charAt(i)) { - case '<': - r.replace(i, i + 1, opt.guilOpen); - i += opt.guilOpen.length(); - break; - case '>': - r.replace(i, i + 1, opt.guilClose); - i += opt.guilClose.length(); - break; - default: - i++; - break; - } - return r.toString(); - } - - /** - * Wraps a string in Guillemot (or an ASCII substitute) characters. - * - * @param str the String to be wrapped. - * @return the wrapped String. - */ - private String guilWrap(Options opt, String str) { - return opt.guilOpen + str + opt.guilClose; - } - - /** - * Print the visibility adornment of element e prefixed by - * any stereotypes - */ - private String visibility(Options opt, ProgramElementDoc e) { - if (!opt.showVisibility) - return " "; - if (e.isPrivate()) - return "- "; - else if (e.isPublic()) - return "+ "; - else if (e.isProtected()) - return "# "; - else if (e.isPackagePrivate()) - return "~ "; - else - return " "; - } - - /** Print the method parameter p */ - private String parameter(Options opt, Parameter p[]) { - String par = ""; - for (int i = 0; i < p.length; i++) { - par += p[i].name() + typeAnnotation(opt, p[i].type()); - if (i + 1 < p.length) - par += ", "; - } - return par; - } - - /** Print a a basic type t */ - private String type(Options opt, Type t) { - String type = ""; - if (opt.showQualified) - type = t.qualifiedTypeName(); - else - type = t.typeName(); - type += typeParameters(opt, t.asParameterizedType()); - return type; - } - - /** Print the parameters of the parameterized type t */ - private String typeParameters(Options opt, ParameterizedType t) { - String tp = ""; - if (t == null) - return tp; - Type args[] = t.typeArguments(); - tp += "<"; - for (int i = 0; i < args.length; i++) { - tp += type(opt, args[i]); - if (i != args.length - 1) - tp += ", "; - } - tp += ">"; - return tp; - } - - /** Annotate an field/argument with its type t */ - private String typeAnnotation(Options opt, Type t) { - String ta = ""; - if (t.typeName().equals("void")) - return ta; - ta += " : "; - ta += type(opt, t); - ta += t.dimension(); - return ta; - } - - /** Print the class's attributes fd */ - private void attributes(Options opt, FieldDoc fd[]) { - for (FieldDoc f : fd) { - if (hidden(f)) - continue; - String att = ""; - stereotype(opt, f, Align.LEFT); - att = visibility(opt, f) + f.name(); - if (opt.showType) - att += typeAnnotation(opt, f.type()); - tableLine(Align.LEFT, att); - tagvalue(opt, f); - } - } - - /* - * The following two methods look similar, but can't - * be refactored into one, because their common interface, - * ExecutableMemberDoc, doesn't support returnType for ctors. - */ - - /** Print the class's constructors m */ - private boolean operations(Options opt, ConstructorDoc m[]) { - boolean printed = false; - for (ConstructorDoc cd : m) { - if (hidden(cd)) - continue; - stereotype(opt, cd, Align.LEFT); - String cs = visibility(opt, cd) + cd.name(); - if (opt.showType) { - cs += "(" + parameter(opt, cd.parameters()) + ")"; - } else { - cs += "()"; - } - tableLine(Align.LEFT, cs); - printed = true; - tagvalue(opt, cd); - } - return printed; - } - - /** Print the class's operations m */ - private boolean operations(Options opt, MethodDoc m[]) { - boolean printed = false; - for (MethodDoc md : m) { - if (hidden(md)) - continue; - // Filter-out static initializer method - if (md.name().equals("") && md.isStatic() && md.isPackagePrivate()) - continue; - stereotype(opt, md, Align.LEFT); - String op = visibility(opt, md) + md.name(); - if (opt.showType) { - op += "(" + parameter(opt, md.parameters()) + ")" - + typeAnnotation(opt, md.returnType()); - } else { - op += "()"; - } - tableLine(Align.LEFT, op, opt, md.isAbstract() ? Font.ABSTRACT : Font.NORMAL); - printed = true; - - tagvalue(opt, md); - } - return printed; - } - - /** Print the common class node's properties */ - private void nodeProperties(Options opt) { - w.print(", fontname=\"" + opt.nodeFontName + "\""); - w.print(", fontcolor=\"" + opt.nodeFontColor + "\""); - w.print(", fontsize=" + opt.nodeFontSize); - w.println("];"); - } - - /** - * Return as a string the tagged values associated with c - * @param opt the Options used to guess font names - * @param c the Doc entry to look for @tagvalue - * @param prevterm the termination string for the previous element - * @param term the termination character for each tagged value - */ - private void tagvalue(Options opt, Doc c) { - Tag tags[] = c.tags("tagvalue"); - if (tags.length == 0) - return; - - for (Tag tag : tags) { - String t[] = StringUtil.tokenize(tag.text()); - if (t.length != 2) { - System.err.println("@tagvalue expects two fields: " + tag.text()); - continue; - } - tableLine(Align.RIGHT, "{" + t[0] + " = " + t[1] + "}", opt, Font.TAG); - } - } - - /** - * Return as a string the stereotypes associated with c - * terminated by the escape character term - */ - private void stereotype(Options opt, Doc c, Align align) { - for (Tag tag : c.tags("stereotype")) { - String t[] = StringUtil.tokenize(tag.text()); - if (t.length != 1) { - System.err.println("@stereotype expects one field: " + tag.text()); - continue; - } - tableLine(align, guilWrap(opt, t[0])); - } - } - - /** Return true if c has a @hidden tag associated with it */ - private boolean hidden(ProgramElementDoc c) { - Tag tags[] = c.tags("hidden"); - if (tags.length > 0) - return true; - tags = c.tags("view"); - if (tags.length > 0) - return true; - Options opt; - if(c instanceof ClassDoc) - opt = optionProvider.getOptionsFor((ClassDoc) c); - else - opt = optionProvider.getOptionsFor(c.containingClass()); - return opt.matchesHideExpression(c.toString()); - } - - protected ClassInfo getClassInfo(String className) { - return classnames.get(removeTemplate(className)); - } - - private ClassInfo newClassInfo(String className, boolean printed, boolean hidden) { - ClassInfo ci = new ClassInfo(printed, hidden); - classnames.put(removeTemplate(className), ci); - return ci; - } - - /** Return true if the class name is associated to an hidden class or matches a hide expression */ - private boolean hidden(String s) { - ClassInfo ci = getClassInfo(s); - Options opt = optionProvider.getOptionsFor(s); - if(ci != null) - return ci.hidden || opt.matchesHideExpression(s); - else - return opt.matchesHideExpression(s); - } - - - - /** - * Prints the class if needed. - *

- * A class is a rootClass if it's included among the classes returned by - * RootDoc.classes(), this information is used to properly compute - * relative links in diagrams for UMLDoc - */ - public String printClass(ClassDoc c, boolean rootClass) { - ClassInfo ci; - boolean toPrint; - Options opt = optionProvider.getOptionsFor(c); - - String className = c.toString(); - if ((ci = getClassInfo(className)) != null) - toPrint = !ci.nodePrinted; - else { - toPrint = true; - ci = newClassInfo(className, true, hidden(c)); - } - if (toPrint && !hidden(c) && (!c.isEnum() || opt.showEnumerations)) { - // Associate classname's alias - String r = className; - w.println("\t// " + r); - // Create label - w.print("\t" + ci.name + " [label="); - externalTableStart(opt, c.qualifiedName(), classToUrl(c, rootClass)); - innerTableStart(); - if (c.isInterface()) - tableLine(Align.CENTER, guilWrap(opt, "interface")); - if (c.isEnum()) - tableLine(Align.CENTER, guilWrap(opt, "enumeration")); - stereotype(opt, c, Align.CENTER); - Font font = c.isAbstract() && !c.isInterface() ? Font.CLASS_ABSTRACT : Font.CLASS; - String qualifiedName = qualifiedName(opt, r); - int startTemplate = qualifiedName.indexOf('<'); - int idx = 0; - if(startTemplate < 0) - idx = qualifiedName.lastIndexOf('.'); - else - idx = qualifiedName.lastIndexOf('.', startTemplate); - if(opt.postfixPackage && idx > 0 && idx < (qualifiedName.length() - 1)) { - String packageName = qualifiedName.substring(0, idx); - String cn = className.substring(idx + 1); - tableLine(Align.CENTER, escape(cn), opt, font); - tableLine(Align.CENTER, packageName, opt, Font.PACKAGE); - } else { - tableLine(Align.CENTER, escape(qualifiedName), opt, font); - } - tagvalue(opt, c); - innerTableEnd(); - - boolean showMembers = - (opt.showAttributes && c.fields().length > 0) || - (c.isEnum() && opt.showEnumConstants && c.enumConstants().length > 0) || - (opt.showOperations && c.methods().length > 0) || - (opt.showConstructors && c.constructors().length > 0); - - if (showMembers) { - if (opt.showAttributes) { - innerTableStart(); - FieldDoc[] fields = c.fields(); - // if there are no fields, print an empty line to generate proper HTML - if (fields.length == 0) - tableLine(Align.LEFT, ""); - else - attributes(opt, c.fields()); - innerTableEnd(); - } else if(!c.isEnum() && (opt.showConstructors || opt.showOperations)) { - // show an emtpy box if we don't show attributes but - // we show operations - innerTableStart(); - tableLine(Align.LEFT, ""); - innerTableEnd(); - } - if (c.isEnum() && opt.showEnumConstants) { - innerTableStart(); - FieldDoc[] ecs = c.enumConstants(); - // if there are no constants, print an empty line to generate proper HTML - if (ecs.length == 0) { - tableLine(Align.LEFT, ""); - } else { - for (FieldDoc fd : c.enumConstants()) { - tableLine(Align.LEFT, fd.name()); - } - } - innerTableEnd(); - } - if (!c.isEnum() && (opt.showConstructors || opt.showOperations)) { - innerTableStart(); - boolean printedLines = false; - if (opt.showConstructors) - printedLines |= operations(opt, c.constructors()); - if (opt.showOperations) - printedLines |= operations(opt, c.methods()); - - if (!printedLines) - // if there are no operations nor constructors, - // print an empty line to generate proper HTML - tableLine(Align.LEFT, ""); - - innerTableEnd(); - } - } - externalTableEnd(); - nodeProperties(opt); - ci.nodePrinted = true; - } - return ci.name; - } - - private String getNodeName(ClassDoc c) { - String className = c.toString(); - ClassInfo ci = getClassInfo(className); - if (ci == null) - ci = newClassInfo(className, false, hidden(c)); - return ci.name; - } - - /** Return a class's internal name */ - private String getNodeName(String c) { - ClassInfo ci = getClassInfo(c); - - if (ci == null) - ci = newClassInfo(c, false, false); - return ci.name; - } - - /** - * Print all relations for a given's class's tag - * @param tagname the tag containing the given relation - * @param from the source class - * @param fromName the source class internal name - * @param edgetype the dot edge specification - */ - private void relation(Options opt, RelationType rt, ClassDoc from, String fromName) { - String tagname = rt.toString().toLowerCase(); - for (Tag tag : from.tags(tagname)) { - String t[] = StringUtil.tokenize(tag.text()); // l-src label l-dst target - if (t.length != 4) { - System.err.println("Error in " + from + "\n" + tagname + " expects four fields (l-src label l-dst target): " + tag.text()); - return; - } - String dest = t[3]; - String destName = null; - ClassDoc to = from.findClass(t[3]); - if(to != null) { - dest = to.toString(); - destName = getNodeName(dest); - } else { - destName = getNodeName(t[3]); - } - - if(hidden(dest)) - continue; - relation(opt, rt, from.toString(), fromName, dest, destName, t[0], t[1], t[2]); - } - } - - private void relation(Options opt, RelationType rt, String from, String fromName, - String dest, String destName, String tailLabel, String label, String headLabel) { - // print relation - String edgetype = associationMap.get(rt); - w.println("\t// " + from + " " + rt.toString() + " " + dest); - w.println("\t" + fromName + ":p -> " + destName + ":p [" + - "taillabel=\"" + tailLabel + "\", " + - "label=\"" + guillemize(opt, label) + "\", " + - "headlabel=\"" + headLabel + "\", " + - "fontname=\"" + opt.edgeFontName + "\", " + - "fontcolor=\"" + opt.edgeFontColor + "\", " + - "fontsize=" + opt.edgeFontSize + ", " + - "color=\"" + opt.edgeColor + "\", " + - edgetype + "];" - ); - - // update relation info - RelationDirection d = RelationDirection.BOTH; - if(rt == RelationType.NAVASSOC || rt == RelationType.DEPEND) - d = RelationDirection.OUT; - getClassInfo(from).addRelation(dest, rt, d); - getClassInfo(dest).addRelation(from, rt, d.inverse()); - - } - - /** Print a class's relations */ - public void printRelations(ClassDoc c) { - Options opt = optionProvider.getOptionsFor(c); - if (hidden(c) || c.name().equals("")) // avoid phantom classes, they may pop up when the source uses annotations - return; - String className = c.toString(); - String cs = getNodeName(c); - - // Print generalization (through the Java superclass) - Type s = c.superclassType(); - if (s != null && - !s.toString().equals("java.lang.Object") && - !c.isEnum() && - !hidden(s.asClassDoc())) { - ClassDoc sc = s.asClassDoc(); - w.println("\t//" + c + " extends " + s + "\n" + - "\t" + getNodeName(sc) + ":p -> " + cs + ":p [dir=back,arrowtail=empty];"); - getClassInfo(className).addRelation(sc.toString(), RelationType.EXTENDS, RelationDirection.OUT); - getClassInfo(sc.toString()).addRelation(className, RelationType.EXTENDS, RelationDirection.IN); - } - - // Print generalizations (through @extends tags) - for (Tag tag : c.tags("extends")) - if (!hidden(tag.text())) { - w.println("\t//" + c + " extends " + tag.text() + "\n" + - "\t" + getNodeName(tag.text()) + ":p -> " + cs + ":p [dir=back,arrowtail=empty];"); - getClassInfo(className).addRelation(tag.text(), RelationType.EXTENDS, RelationDirection.OUT); - getClassInfo(tag.text()).addRelation(className, RelationType.EXTENDS, RelationDirection.IN); - } - // Print realizations (Java interfaces) - for (Type iface : c.interfaceTypes()) { - ClassDoc ic = iface.asClassDoc(); - if (!hidden(ic)) { - w.println("\t//" + c + " implements " + ic + "\n\t" + getNodeName(ic) + ":p -> " + cs + ":p [dir=back,arrowtail=empty,style=dashed];" - ); - getClassInfo(className).addRelation(ic.toString(), RelationType.IMPLEMENTS, RelationDirection.OUT); - getClassInfo(ic.toString()).addRelation(className, RelationType.IMPLEMENTS, RelationDirection.IN); - } - } - // Print other associations - relation(opt, RelationType.ASSOC, c, cs); - relation(opt, RelationType.NAVASSOC, c, cs); - relation(opt, RelationType.HAS, c, cs); - relation(opt, RelationType.COMPOSED, c, cs); - relation(opt, RelationType.DEPEND, c, cs); - } - - /** Print classes that were parts of relationships, but not parsed by javadoc */ - public void printExtraClasses(RootDoc root) { - Set names = new HashSet(classnames.keySet()); - for(String className: names) { - ClassInfo info = getClassInfo(className); - if (!info.nodePrinted) { - ClassDoc c = root.classNamed(className); - if(c != null) { - printClass(c, false); - } else { - Options opt = optionProvider.getOptionsFor(className); - if(opt.matchesHideExpression(className)) - continue; - w.println("\t// " + className); - w.print("\t" + info.name + "[label="); - externalTableStart(opt, className, classToUrl(className)); - innerTableStart(); - int idx = className.lastIndexOf("."); - if(opt.postfixPackage && idx > 0 && idx < (className.length() - 1)) { - String packageName = className.substring(0, idx); - String cn = className.substring(idx + 1); - tableLine(Align.CENTER, escape(cn), opt, Font.CLASS); - tableLine(Align.CENTER, packageName, opt, Font.PACKAGE); - } else { - tableLine(Align.CENTER, escape(className), opt, Font.CLASS); - } - innerTableEnd(); - externalTableEnd(); - nodeProperties(opt); - } - } - } - } - - /** - * Prints associations recovered from the fields of a class. An association is inferred only - * if another relation between the two classes is not already in the graph. - * @param classes - */ - public void printInferredRelations(ClassDoc[] classes) { - for (ClassDoc c : classes) { - printInferredRelations(c); - } - } - - /** - * Prints associations recovered from the fields of a class. An association is inferred only - * if another relation between the two classes is not already in the graph. - * @param classes - */ - public void printInferredRelations(ClassDoc c) { - Options opt = optionProvider.getOptionsFor(c); - - // check if the source is excluded from inference - String sourceName = c.toString(); - if (hidden(c)) - return; - - for (FieldDoc field : c.fields(false)) { - // skip statics - if(field.isStatic()) - continue; - - // skip primitives - FieldRelationInfo fri = getFieldRelationInfo(field); - if (fri == null) - continue; - - // check if the destination is excluded from inference - if (hidden(fri.cd)) - continue; - - String dest = fri.cd.toString(); - String destAdornment = fri.multiple ? "*" : ""; - relation(opt, opt.inferRelationshipType, sourceName, getNodeName(c), dest, - getNodeName(dest), "", "", destAdornment); - } - } - - /** - * Prints dependencies recovered from the methods of a class. A - * dependency is inferred only if another relation between the two - * classes is not already in the graph. - * @param classes - */ - public void printInferredDependencies(ClassDoc[] classes) { - for (ClassDoc c : classes) { - printInferredDependencies(c); - } - } - - /** - * Prints dependencies recovered from the methods of a class. A - * dependency is inferred only if another relation between the two - * classes is not already in the graph. - * @param classes - */ - public void printInferredDependencies(ClassDoc c) { - Options opt = optionProvider.getOptionsFor(c); - - String sourceName = c.toString(); - if (hidden(c)) - return; - - Set types = new HashSet(); - // harvest method return and parameter types - for (MethodDoc method : filterByVisibility(c.methods(false), opt.inferDependencyVisibility)) { - types.add(method.returnType()); - for (Parameter parameter : method.parameters()) { - types.add(parameter.type()); - } - } - // and the field types - if (!opt.inferRelationships) { - for (FieldDoc field : filterByVisibility(c.fields(false), opt.inferDependencyVisibility)) { - types.add(field.type()); - } - } - // see if there are some type parameters - if (c.asParameterizedType() != null) { - ParameterizedType pt = c.asParameterizedType(); - types.addAll(Arrays.asList(pt.typeArguments())); - } - // see if type parameters extend something - for(TypeVariable tv: c.typeParameters()) { - if(tv.bounds().length > 0 ) - types.addAll(Arrays.asList(tv.bounds())); - } - - // and finally check for explicitly imported classes (this - // assumes there are no unused imports...) - if (opt.useImports) - types.addAll(Arrays.asList(c.importedClasses())); - - // compute dependencies - for (Type type : types) { - // skip primitives and type variables, as well as dependencies - // on the source class - if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable - || c.toString().equals(type.asClassDoc().toString())) - continue; - - // check if the destination is excluded from inference - ClassDoc fc = type.asClassDoc(); - String destName = fc.toString(); - if (hidden(fc)) - continue; - - // check if source and destination are in the same package and if we are allowed - // to infer dependencies between classes in the same package - if(!opt.inferDepInPackage && c.containingPackage().equals(fc.containingPackage())) - continue; - - // if source and dest are not already linked, add a dependency - RelationPattern rp = getClassInfo(sourceName).getRelation(destName); - if (rp == null || rp.matchesOne(new RelationPattern(RelationDirection.OUT))) { - relation(opt, RelationType.DEPEND, sourceName, getNodeName(sourceName), destName, - getNodeName(destName), "", "", ""); - } - - } - } - - /** - * Returns all program element docs that have a visibility greater or - * equal than the specified level - */ - private List filterByVisibility(T[] docs, Visibility visibility) { - if (visibility == Visibility.PRIVATE) - return Arrays.asList(docs); - - List filtered = new ArrayList(); - for (T doc : docs) { - if (Visibility.get(doc).compareTo(visibility) > 0) - filtered.add(doc); - } - return filtered; - } - - - - private FieldRelationInfo getFieldRelationInfo(FieldDoc field) { - Type type = field.type(); - if(type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable) - return null; - - if (type.dimension().endsWith("[]")) { - return new FieldRelationInfo(type.asClassDoc(), true); - } - - Options opt = optionProvider.getOptionsFor(type.asClassDoc()); - if (opt.matchesCollPackageExpression(type.qualifiedTypeName())) { - Type[] argTypes = getInterfaceTypeArguments(collectionClassDoc, type); - if (argTypes != null && argTypes.length == 1 && !argTypes[0].isPrimitive()) - return new FieldRelationInfo(argTypes[0].asClassDoc(), true); - - argTypes = getInterfaceTypeArguments(mapClassDoc, type); - if (argTypes != null && argTypes.length == 2 && !argTypes[1].isPrimitive()) - return new FieldRelationInfo(argTypes[1].asClassDoc(), true); - } - - return new FieldRelationInfo(type.asClassDoc(), false); - } - - private Type[] getInterfaceTypeArguments(ClassDoc iface, Type t) { - if (t instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) t; - if (iface.equals(t.asClassDoc())) { - return pt.typeArguments(); - } else { - for (Type pti : pt.interfaceTypes()) { - Type[] result = getInterfaceTypeArguments(iface, pti); - if (result != null) - return result; - } - if (pt.superclassType() != null) - return getInterfaceTypeArguments(iface, pt.superclassType()); - } - } else if (t instanceof ClassDoc) { - ClassDoc cd = (ClassDoc) t; - for (Type pti : cd.interfaceTypes()) { - Type[] result = getInterfaceTypeArguments(iface, pti); - if (result != null) - return result; - } - if (cd.superclassType() != null) - return getInterfaceTypeArguments(iface, cd.superclassType()); - } - return null; - } - - /** Removes the template specs from a class name. */ - private String removeTemplate(String name) { - int openIdx = name.indexOf('<'); - if(openIdx == -1) - return name; - else - return name.substring(0, openIdx); - } - - /** Convert the class name into a corresponding URL */ - public String classToUrl(ClassDoc cd, boolean rootClass) { - // building relative path for context and package diagrams - if(contextDoc != null && rootClass) { - // determine the context path, relative to the root - String packageName = null; - if (contextDoc instanceof ClassDoc) { - packageName = ((ClassDoc) contextDoc).containingPackage().name(); - } else if (contextDoc instanceof PackageDoc) { - packageName = ((PackageDoc) contextDoc).name(); - } else { - return classToUrl(cd.qualifiedName()); - } - return buildRelativePath(packageName, cd.containingPackage().name()) + cd.name() + ".html"; - } else { - return classToUrl(cd.qualifiedName()); - } - } - - protected static String buildRelativePath(String contextPackageName, String classPackageName) { - // path, relative to the root, of the destination class - String[] contextClassPath = contextPackageName.split("\\."); - String[] currClassPath = classPackageName.split("\\."); - - // compute relative path between the context and the destination - // ... first, compute common part - int i = 0; - while (i < contextClassPath.length && i < currClassPath.length - && contextClassPath[i].equals(currClassPath[i])) - i++; - // ... go up with ".." to reach the common root - StringBuffer buf = new StringBuffer(); - if (i == contextClassPath.length) { - buf.append(".").append(FILE_SEPARATOR); - } else { - for (int j = i; j < contextClassPath.length; j++) { - buf.append("..").append(FILE_SEPARATOR); - } - } - // ... go down from the common root to the destination - for (int j = i; j < currClassPath.length; j++) { - buf.append(currClassPath[j]).append(FILE_SEPARATOR); - } - return buf.toString(); - } - - /** Convert the class name into a corresponding URL */ - public String classToUrl(String className) { - String docRoot = mapApiDocRoot(className); - if (docRoot != null) { - StringBuffer buf = new StringBuffer(docRoot); - buf.append(className.replace('.', FILE_SEPARATOR)); - buf.append(".html"); - return buf.toString(); - } else { - return null; - } - } - - /** - * Returns the appropriate URL "root" for a given class name. - * The root will be used as the prefix of the URL used to link the class in - * the final diagram to the associated JavaDoc page. - */ - private String mapApiDocRoot(String className) { - String root = null; - /* If no packages are specified, we use apiDocRoot for all of them. */ - if (rootClasses.contains(className)) { - root = optionProvider.getGlobalOptions().apiDocRoot; - } else { - Options globalOptions = optionProvider.getGlobalOptions(); - root = globalOptions.getApiDocRoot(className); - } - return root; - } - - - /** Dot prologue - * @throws IOException */ - public void prologue() throws IOException { - Options opt = optionProvider.getGlobalOptions(); - OutputStream os = null; - - if (opt.outputFileName.equals("-")) - os = System.out; - else { - // prepare output file. Use the output file name as a full path unless the output - // directory is specified - File file = null; - if (opt.outputDirectory != null) - file = new File(opt.outputDirectory, opt.outputFileName); - else - file = new File(opt.outputFileName); - // make sure the output directory are there, otherwise create them - if (file.getParentFile() != null - && !file.getParentFile().exists()) - file.getParentFile().mkdirs(); - os = new FileOutputStream(file); - } - - // print plologue - w = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(os), opt.outputEncoding)); - w.println( - "#!/usr/local/bin/dot\n" + - "#\n" + - "# Class diagram \n" + - "# Generated by UmlGraph version " + - Version.VERSION + " (http://www.spinellis.gr/sw/umlgraph)\n" + - "#\n\n" + - "digraph G {\n" + - "\tedge [fontname=\"" + opt.edgeFontName + - "\",fontsize=10,labelfontname=\"" + opt.edgeFontName + - "\",labelfontsize=10];\n" + - "\tnode [fontname=\"" + opt.nodeFontName + - "\",fontsize=10,shape=plaintext];" - ); - if (opt.horizontal) - w.println("\trankdir=LR;\n\tranksep=1;"); - if (opt.bgColor != null) - w.println("\tbgcolor=\"" + opt.bgColor + "\";\n"); - } - - /** Dot epilogue */ - public void epilogue() { - w.println("}\n"); - w.flush(); - w.close(); - } - - private void externalTableStart(Options opt, String name, String url) { - String bgcolor = ""; - if (opt.nodeFillColor != null) - bgcolor = " bgcolor=\""+ opt.nodeFillColor + "\""; - String href = ""; - if (url != null) - href = " href=\"" + url + "\""; - w.print("<" + linePostfix); - } - - private void externalTableEnd() { - w.print(linePrefix + linePrefix + "
>"); - } - - private void innerTableStart() { - w.print(linePrefix + linePrefix + "" + linePostfix); - } - - private void innerTableEnd() { - w.print(linePrefix + linePrefix + "
" + linePostfix); - } - - private void tableLine(Align align, String text) { - tableLine(align, text, null, Font.NORMAL); - } - - private void tableLine(Align align, String text, Options opt, Font font) { - String open; - String close = ""; - String prefix = linePrefix + linePrefix + linePrefix; - if(align == Align.CENTER) - open = prefix + ""; - else if(align == Align.LEFT) - open = prefix + ""; - else if(align == Align.RIGHT) - open = prefix + ""; - else - throw new RuntimeException("Unknown alignement type " + align); - - text = fontWrap(" " + text + " ", opt, font); - w.print(open + text + close + linePostfix); - } - - /** - * Wraps the text with the appropriate font according to the specified font type - * @param opt - * @param text - * @param font - * @return - */ - private String fontWrap(String text, Options opt, Font font) { - if(font == Font.ABSTRACT) { - return fontWrap(text, opt.nodeFontAbstractName, opt.nodeFontSize); - } else if(font == Font.CLASS) { - return fontWrap(text, opt.nodeFontClassName, opt.nodeFontClassSize); - } else if(font == Font.CLASS_ABSTRACT) { - String name; - if(opt.nodeFontClassAbstractName == null) - name = opt.nodeFontAbstractName; - else - name = opt.nodeFontClassAbstractName; - return fontWrap(text, name, opt.nodeFontClassSize); - } else if(font == Font.PACKAGE) { - return fontWrap(text, opt.nodeFontPackageName, opt.nodeFontPackageSize); - } else if(font == Font.TAG) { - return fontWrap(text, opt.nodeFontTagName, opt.nodeFontTagSize); - } else { - return text; - } - } - - /** - * Wraps the text with the appropriate font tags when the font name - * and size are not void - * @param text the text to be wrapped - * @param fontName considered void when it's null - * @param fontSize considered void when it's <= 0 - */ - private String fontWrap(String text, String fontName, double fontSize) { - if(fontName == null && fontSize == -1) - return text; - else if(fontName == null) - return "" + text + ""; - else if(fontSize <= 0) - return "" + text + ""; - else - return "" + text + ""; - } - - private static class FieldRelationInfo { - ClassDoc cd; - boolean multiple; - - public FieldRelationInfo(ClassDoc cd, boolean multiple) { - this.cd = cd; - this.multiple = multiple; - } - } -} diff --git a/src/gr/spinellis/umlgraph/doclet/ClassInfo.java b/src/gr/spinellis/umlgraph/doclet/ClassInfo.java deleted file mode 100644 index 045194c..0000000 --- a/src/gr/spinellis/umlgraph/doclet/ClassInfo.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Class's dot-comaptible alias name (for fully qualified class names) - * and printed information - * @version $Revision$ - * @author Diomidis Spinellis - */ -class ClassInfo { - private static int classNumber; - /** Alias name for the class */ - String name; - /** True if the class class node has been printed */ - boolean nodePrinted; - /** True if the class class node is hidden */ - boolean hidden; - /** - * The list of classes that share a relation with this one. Contains - * all the classes linked with a bi-directional relation , and the ones - * referred by a directed relation - */ - Map relatedClasses = new HashMap(); - - ClassInfo(boolean p, boolean h) { - nodePrinted = p; - hidden = h; - name = "c" + (new Integer(classNumber)).toString(); - classNumber++; - } - - public void addRelation(String dest, RelationType rt, RelationDirection d) { - RelationPattern ri = relatedClasses.get(dest); - if(ri == null) { - ri = new RelationPattern(RelationDirection.NONE); - relatedClasses.put(dest, ri); - } - ri.addRelation(rt, d); - } - - public RelationPattern getRelation(String dest) { - return relatedClasses.get(dest); - } - - /** Start numbering from zero. */ - public static void reset() { - classNumber = 0; - } - - -} - diff --git a/src/gr/spinellis/umlgraph/doclet/ClassMatcher.java b/src/gr/spinellis/umlgraph/doclet/ClassMatcher.java deleted file mode 100644 index f8b7f92..0000000 --- a/src/gr/spinellis/umlgraph/doclet/ClassMatcher.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.ClassDoc; - -/** - * A ClassMatcher is used to check if a class definition matches a - * specific condition. The nature of the condition is dependent on - * the kind of matcher - * @author wolf - */ -public interface ClassMatcher { - /** - * Returns the options for the specified class. - */ - public boolean matches(ClassDoc cd); - - /** - * Returns the options for the specified class. - */ - public boolean matches(String name); -} diff --git a/src/gr/spinellis/umlgraph/doclet/ContextMatcher.java b/src/gr/spinellis/umlgraph/doclet/ContextMatcher.java deleted file mode 100644 index d0569d2..0000000 --- a/src/gr/spinellis/umlgraph/doclet/ContextMatcher.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.RootDoc; - -/** - * Matches classes that are directly connected to one of the classes matched by - * the regual expression specified. The context center is computed by regex - * lookup. Depending on the specified Options, inferred relations and - * dependencies will be used as well. - *

- * This class needs to perform quite a bit of computations in order to gather - * the network of class releationships, so you are allowed to reuse it should - * you - * @author wolf - * - * @depend - - - DevNullWriter - */ -public class ContextMatcher implements ClassMatcher { - ClassGraphHack cg; - Pattern pattern; - List matched; - Set visited = new HashSet(); - Options opt; - RootDoc root; - boolean keepParentHide; - - /** - * Builds the context matcher - * @param root The root doc returned by JavaDoc - * @param pattern The pattern that will match the "center" of this - * context - * @param opt The options will be used to decide on inference - * @param keepParentHide If true, parent option hide patterns will be - * preserved, so that classes hidden by the options won't - * be shown in the context - * @param fullContext If true, all the classes related to the context - * center will be included, otherwise it will match only - * the classes referred with an outgoing relation from - * the context center - * @throws IOException - */ - public ContextMatcher(RootDoc root, Pattern pattern, Options options, boolean keepParentHide) throws IOException { - this.pattern = pattern; - this.root = root; - this.keepParentHide = keepParentHide; - opt = (Options) options.clone(); - opt.setOption(new String[] { "-!hide" }); - opt.setOption(new String[] { "-!attributes" }); - opt.setOption(new String[] { "-!operations" }); - this.cg = new ClassGraphHack(root, opt); - - setContextCenter(pattern); - } - - /** - * Can be used to setup a different pattern for this context matcher. - *

- * This can be used to speed up subsequent matching with the same global - * options, since the class network informations will be reused. - * @param pattern - */ - public void setContextCenter(Pattern pattern) { - // build up the classgraph printing the relations for all of the - // classes that make up the "center" of this context - this.pattern = pattern; - matched = new ArrayList(); - for (ClassDoc cd : root.classes()) { - if (pattern.matcher(cd.toString()).matches()) { - matched.add(cd); - addToGraph(cd); - } - } - } - - /** - * Adds the specified class to the internal class graph along with its - * relations and depencies, eventually inferring them, according to the - * Options specified for this matcher - * @param cd - */ - private void addToGraph(ClassDoc cd) { - // avoid adding twice the same class, but don't rely on cg.getClassInfo - // since there - // are other ways to add a classInfor than printing the class - if (visited.contains(cd.toString())) - return; - - visited.add(cd.toString()); - cg.printClass(cd, false); - cg.printRelations(cd); - if (opt.inferRelationships) { - cg.printInferredRelations(cd); - } - if (opt.inferDependencies) { - cg.printInferredDependencies(cd); - } - } - - /** - * @see gr.spinellis.umlgraph.doclet.ClassMatcher#matches(com.sun.javadoc.ClassDoc) - */ - public boolean matches(ClassDoc cd) { - if (keepParentHide && opt.matchesHideExpression(cd.toString())) - return false; - - // if the class is matched, it's in by default. - if (matched.contains(cd)) - return true; - - // otherwise, add the class to the graph and see if it's associated - // with any of the matched classes using the classgraph hack - addToGraph(cd); - return matches(cd.toString()); - } - - /** - * @see gr.spinellis.umlgraph.doclet.ClassMatcher#matches(java.lang.String) - */ - public boolean matches(String name) { - if (pattern.matcher(name).matches()) - return true; - - for (ClassDoc mcd : matched) { - String mcName = mcd.toString(); - ClassInfo ciMatched = cg.getClassInfo(mcName); - RelationPattern rp = ciMatched.getRelation(name); - if (ciMatched != null && rp != null && opt.contextRelationPattern.matchesOne(rp)) - return true; - } - return false; - } - - /** - * A quick hack to compute class dependencies reusing ClassGraph but - * without generating output. Will be removed once the ClassGraph class - * will be split into two classes for graph computation and output - * generation. - * @author wolf - * - */ - private static class ClassGraphHack extends ClassGraph { - - public ClassGraphHack(RootDoc root, OptionProvider optionProvider) throws IOException { - super(root, optionProvider, null); - prologue(); - } - - public void prologue() throws IOException { - w = new PrintWriter(new DevNullWriter()); - } - - } - - /** - * Simple dev/null imitation - * @author wolf - */ - private static class DevNullWriter extends Writer { - - public void write(char[] cbuf, int off, int len) throws IOException { - // nothing to do - } - - public void flush() throws IOException { - // nothing to do - } - - public void close() throws IOException { - // nothing to do - } - - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/ContextView.java b/src/gr/spinellis/umlgraph/doclet/ContextView.java deleted file mode 100644 index d1e4d7d..0000000 --- a/src/gr/spinellis/umlgraph/doclet/ContextView.java +++ /dev/null @@ -1,109 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -import java.io.IOException; -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.RootDoc; - -/** - * A view designed for UMLDoc, filters out everything that it's not directly - * connected to the center class of the context. - *

- * As such, can be viewed as a simplified version of a {@linkplain View} using a - * single {@linkplain ContextMatcher}, but provides some extra configuration - * such as context highlighting and output path configuration (and it is - * specified in code rather than in javadoc comments). - * @author wolf - * - */ -public class ContextView implements OptionProvider { - - private ClassDoc cd; - private ContextMatcher matcher; - private Options globalOptions; - private Options myGlobalOptions; - private Options hideOptions; - private Options centerOptions; - private Options packageOptions; - private static final String[] HIDE_OPTIONS = new String[] { "-hide" }; - - public ContextView(String outputFolder, ClassDoc cd, RootDoc root, Options parent) - throws IOException { - this.cd = cd; - String outputPath = cd.containingPackage().name().replace('.', '/') + "/" + cd.name() - + ".dot"; - - // setup options statically, so that we won't need to change them so - // often - this.globalOptions = parent.getGlobalOptions(); - - this.packageOptions = parent.getGlobalOptions(); - this.packageOptions.showQualified = false; - - this.myGlobalOptions = parent.getGlobalOptions(); - this.myGlobalOptions.setOption(new String[] { "-output", outputPath }); - this.myGlobalOptions.setOption(HIDE_OPTIONS); - - this.hideOptions = parent.getGlobalOptions(); - this.hideOptions.setOption(HIDE_OPTIONS); - - this.centerOptions = parent.getGlobalOptions(); - this.centerOptions.nodeFillColor = "lemonChiffon"; - this.centerOptions.showQualified = false; - - this.matcher = new ContextMatcher(root, Pattern.compile(cd.qualifiedName()), - myGlobalOptions, true); - - } - - public void setContextCenter(ClassDoc contextCenter) { - this.cd = contextCenter; - String outputPath = cd.containingPackage().name().replace('.', '/') + "/" + cd.name() - + ".dot"; - this.myGlobalOptions.setOption(new String[] { "-output", outputPath }); - matcher.setContextCenter(Pattern.compile(cd.toString())); - } - - public String getDisplayName() { - return "Context view for class " + cd; - } - - public Options getGlobalOptions() { - return myGlobalOptions; - } - - public Options getOptionsFor(ClassDoc cd) { - if (globalOptions.matchesHideExpression(cd.toString()) || !matcher.matches(cd)) { - return hideOptions; - } else if (cd.equals(this.cd)) { - return centerOptions; - } else if(cd.containingPackage().equals(this.cd.containingPackage())){ - return packageOptions; - } else { - return globalOptions; - } - } - - public Options getOptionsFor(String name) { - if (!matcher.matches(name)) - return hideOptions; - else if (name.equals(cd.name())) - return centerOptions; - else - return globalOptions; - } - - public void overrideForClass(Options opt, ClassDoc cd) { - if (opt.matchesHideExpression(cd.toString()) || !matcher.matches(cd)) - opt.setOption(HIDE_OPTIONS); - if (cd.equals(this.cd)) - opt.nodeFillColor = "lemonChiffon"; - } - - public void overrideForClass(Options opt, String className) { - if (!matcher.matches(className)) - opt.setOption(HIDE_OPTIONS); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/InterfaceMatcher.java b/src/gr/spinellis/umlgraph/doclet/InterfaceMatcher.java deleted file mode 100644 index ad2396e..0000000 --- a/src/gr/spinellis/umlgraph/doclet/InterfaceMatcher.java +++ /dev/null @@ -1,48 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.RootDoc; - -/** - * Matches every class that implements (directly or indirectly) an - * interfaces matched by regular expression provided. - */ -public class InterfaceMatcher implements ClassMatcher { - - protected RootDoc root; - protected Pattern pattern; - - public InterfaceMatcher(RootDoc root, Pattern pattern) { - this.root = root; - this.pattern = pattern; - } - - public boolean matches(ClassDoc cd) { - // if it's the interface we're looking for, match - if(cd.isInterface() && pattern.matcher(cd.toString()).matches()) - return true; - - // for each interface, recurse, since classes and interfaces - // are treated the same in the doclet API - for (ClassDoc iface : cd.interfaces()) { - if(matches(iface)) - return true; - } - - // recurse on supeclass, if available - if(cd.superclass() != null) - return matches(cd.superclass()); - - return false; - } - - public boolean matches(String name) { - ClassDoc cd = root.classNamed(name); - if(cd == null) - return false; - return matches(cd); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/OptionProvider.java b/src/gr/spinellis/umlgraph/doclet/OptionProvider.java deleted file mode 100644 index 99ce9c3..0000000 --- a/src/gr/spinellis/umlgraph/doclet/OptionProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Contibuted by Andrea Aime - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.ClassDoc; - -/** - * A factory class that builds Options object for general use or for a - * specific class - */ -public interface OptionProvider { - /** - * Returns the options for the specified class. - */ - public Options getOptionsFor(ClassDoc cd); - - /** - * Returns the options for the specified class. - */ - public Options getOptionsFor(String name); - - /** - * Returns the global options (the class independent definition) - */ - public Options getGlobalOptions(); - - /** - * Gets a base Options and applies the overrides for the specified class - */ - public void overrideForClass(Options opt, ClassDoc cd); - - /** - * Gets a base Options and applies the overrides for the specified class - */ - public void overrideForClass(Options opt, String className); - - /** - * Returns user displayable name for this option provider. - *

Will be used to provide progress feedback on the console - */ - public String getDisplayName(); -} diff --git a/src/gr/spinellis/umlgraph/doclet/Options.java b/src/gr/spinellis/umlgraph/doclet/Options.java deleted file mode 100644 index 6730e3f..0000000 --- a/src/gr/spinellis/umlgraph/doclet/Options.java +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.Tag; - -/** - * Represent the program options - * @version $Revision$ - * @author Diomidis Spinellis - */ -public class Options implements Cloneable, OptionProvider { - // dot's font platform dependence workaround - private static String defaultFont; - private static String defaultItalicFont; - // reused often, especially in UmlGraphDoc, worth creating just once and reusing - private static final Pattern allPattern = Pattern.compile(".*"); - protected static final String DEFAULT_EXTERNAL_APIDOC = "http://java.sun.com/j2se/1.4.2/docs/api/"; - - static { - // use an appropriate font depending on the current operating system - // (on windows graphviz is unable to locate "Helvetica-Oblique" - if(System.getProperty("os.name").toLowerCase().contains("windows")) { - defaultFont = "arial"; - defaultItalicFont = "ariali"; - } else { - defaultFont = "Helvetica"; - defaultItalicFont = "Helvetica-Oblique"; - } - } - - // instance fields - Vector hidePatterns; - boolean showQualified; - boolean showAttributes; - boolean showEnumerations; - boolean showEnumConstants; - boolean showOperations; - boolean showConstructors; - boolean showVisibility; - boolean horizontal; - boolean showType; - String edgeFontName; - String edgeFontColor; - String edgeColor; - double edgeFontSize; - String nodeFontName; - String nodeFontAbstractName; - String nodeFontColor; - double nodeFontSize; - String nodeFillColor; - double nodeFontClassSize; - String nodeFontClassName; - String nodeFontClassAbstractName; - double nodeFontTagSize; - String nodeFontTagName; - double nodeFontPackageSize; - String nodeFontPackageName; - String bgColor; - public String outputFileName; - String outputEncoding; - Map apiDocMap; - String apiDocRoot; - boolean postfixPackage; - boolean useGuillemot; - boolean findViews; - String viewName; - public String outputDirectory; - /** Guillemot left (open) */ - String guilOpen = "«"; // "\u00ab"; - /** Guillemot right (close) */ - String guilClose = "»"; // "\u00bb"; - boolean inferRelationships; - boolean inferDependencies; - RelationPattern contextRelationPattern; - boolean useImports; - Visibility inferDependencyVisibility; - boolean inferDepInPackage; - RelationType inferRelationshipType; - private Vector collPackages; - boolean compact; - // internal option, used by UMLDoc to generate relative links between classes - boolean relativeLinksForSourcePackages; - // internal option, used by UMLDoc to force strict matching on the class names - // and avoid problems with packages in the template declaration making UmlGraph hide - // classes outside of them (for example, class gr.spinellis.Foo - // would have been hidden by the hide pattern "java.*" - // TODO: consider making this standard behaviour - boolean strictMatching; - - Options() { - showQualified = false; - showAttributes = false; - showEnumConstants = false; - showOperations = false; - showVisibility = false; - showEnumerations = false; - showConstructors = false; - showType = false; - edgeFontName = defaultFont; - edgeFontColor = "black"; - edgeColor = "black"; - edgeFontSize = 10; - nodeFontColor = "black"; - nodeFontName = defaultFont; - nodeFontAbstractName = defaultItalicFont; - nodeFontSize = 10; - nodeFontClassSize = -1; - nodeFontClassName = null; - nodeFontClassAbstractName = null; - nodeFontTagSize = -1; - nodeFontTagName = null; - nodeFontPackageSize = -1; - nodeFontPackageName = null; - nodeFillColor = null; - bgColor = null; - outputFileName = "graph.dot"; - outputDirectory= null; - outputEncoding = "ISO-8859-1"; - hidePatterns = new Vector(); - apiDocMap = new HashMap(); - apiDocRoot = null; - postfixPackage = false; - useGuillemot = true; - findViews = false; - viewName = null; - contextRelationPattern = new RelationPattern(RelationDirection.BOTH); - inferRelationships = false; - inferDependencies = false; - inferDependencyVisibility = Visibility.PRIVATE; - inferDepInPackage = false; - useImports = false; - inferRelationshipType = RelationType.NAVASSOC; - collPackages = new Vector(); - compact = false; - relativeLinksForSourcePackages = false; - } - - public Object clone() { - Options clone = null; - try { - clone = (Options) super.clone(); - } catch (CloneNotSupportedException e) { - // Should not happen - } - // deep clone the hide and collection patterns - clone.hidePatterns = new Vector(hidePatterns); - clone.collPackages= new Vector(collPackages); - clone.apiDocMap = new HashMap(apiDocMap); - return clone; - } - - /** Most complete output */ - public void setAll() { - showAttributes = true; - showEnumerations = true; - showEnumConstants = true; - showOperations = true; - showConstructors = true; - showVisibility = true; - showType = true; - } - - /** - * Return the number of arguments associated with the specified option. - * The return value includes the actual option. - * Will return 0 if the option is not supported. - */ - public static int optionLength(String option) { - if(option.equals("-qualify") || - option.equals("-horizontal") || - option.equals("-attributes") || - option.equals("-operations") || - option.equals("-constructors") || - option.equals("-visibility") || - option.equals("-types") || - option.equals("-all") || - option.equals("-postfixpackage") || - option.equals("-noguillemot") || - option.equals("-enumconstants") || - option.equals("-enumerations") || - option.equals("-views") || - option.equals("-inferrel") || - option.equals("-useimports") || - option.equals("-inferdep") || - option.equals("-inferdepinpackage") || - option.equals("-compact")) - - return 1; - else if(option.equals("-nodefillcolor") || - option.equals("-nodefontcolor") || - option.equals("-nodefontsize") || - option.equals("-nodefontname") || - option.equals("-nodefontabstractname") || - option.equals("-nodefontclasssize") || - option.equals("-nodefontclassname") || - option.equals("-nodefontclassabstractname") || - option.equals("-nodefonttagsize") || - option.equals("-nodefonttagname") || - option.equals("-nodefontpackagesize") || - option.equals("-nodefontpackagename") || - option.equals("-edgefontcolor") || - option.equals("-edgecolor") || - option.equals("-edgefontsize") || - option.equals("-edgefontname") || - option.equals("-output") || - option.equals("-outputencoding") || - option.equals("-bgcolor") || - option.equals("-hide") || - option.equals("-apidocroot") || - option.equals("-apidocmap") || - option.equals("-d") || - option.equals("-view") || - option.equals("-inferreltype") || - option.equals("-inferdepvis") || - option.equals("-collpackages") || - option.equals("-link")) - return 2; - else if(option.equals("-contextPattern")) - return 3; - else - return 0; - } - - /** Set the options based on a single option and its arguments */ - void setOption(String[] opt) { - if(!opt[0].equals("-hide") && optionLength(opt[0]) > opt.length) { - System.err.println("Skipping option '" + opt[0] + "', missing argument"); - return; - } - - if(opt[0].equals("-qualify")) { - showQualified = true; - } else if (opt[0].equals("-!qualify")) { - showQualified = false; - } else if(opt[0].equals("-horizontal")) { - horizontal = true; - } else if (opt[0].equals("-!horizontal")) { - horizontal = false; - } else if(opt[0].equals("-attributes")) { - showAttributes = true; - } else if (opt[0].equals("-!attributes")) { - showAttributes = false; - } else if(opt[0].equals("-enumconstants")) { - showEnumConstants = true; - } else if (opt[0].equals("-!enumconstants")) { - showEnumConstants = false; - } else if(opt[0].equals("-operations")) { - showOperations = true; - } else if (opt[0].equals("-!operations")) { - showOperations = false; - } else if(opt[0].equals("-enumerations")) { - showEnumerations = true; - } else if (opt[0].equals("-!enumerations")) { - showEnumerations = false; - } else if(opt[0].equals("-constructors")) { - showConstructors = true; - } else if (opt[0].equals("-!constructors")) { - showConstructors = false; - } else if(opt[0].equals("-visibility")) { - showVisibility = true; - } else if (opt[0].equals("-!visibility")) { - showVisibility = false; - } else if(opt[0].equals("-types")) { - showType = true; - } else if (opt[0].equals("-!types")) { - showType = false; - } else if(opt[0].equals("-all")) { - setAll(); - } else if(opt[0].equals("-bgcolor")) { - bgColor = opt[1]; - } else if (opt[0].equals("-!bgcolor")) { - bgColor = null; - } else if(opt[0].equals("-edgecolor")) { - edgeColor = opt[1]; - } else if (opt[0].equals("-!edgecolor")) { - edgeColor = "black"; - } else if(opt[0].equals("-edgefontcolor")) { - edgeFontColor = opt[1]; - } else if (opt[0].equals("-!edgefontcolor")) { - edgeFontColor = "black"; - } else if(opt[0].equals("-edgefontname")) { - edgeFontName = opt[1]; - } else if (opt[0].equals("-!edgefontname")) { - edgeFontName = defaultFont; - } else if(opt[0].equals("-edgefontsize")) { - edgeFontSize = Integer.parseInt(opt[1]); - } else if (opt[0].equals("-!edgefontsize")) { - edgeFontSize = 10; - } else if(opt[0].equals("-nodefontcolor")) { - nodeFontColor = opt[1]; - } else if (opt[0].equals("-!nodefontcolor")) { - nodeFontColor = "black"; - } else if(opt[0].equals("-nodefontname")) { - nodeFontName = opt[1]; - } else if (opt[0].equals("-!nodefontname")) { - nodeFontName = defaultFont; - } else if(opt[0].equals("-nodefontabstractname")) { - nodeFontAbstractName = opt[1]; - } else if (opt[0].equals("-!nodefontabstractname")) { - nodeFontAbstractName = defaultItalicFont; - } else if(opt[0].equals("-nodefontsize")) { - nodeFontSize = Integer.parseInt(opt[1]); - } else if (opt[0].equals("-!nodefontsize")) { - nodeFontSize = 10; - } else if(opt[0].equals("-nodefontclassname")) { - nodeFontClassName = opt[1]; - } else if (opt[0].equals("-!nodefontclassname")) { - nodeFontClassName = null; - } else if(opt[0].equals("-nodefontclassabstractname")) { - nodeFontClassAbstractName = opt[1]; - } else if (opt[0].equals("-!nodefontclassabstractname")) { - nodeFontClassAbstractName = null; - } else if(opt[0].equals("-nodefontclasssize")) { - nodeFontClassSize = Integer.parseInt(opt[1]); - } else if (opt[0].equals("-!nodefontclasssize")) { - nodeFontClassSize = -1; - } else if(opt[0].equals("-nodefonttagname")) { - nodeFontTagName = opt[1]; - } else if (opt[0].equals("-!nodefonttagname")) { - nodeFontTagName = null; - } else if(opt[0].equals("-nodefonttagsize")) { - nodeFontTagSize = Integer.parseInt(opt[1]); - } else if (opt[0].equals("-!nodefonttagsize")) { - nodeFontTagSize = -1; - } else if(opt[0].equals("-nodefontpackagename")) { - nodeFontPackageName = opt[1]; - } else if (opt[0].equals("-!nodefontpackagename")) { - nodeFontPackageName = null; - } else if(opt[0].equals("-nodefontpackagesize")) { - nodeFontPackageSize = Integer.parseInt(opt[1]); - } else if (opt[0].equals("-!nodefontpackagesize")) { - nodeFontPackageSize = -1; - } else if(opt[0].equals("-nodefillcolor")) { - nodeFillColor = opt[1]; - } else if (opt[0].equals("-!nodefillcolor")) { - nodeFillColor = null; - } else if(opt[0].equals("-output")) { - outputFileName = opt[1]; - } else if (opt[0].equals("-!output")) { - outputFileName = "graph.dot"; - } else if(opt[0].equals("-outputencoding")) { - outputEncoding = opt[1]; - } else if (opt[0].equals("-!outputencoding")) { - outputEncoding = "ISO-8859-1"; - } else if(opt[0].equals("-hide")) { - if(opt.length == 1) { - hidePatterns.clear(); - hidePatterns.add(allPattern); - } else { - try { - hidePatterns.add(Pattern.compile(opt[1])); - } catch (PatternSyntaxException e) { - System.err.println("Skipping invalid pattern " + opt[1]); - } - } - } else if (opt[0].equals("-!hide")) { - hidePatterns.clear(); - } else if(opt[0].equals("-apidocroot")) { - apiDocRoot = fixApiDocRoot(opt[1]); - } else if (opt[0].equals("-!apidocroot")) { - apiDocRoot = null; - } else if(opt[0].equals("-apidocmap")) { - setApiDocMapFile(opt[1]); - } else if (opt[0].equals("-!apidocmap")) { - apiDocMap.clear(); - } else if(opt[0].equals("-noguillemot")) { - guilOpen = "<<"; - guilClose = ">>"; - } else if (opt[0].equals("-!noguillemot")) { - guilOpen = "\u00ab"; - guilClose = "\u00bb"; - } else if (opt[0].equals("-view")) { - viewName = opt[1]; - } else if (opt[0].equals("-!view")) { - viewName = null; - } else if (opt[0].equals("-views")) { - findViews = true; - } else if (opt[0].equals("-!views")) { - findViews = false; - } else if (opt[0].equals("-d")) { - outputDirectory = opt[1]; - } else if (opt[0].equals("-!d")) { - outputDirectory = null; - } else if(opt[0].equals("-inferrel")) { - inferRelationships = true; - } else if(opt[0].equals("-!inferrel")) { - inferRelationships = false; - } else if(opt[0].equals("-inferreltype")) { - try { - inferRelationshipType = RelationType.valueOf(opt[1].toUpperCase()); - } catch(IllegalArgumentException e) { - System.err.println("Unknown association type " + opt[1]); - } - } else if(opt[0].equals("-!inferreltype")) { - inferRelationshipType = RelationType.NAVASSOC; - } else if(opt[0].equals("-inferdepvis")) { - try { - Visibility vis = Visibility.valueOf(opt[1].toUpperCase()); - inferDependencyVisibility = vis; - } catch(IllegalArgumentException e) { - System.err.println("Ignoring invalid visibility specification for " + - "dependency inference: " + opt[1]); - } - } else if(opt[0].equals("-!inferdepvis")) { - inferDependencyVisibility = Visibility.PRIVATE; - } else if(opt[0].equals("-inferdep")) { - inferDependencies = true; - } else if(opt[0].equals("-!inferdep")) { - inferDependencies = false; - } else if(opt[0].equals("-inferdepinpackage")) { - inferDepInPackage = true; - } else if(opt[0].equals("-!inferdepinpackage")) { - inferDepInPackage = false; - } else if(opt[0].equals("-useimports")) { - useImports = true; - } else if(opt[0].equals("-!useimports")) { - useImports = false; - } else if (opt[0].equals("-collpackages")) { - try { - collPackages.add(Pattern.compile(opt[1])); - } catch (PatternSyntaxException e) { - System.err.println("Skipping invalid pattern " + opt[1]); - } - } else if (opt[0].equals("-!collpackages")) { - collPackages.clear(); - } else if (opt[0].equals("-compact")) { - compact = true; - } else if (opt[0].equals("-!compact")) { - compact = false; - } else if (opt[0].equals("-postfixpackage")) { - postfixPackage = true; - } else if (opt[0].equals("-!postfixpackage")) { - postfixPackage = false; - } else if (opt[0].equals("-link")) { - addApiDocRoots(opt[1]); - } else if(opt[0].equals("-contextPattern")) { - RelationDirection d; RelationType rt; - try { - d = RelationDirection.valueOf(opt[2].toUpperCase()); - if(opt[1].equalsIgnoreCase("all")) { - contextRelationPattern = new RelationPattern(d); - } else { - rt = RelationType.valueOf(opt[1].toUpperCase()); - contextRelationPattern.addRelation(rt, d); - } - } catch(IllegalArgumentException e) { - - } - - } else - ; // Do nothing, javadoc will handle the option or complain, if - // needed. - } - - /** - * Adds api doc roots from a link. The folder reffered by the link should contain a package-list - * file that will be parsed in order to add api doc roots to this configuration - * @param packageListUrl - */ - private void addApiDocRoots(String packageListUrl) { - BufferedReader br = null; - packageListUrl = fixApiDocRoot(packageListUrl); - try { - URL url = new URL(packageListUrl + "/package-list"); - br = new BufferedReader(new InputStreamReader(url.openStream())); - String line = null; - while((line = br.readLine()) != null) { - line = line + "."; - Pattern pattern = Pattern.compile(line.replace(".", "\\.") + "[^\\.]*"); - apiDocMap.put(pattern, packageListUrl); - } - } catch(IOException e) { - System.err.println("Errors happened while accessing the package-list file at " - + packageListUrl); - } finally { - if(br != null) - try { - br.close(); - } catch (IOException e) {} - } - - } - - /** - * Loads the property file referred by apiDocMapFileName and fills the apiDocMap - * accordingly - * @param apiDocMapFileName - */ - void setApiDocMapFile(String apiDocMapFileName) { - try { - InputStream is = new FileInputStream(apiDocMapFileName); - Properties userMap = new Properties(); - userMap.load(is); - for (Map.Entry mapEntry : userMap.entrySet()) { - try { - Pattern regex = Pattern.compile((String) mapEntry.getKey()); - String thisRoot = (String) mapEntry.getValue(); - if (thisRoot != null) { - thisRoot = fixApiDocRoot(thisRoot); - apiDocMap.put(regex, thisRoot); - } else { - System.err.println("No URL for pattern " + mapEntry.getKey()); - } - } catch (PatternSyntaxException e) { - System.err.println("Skipping bad pattern " + mapEntry.getKey()); - } - } - } catch (FileNotFoundException e) { - System.err.println("File " + apiDocMapFileName + " was not found: " + e); - } catch (IOException e) { - System.err.println("Error reading the property api map file " + apiDocMapFileName - + ": " + e); - } - } - - /** - * Returns the appropriate URL "root" for an external class name. It will - * match the class name against the regular expressions specified in the - * apiDocMap; if a match is found, the associated URL - * will be returned. - * - * NOTE: The match order of the match attempts is the one specified by the - * constructor of the api doc root, so it depends on the order of "-link" and "-apiDocMap" - * parameters. - */ - public String getApiDocRoot(String className) { - if(apiDocMap.isEmpty()) - apiDocMap.put(Pattern.compile(".*"), DEFAULT_EXTERNAL_APIDOC); - - for (Map.Entry mapEntry : apiDocMap.entrySet()) { - Pattern regex = mapEntry.getKey(); - Matcher matcher = regex.matcher(className); - if (matcher.matches()) - return mapEntry.getValue(); - } - return null; - } - - /** Trim and append a file separator to the string */ - private String fixApiDocRoot(String str) { - String fixed = null; - if (str != null) { - fixed = str.trim(); - if (fixed.length() > 0) { - if (!File.separator.equals("/")) - fixed = fixed.replace(File.separator.charAt(0), '/'); - if (!fixed.endsWith("/")) - fixed = fixed + "/"; - } - } - return fixed; - } - - /** Set the options based on the command line parameters */ - public void setOptions(String[][] options) { - for (String s[] : options) - setOption(s); - } - - - /** Set the options based on the tag elements of the ClassDoc parameter */ - public void setOptions(ClassDoc p) { - if (p == null) - return; - - for (Tag tag : p.tags("opt")) { - String[] opt = StringUtil.tokenize(tag.text()); - opt[0] = "-" + opt[0]; - setOption(opt); - } - } - - /** - * Check if the supplied string matches an entity specified - * with the -hide parameter. - * @return true if the string matches. - */ - public boolean matchesHideExpression(String s) { - for (Pattern hidePattern : hidePatterns) { - // micro-optimization because the "all pattern" is heavily used in UmlGraphDoc - if(hidePattern == allPattern) - return true; - - Matcher m = hidePattern.matcher(s); - if (strictMatching) { - if (m.matches()) { - return true; - } - } else if (m.find()) { - return true; - } - } - return false; - } - - /** - * Check if the supplied string matches an entity specified - * with the -hide parameter. - * @return true if the string matches. - */ - public boolean matchesCollPackageExpression(String s) { - for (Pattern collPattern : collPackages) { - Matcher m = collPattern.matcher(s); - if (strictMatching) { - if (m.matches()) { - return true; - } - } else if (m.find()) { - return true; - } - } - return false; - } - - // ---------------------------------------------------------------- - // OptionProvider methods - // ---------------------------------------------------------------- - - public Options getOptionsFor(ClassDoc cd) { - Options localOpt = getGlobalOptions(); - localOpt.setOptions(cd); - return localOpt; - } - - public Options getOptionsFor(String name) { - return getGlobalOptions(); - } - - public Options getGlobalOptions() { - return (Options) clone(); - } - - public void overrideForClass(Options opt, ClassDoc cd) { - // nothing to do - } - - public void overrideForClass(Options opt, String className) { - // nothing to do - } - - public String getDisplayName() { - return "general class diagram"; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("UMLGRAPH OPTIONS\n"); - for(Field f : this.getClass().getDeclaredFields()) { - if(!Modifier.isStatic(f.getModifiers())) { - f.setAccessible(true); - try { - sb.append(f.getName() + ":" + f.get(this) + "\n"); - } catch (Exception e) { - } - } - } - return sb.toString(); - } - -} - diff --git a/src/gr/spinellis/umlgraph/doclet/PackageMatcher.java b/src/gr/spinellis/umlgraph/doclet/PackageMatcher.java deleted file mode 100644 index ae8da2e..0000000 --- a/src/gr/spinellis/umlgraph/doclet/PackageMatcher.java +++ /dev/null @@ -1,26 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.PackageDoc; - -public class PackageMatcher implements ClassMatcher { - protected PackageDoc packageDoc; - - public PackageMatcher(PackageDoc packageDoc) { - super(); - this.packageDoc = packageDoc; - } - - public boolean matches(ClassDoc cd) { - return cd.containingPackage().equals(packageDoc); - } - - public boolean matches(String name) { - for (ClassDoc cd : packageDoc.allClasses()) { - if (cd.qualifiedName().equals(name)) - return true; - } - return false; - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/PackageView.java b/src/gr/spinellis/umlgraph/doclet/PackageView.java deleted file mode 100644 index f9e8f68..0000000 --- a/src/gr/spinellis/umlgraph/doclet/PackageView.java +++ /dev/null @@ -1,69 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.PackageDoc; -import com.sun.javadoc.RootDoc; - -/** - * A view designed for UMLDoc, filters out everything that it's not contained in - * the specified package. - *

- * As such, can be viewed as a simplified version of a {@linkplain View} using a - * single {@linkplain ClassMatcher}, and provides some extra configuration such - * as output path configuration (and it is specified in code rather than in - * javadoc comments). - * @author wolf - * - */ -public class PackageView implements OptionProvider { - - private PackageDoc pd; - private OptionProvider parent; - private ClassMatcher matcher; - private String outputPath; - - public PackageView(String outputFolder, PackageDoc pd, RootDoc root, OptionProvider parent) { - this.parent = parent; - this.pd = pd; - this.matcher = new PackageMatcher(pd); - this.outputPath = pd.name().replace('.', '/') + "/" + pd.name() + ".dot"; - } - - public String getDisplayName() { - return "Package view for package " + pd; - } - - public Options getGlobalOptions() { - Options go = parent.getGlobalOptions(); - - go.setOption(new String[] { "-output", outputPath }); - go.setOption(new String[] { "-hide" }); - - return go; - } - - public Options getOptionsFor(ClassDoc cd) { - Options go = parent.getGlobalOptions(); - overrideForClass(go, cd); - return go; - } - - public Options getOptionsFor(String name) { - Options go = parent.getGlobalOptions(); - overrideForClass(go, name); - return go; - } - - public void overrideForClass(Options opt, ClassDoc cd) { - opt.showQualified = false; - if (!matcher.matches(cd) || parent.getGlobalOptions().matchesHideExpression(cd.name())) - opt.setOption(new String[] { "-hide" }); - } - - public void overrideForClass(Options opt, String className) { - opt.showQualified = false; - if (!matcher.matches(className)) - opt.setOption(new String[] { "-hide" }); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/PatternMatcher.java b/src/gr/spinellis/umlgraph/doclet/PatternMatcher.java deleted file mode 100644 index 5e86a5b..0000000 --- a/src/gr/spinellis/umlgraph/doclet/PatternMatcher.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ -package gr.spinellis.umlgraph.doclet; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; - -/** - * Matches classes performing a regular expression match on the qualified class - * name - * @author wolf - */ -public class PatternMatcher implements ClassMatcher { - Pattern pattern; - - public PatternMatcher(Pattern pattern) { - this.pattern = pattern; - } - - public boolean matches(ClassDoc cd) { - return matches(cd.toString()); - } - - public boolean matches(String name) { - Matcher matcher = pattern.matcher(name); - return matcher.matches(); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/RelationDirection.java b/src/gr/spinellis/umlgraph/doclet/RelationDirection.java deleted file mode 100644 index 5cd86a1..0000000 --- a/src/gr/spinellis/umlgraph/doclet/RelationDirection.java +++ /dev/null @@ -1,51 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -/** - * The possibile directions of a relation given a reference class (used in - * context diagrams) - */ -public enum RelationDirection { - NONE, IN, OUT, BOTH; - - /** - * Adds the current direction - * @param d - * @return - */ - public RelationDirection sum(RelationDirection d) { - if (this == NONE) - return d; - - if ((this == IN && d == OUT) || (this == OUT && d == IN) || this == BOTH || d == BOTH) - return BOTH; - return this; - } - - /** - * Returns true if this direction "contains" the specified one, that is, - * either it's equal to it, or this direction is {@link #BOTH} - * @param d - * @return - */ - public boolean contains(RelationDirection d) { - if (this == BOTH) - return true; - else - return d == this; - } - - /** - * Inverts the direction of the relation. Turns IN into OUT and vice-versa, NONE and BOTH - * are not changed - * @return - */ - public RelationDirection inverse() { - if (this == IN) - return OUT; - else if (this == OUT) - return IN; - else - return this; - } - -}; diff --git a/src/gr/spinellis/umlgraph/doclet/RelationPattern.java b/src/gr/spinellis/umlgraph/doclet/RelationPattern.java deleted file mode 100644 index 62afa49..0000000 --- a/src/gr/spinellis/umlgraph/doclet/RelationPattern.java +++ /dev/null @@ -1,50 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -/** - * A map from relation types to directions - * @author wolf - * - */ -public class RelationPattern { - /** - * A map from RelationType (indexes) to Direction objects - */ - RelationDirection[] directions; - - /** - * Creates a new pattern using the same direction for every relation kind - * @param defaultDirection The direction used to initialize this pattern - */ - public RelationPattern(RelationDirection defaultDirection) { - directions = new RelationDirection[RelationType.values().length]; - for (int i = 0; i < directions.length; i++) { - directions[i] = defaultDirection; - } - } - - /** - * Adds, eventually merging, a direction for the specified relation type - * @param relationType - * @param direction - */ - public void addRelation(RelationType relationType, RelationDirection direction) { - int idx = relationType.ordinal(); - directions[idx] = directions[idx].sum(direction); - } - - /** - * Returns true if this patterns matches at least the direction of one - * of the relations in the other relation patterns. Matching is defined - * by {@linkplain RelationDirection#contains(RelationDirection)} - * @param relationPattern - * @return - */ - public boolean matchesOne(RelationPattern relationPattern) { - for (int i = 0; i < directions.length; i++) { - if (directions[i].contains(relationPattern.directions[i])) - return true; - } - return false; - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/RelationType.java b/src/gr/spinellis/umlgraph/doclet/RelationType.java deleted file mode 100644 index 23577ba..0000000 --- a/src/gr/spinellis/umlgraph/doclet/RelationType.java +++ /dev/null @@ -1,10 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -/** - * The type of relation that links two entities - * @author wolf - * - */ -public enum RelationType { - ASSOC, NAVASSOC, HAS, COMPOSED, DEPEND, EXTENDS, IMPLEMENTS; -} diff --git a/src/gr/spinellis/umlgraph/doclet/StringUtil.java b/src/gr/spinellis/umlgraph/doclet/StringUtil.java deleted file mode 100644 index aa44f24..0000000 --- a/src/gr/spinellis/umlgraph/doclet/StringUtil.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import java.util.*; - -/** - * String utility functions - * @version $Revision$ - * @author Diomidis Spinellis - */ -class StringUtil { - /** Tokenize string s into an array */ - public static String[] tokenize(String s) { - ArrayList r = new ArrayList(); - String remain = s; - int n = 0, pos; - - remain = remain.trim(); - while (remain.length() > 0) { - if (remain.startsWith("\"")) { - // Field in quotes - pos = remain.indexOf('"', 1); - if (pos == -1) - break; - r.add(remain.substring(1, pos)); - if (pos + 1 < remain.length()) - pos++; - } else { - // Space-separated field - pos = remain.indexOf(' ', 0); - if (pos == -1) { - r.add(remain); - remain = ""; - } else - r.add(remain.substring(0, pos)); - } - remain = remain.substring(pos + 1); - remain = remain.trim(); - // - is used as a placeholder for empy fields - if (r.get(n).equals("-")) - r.set(n, ""); - n++; - } - return r.toArray(new String[0]); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/SubclassMatcher.java b/src/gr/spinellis/umlgraph/doclet/SubclassMatcher.java deleted file mode 100644 index 04965a1..0000000 --- a/src/gr/spinellis/umlgraph/doclet/SubclassMatcher.java +++ /dev/null @@ -1,41 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.RootDoc; - -/** - * Matches every class that extends (directly or indirectly) a class - * matched by the regular expression provided. - */ -public class SubclassMatcher implements ClassMatcher { - - protected RootDoc root; - protected Pattern pattern; - - public SubclassMatcher(RootDoc root, Pattern pattern) { - this.root = root; - this.pattern = pattern; - } - - public boolean matches(ClassDoc cd) { - // if it's the class we're looking for return - if(pattern.matcher(cd.toString()).matches()) - return true; - - // recurse on supeclass, if available - if(cd.superclass() != null) - return matches(cd.superclass()); - - return false; - } - - public boolean matches(String name) { - ClassDoc cd = root.classNamed(name); - if(cd == null) - return false; - return matches(cd); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/UMLOptions.java b/src/gr/spinellis/umlgraph/doclet/UMLOptions.java deleted file mode 100644 index 4edfdef..0000000 --- a/src/gr/spinellis/umlgraph/doclet/UMLOptions.java +++ /dev/null @@ -1,9 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -/** - * Options for UMLGraph class diagram generation - * @opt operations - * @opt visibility - * @hidden - */ -public class UMLOptions {} \ No newline at end of file diff --git a/src/gr/spinellis/umlgraph/doclet/UmlGraph.java b/src/gr/spinellis/umlgraph/doclet/UmlGraph.java deleted file mode 100644 index bd37565..0000000 --- a/src/gr/spinellis/umlgraph/doclet/UmlGraph.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.Doc; -import com.sun.javadoc.LanguageVersion; -import com.sun.javadoc.RootDoc; - -/** - * Doclet API implementation - * @depend - - - OptionProvider - * @depend - - - Options - * @depend - - - View - * @depend - - - ClassGraph - * @depend - - - Version - * - * @version $Revision$ - * @author Diomidis Spinellis - */ -public class UmlGraph { - - private static final String programName = "UmlGraph"; - private static final String docletName = "gr.spinellis.umlgraph.doclet.UmlGraph"; - - /** Entry point through javadoc */ - public static boolean start(RootDoc root) throws IOException { - Options opt = buildOptions(root); - root.printNotice("UMLGraph doclet version " + Version.VERSION + " started"); - - View[] views = buildViews(opt, root, root); - if(views == null) - return false; - if (views.length == 0) - buildGraph(root, opt, null); - else - for (int i = 0; i < views.length; i++) - buildGraph(root, views[i], null); - return true; - } - - public static void main(String args[]) { - PrintWriter err = new PrintWriter(System.err); - com.sun.tools.javadoc.Main.execute(programName, - err, err, err, docletName, args); - } - - /** - * Creates the base Options object, that contains both the options specified on the command - * line and the ones specified in the UMLOptions class, if available. - */ - public static Options buildOptions(RootDoc root) { - Options opt = new Options(); - opt.setOptions(root.options()); - opt.setOptions(findUMLOptions(root)); - return opt; - } - - private static ClassDoc findUMLOptions(RootDoc root) { - ClassDoc[] classes = root.classes(); - for (ClassDoc cd : classes) - if(cd.name().equals("UMLOptions")) - return cd; - return null; - } - - /** - * Builds and outputs a single graph according to the view overrides - */ - public static void buildGraph(RootDoc root, OptionProvider op, Doc contextDoc) throws IOException { - Options opt = op.getGlobalOptions(); - root.printNotice("Building " + op.getDisplayName()); - ClassDoc[] classes = root.classes(); - - ClassGraph c = new ClassGraph(root, op, contextDoc); - c.prologue(); - for (int i = 0; i < classes.length; i++) - c.printClass(classes[i], true); - for (int i = 0; i < classes.length; i++) - c.printRelations(classes[i]); - if(opt.inferRelationships) - c.printInferredRelations(classes); - if(opt.inferDependencies) - c.printInferredDependencies(classes); - - c.printExtraClasses(root); - c.epilogue(); - } - - /** - * Builds the views according to the parameters on the command line - * @param opt The options - * @param srcRootDoc The RootDoc for the source classes - * @param viewRootDoc The RootDoc for the view classes (may be - * different, or may be the same as the srcRootDoc) - */ - public static View[] buildViews(Options opt, RootDoc srcRootDoc, RootDoc viewRootDoc) { - if (opt.viewName != null) { - ClassDoc viewClass = viewRootDoc.classNamed(opt.viewName); - if(viewClass == null) { - System.out.println("View " + opt.viewName + " not found! Exiting without generating any output."); - return null; - } - if(viewClass.tags("view").length == 0) { - System.out.println(viewClass + " is not a view!"); - return null; - } - if(viewClass.isAbstract()) { - System.out.println(viewClass + " is an abstract view, no output will be generated!"); - return null; - } - return new View[] { buildView(srcRootDoc, viewClass, opt) }; - } else if (opt.findViews) { - List views = new ArrayList(); - ClassDoc[] classes = viewRootDoc.classes(); - - // find view classes - for (int i = 0; i < classes.length; i++) - if (classes[i].tags("view").length > 0 && !classes[i].isAbstract()) - views.add(buildView(srcRootDoc, classes[i], opt)); - - return views.toArray(new View[views.size()]); - } else - return new View[0]; - } - - /** - * Builds a view along with its parent views, recursively - */ - private static View buildView(RootDoc root, ClassDoc viewClass, OptionProvider provider) { - ClassDoc superClass = viewClass.superclass(); - if(superClass == null || superClass.tags("view").length == 0) - return new View(root, viewClass, provider); - - return new View(root, viewClass, buildView(root, superClass, provider)); - } - - /** Option checking */ - public static int optionLength(String option) { - return Options.optionLength(option); - } - - /** Indicate the language version we support */ - public static LanguageVersion languageVersion() { - return LanguageVersion.JAVA_1_5; - } -} diff --git a/src/gr/spinellis/umlgraph/doclet/UmlGraphDoc.java b/src/gr/spinellis/umlgraph/doclet/UmlGraphDoc.java deleted file mode 100644 index 7a5669f..0000000 --- a/src/gr/spinellis/umlgraph/doclet/UmlGraphDoc.java +++ /dev/null @@ -1,242 +0,0 @@ -package gr.spinellis.umlgraph.doclet; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Pattern; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.LanguageVersion; -import com.sun.javadoc.PackageDoc; -import com.sun.javadoc.RootDoc; -import com.sun.tools.doclets.standard.Standard; - -/** - * Chaining doclet that runs the standart Javadoc doclet first, and on success, - * runs the generation of dot files by UMLGraph - * @author wolf - * - * @depend - - - WrappedClassDoc - * @depend - - - WrappedRootDoc - */ -public class UmlGraphDoc { - /** - * Option check, forwards options to the standard doclet, if that one refuses them, - * they are sent to UmlGraph - */ - public static int optionLength(String option) { - int result = Standard.optionLength(option); - if (result != 0) - return result; - else - return UmlGraph.optionLength(option); - } - - /** - * Standard doclet entry point - * @param root - * @return - */ - public static boolean start(RootDoc root) { - root.printNotice("UmlGraphDoc version " + Version.VERSION + ", running the standard doclet"); - Standard.start(root); - root.printNotice("UmlGraphDoc version " + Version.VERSION + ", altering javadocs"); - try { - String outputFolder = findOutputPath(root.options()); - - Options opt = new Options(); - opt.setOptions(root.options()); - // in javadoc enumerations are always printed - opt.showEnumerations = true; - opt.relativeLinksForSourcePackages = true; - // enable strict matching for hide expressions - opt.strictMatching = true; -// root.printNotice(opt.toString()); - - root = new WrappedRootDoc(root); - generatePackageDiagrams(root, opt, outputFolder); - generateContextDiagrams(root, opt, outputFolder); - } catch(Throwable t) { - root.printWarning("Error!"); - root.printWarning(t.toString()); - t.printStackTrace(); - return false; - } - return true; - } - - /** - * Standand doclet entry - * @return - */ - public static LanguageVersion languageVersion() { - return Standard.languageVersion(); - } - - /** - * Generates the package diagrams for all of the packages that contain classes among those - * returned by RootDoc.class() - */ - private static void generatePackageDiagrams(RootDoc root, Options opt, String outputFolder) - throws IOException { - Set packages = new HashSet(); - for (ClassDoc classDoc : root.classes()) { - PackageDoc packageDoc = classDoc.containingPackage(); - if(!packages.contains(packageDoc.name())) { - packages.add(packageDoc.name()); - OptionProvider view = new PackageView(outputFolder, packageDoc, root, opt); - UmlGraph.buildGraph(root, view, packageDoc); - runGraphviz(outputFolder, packageDoc.name(), packageDoc.name(), root); - alterHtmlDocs(outputFolder, packageDoc.name(), packageDoc.name(), - "package-summary.html", Pattern.compile(""), root); - } - } - } - - /** - * Generates the context diagram for a single class - */ - private static void generateContextDiagrams(RootDoc root, Options opt, String outputFolder) - throws IOException { - ContextView view = null; - for (ClassDoc classDoc : root.classes()) { - if(view == null) - view = new ContextView(outputFolder, classDoc, root, opt); - else - view.setContextCenter(classDoc); - UmlGraph.buildGraph(root, view, classDoc); - runGraphviz(outputFolder, classDoc.containingPackage().name(), classDoc.name(), root); - alterHtmlDocs(outputFolder, classDoc.containingPackage().name(), classDoc.name(), - classDoc.name() + ".html", Pattern.compile("(Class|Interface|Enum) " + classDoc.name() + ".*") , root); - } - } - - /** - * Runs Graphviz dot building both a diagram (in png format) and a client side map for it. - *

- * At the moment, it assumes dot.exe is in the classpahth - */ - private static void runGraphviz(String outputFolder, String packageName, String name, RootDoc root) { - File dotFile = new File(outputFolder, packageName.replace(".", "/") + "/" + name + ".dot"); - File pngFile = new File(outputFolder, packageName.replace(".", "/") + "/" + name + ".png"); - File mapFile = new File(outputFolder, packageName.replace(".", "/") + "/" + name + ".map"); - - try { - Process p = Runtime.getRuntime().exec(new String [] { - "dot", - "-Tcmapx", - "-o", - mapFile.getAbsolutePath(), - "-Tpng", - "-o", - pngFile.getAbsolutePath(), - dotFile.getAbsolutePath() - }); - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream())); - String line = null; - while((line = reader.readLine()) != null) - root.printWarning(line); - int result = p.waitFor(); - if (result != 0) - root.printWarning("Errors running Graphviz on " + dotFile); - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * Takes an HTML file, looks for the first instance of the specified insertion point, and - * inserts the diagram image reference and a client side map in that point. - */ - private static void alterHtmlDocs(String outputFolder, String packageName, String className, - String htmlFileName, Pattern insertPointPattern, RootDoc root) throws IOException { - // setup files - File output = new File(outputFolder, packageName.replace(".", "/")); - File htmlFile = new File(output, htmlFileName); - File alteredFile = new File(htmlFile.getAbsolutePath() + ".uml"); - File mapFile = new File(output, className + ".map"); - if (!htmlFile.exists()) { - System.err.println("Expected file not found: " + htmlFile.getAbsolutePath()); - return; - } - - // parse & rewrite - BufferedWriter writer = null; - BufferedReader reader = null; - boolean matched = false; - try { - int BUFSIZE = (int) Math.pow(2, 20); // more or less one megabyte - writer = new BufferedWriter(new FileWriter(alteredFile), BUFSIZE); - reader = new BufferedReader(new FileReader(htmlFile)); - - String line; - while ((line = reader.readLine()) != null) { - writer.write(line); - writer.newLine(); - if (!matched && insertPointPattern.matcher(line).matches()) { - matched = true; - if (mapFile.exists()) - insertClientSideMap(mapFile, writer); - else - root.printWarning("Could not find map file " + mapFile); - writer.write("

\"Package
"); - writer.newLine(); - } - } - } finally { - if (writer != null) - writer.close(); - if (reader != null) - reader.close(); - } - - // if altered, delete old file and rename new one to the old file name - if (matched) { - htmlFile.delete(); - alteredFile.renameTo(htmlFile); - } else { - root.printNotice("Warning, could not find a line that matches the pattern '" + insertPointPattern.pattern() - + "'.\n Class diagram reference not inserted"); - alteredFile.delete(); - } - } - - /** - * Reads the map file and outputs in to the specified writer - * @throws IOException - */ - private static void insertClientSideMap(File mapFile, BufferedWriter writer) throws IOException { - BufferedReader reader = null; - try { - reader = new BufferedReader(new FileReader(mapFile)); - String line = null; - while ((line = reader.readLine()) != null) { - writer.write(line); - writer.newLine(); - } - } finally { - if (reader != null) - reader.close(); - } - } - - /** - * Returns the output path specified on the javadoc options - */ - private static String findOutputPath(String[][] options) { - for (int i = 0; i < options.length; i++) { - if (options[i][0].equals("-d")) - return options[i][1]; - } - return "."; - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/View.java b/src/gr/spinellis/umlgraph/doclet/View.java deleted file mode 100644 index 20fb4e7..0000000 --- a/src/gr/spinellis/umlgraph/doclet/View.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ -package gr.spinellis.umlgraph.doclet; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.RootDoc; -import com.sun.javadoc.Tag; - -/** - * Contains the definition of a View. A View is a set of option overrides that - * will lead to the creation of a UML class diagram. Multiple views can be - * defined on the same source tree, effectively allowing to create multiple - * class diagram out of it. - * @author wolf - * - * @depend - - - Options - * @depend - - - ClassMatcher - * @depend - - - InterfaceMatcher - * @depend - - - PatternMatcher - * @depend - - - SubclassMatcher - * @depend - - - ContextMatcher - * - */ -public class View implements OptionProvider { - Map> optionOverrides = new LinkedHashMap>(); - ClassDoc viewDoc; - OptionProvider provider; - List globalOptions; - RootDoc root; - - /** - * Builds a view given the class that contains its definition - */ - public View(RootDoc root, ClassDoc c, OptionProvider provider) { - this.viewDoc = c; - this.provider = provider; - this.root = root; - Tag[] tags = c.tags(); - ClassMatcher currMatcher = null; - // parse options, get the global ones, and build a map of the - // pattern matched overrides - globalOptions = new ArrayList(); - for (int i = 0; i < tags.length; i++) { - if (tags[i].name().equals("@match")) { - currMatcher = buildMatcher(tags[i].text()); - if(currMatcher != null) { - optionOverrides.put(currMatcher, new ArrayList()); - } - } else if (tags[i].name().equals("@opt")) { - String[] opts = StringUtil.tokenize(tags[i].text()); - opts[0] = "-" + opts[0]; - if (currMatcher == null) { - globalOptions.add(opts); - } else { - optionOverrides.get(currMatcher).add(opts); - } - } - } - } - - /** - * Factory method that builds the appropriate matcher for @match tags - */ - private ClassMatcher buildMatcher(String tagText) { - // check there are at least @match and a parameter - String[] strings = StringUtil.tokenize(tagText); - if (strings.length < 2) { - System.err.println("Skipping uncomplete @match tag, type missing: " + tagText + " in view " + viewDoc); - return null; - } - - try { - if (strings[0].equals("class")) { - return new PatternMatcher(Pattern.compile(strings[1])); - } else if (strings[0].equals("context")) { - return new ContextMatcher(root, Pattern.compile(strings[1]), getGlobalOptions(), - false); - } else if (strings[0].equals("outgoingContext")) { - return new ContextMatcher(root, Pattern.compile(strings[1]), getGlobalOptions(), - false); - } else if (strings[0].equals("interface")) { - return new InterfaceMatcher(root, Pattern.compile(strings[1])); - } else if (strings[0].equals("subclass")) { - return new SubclassMatcher(root, Pattern.compile(strings[1])); - } else { - System.err.println("Skipping @match tag, unknown match type, in view " + viewDoc); - } - } catch (PatternSyntaxException pse) { - System.err.println("Skipping @match tag due to invalid regular expression '" + tagText - + "'" + " in view " + viewDoc); - } catch (Exception e) { - System.err.println("Skipping @match tag due to an internal error '" + tagText - + "'" + " in view " + viewDoc); - e.printStackTrace(); - } - return null; - } - - - // ---------------------------------------------------------------- - // OptionProvider methods - // ---------------------------------------------------------------- - - public Options getOptionsFor(ClassDoc cd) { - Options localOpt = getGlobalOptions(); - overrideForClass(localOpt, cd); - localOpt.setOptions(cd); - return localOpt; - } - - public Options getOptionsFor(String name) { - Options localOpt = getGlobalOptions(); - overrideForClass(localOpt, name); - return localOpt; - } - - public Options getGlobalOptions() { - Options go = provider.getGlobalOptions(); - - boolean outputSet = false; - for (String[] opts : globalOptions) { - if (opts[0].equals("-output")) - outputSet = true; - go.setOption(opts); - } - if (!outputSet) - go.setOption(new String[] { "-output", viewDoc.name() + ".dot" }); - - return go; - } - - public void overrideForClass(Options opt, ClassDoc cd) { - provider.overrideForClass(opt, cd); - for (ClassMatcher cm : optionOverrides.keySet()) { - if(cm.matches(cd)) { - for (String[] override : optionOverrides.get(cm)) { - opt.setOption(override); - } - } - } - } - - public void overrideForClass(Options opt, String className) { - provider.overrideForClass(opt, className); - for (ClassMatcher cm : optionOverrides.keySet()) { - if(cm.matches(className)) { - for (String[] override : optionOverrides.get(cm)) { - opt.setOption(override); - } - } - } - } - - public String getDisplayName() { - return "view " + viewDoc.name(); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/Visibility.java b/src/gr/spinellis/umlgraph/doclet/Visibility.java deleted file mode 100644 index 36da653..0000000 --- a/src/gr/spinellis/umlgraph/doclet/Visibility.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.ProgramElementDoc; - -/** - * Enumerates the possible visibilities in a Java program. For brevity, package - * private visibility is referred as PACKAGE. - * @author wolf - * - */ -public enum Visibility { - PRIVATE, PACKAGE, PROTECTED, PUBLIC; - - public static Visibility get(ProgramElementDoc doc) { - if (doc.isPrivate()) - return PRIVATE; - else if (doc.isPackagePrivate()) - return PACKAGE; - else if (doc.isProtected()) - return PROTECTED; - else - return PUBLIC; - - } -} \ No newline at end of file diff --git a/src/gr/spinellis/umlgraph/doclet/WrappedClassDoc.java b/src/gr/spinellis/umlgraph/doclet/WrappedClassDoc.java deleted file mode 100644 index b236038..0000000 --- a/src/gr/spinellis/umlgraph/doclet/WrappedClassDoc.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.AnnotationDesc; -import com.sun.javadoc.AnnotationTypeDoc; -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.ConstructorDoc; -import com.sun.javadoc.FieldDoc; -import com.sun.javadoc.MethodDoc; -import com.sun.javadoc.PackageDoc; -import com.sun.javadoc.ParamTag; -import com.sun.javadoc.ParameterizedType; -import com.sun.javadoc.SeeTag; -import com.sun.javadoc.SourcePosition; -import com.sun.javadoc.Tag; -import com.sun.javadoc.Type; -import com.sun.javadoc.TypeVariable; -import com.sun.javadoc.WildcardType; - -/** - * A ClassDoc wrapper that caches answer to the most common requests performed - * by UMLGraph, considerably improving the overall UMLDoc performance (ClassDoc - * computes most of the results for more fine grained information at each call). - *

- * Unfortunately this has a side effect, since it breaks the equals() call between - * plain ClassDoc instances and WrappedClassDoc ones, so use it with due care. - *

- * In particular, don't provide WrappedClassDoc instances to the standard doclet. - * @author wolf - * - */ -public class WrappedClassDoc implements ClassDoc { - ClassDoc wrapped; - String toString; - String name; - Tag[] tags; - - public WrappedClassDoc(ClassDoc wrapped) { - this.wrapped = wrapped; - } - - public AnnotationDesc[] annotations() { - return wrapped.annotations(); - } - - public AnnotationTypeDoc asAnnotationTypeDoc() { - return wrapped.asAnnotationTypeDoc(); - } - - public ClassDoc asClassDoc() { - return wrapped.asClassDoc(); - } - - public ParameterizedType asParameterizedType() { - return wrapped.asParameterizedType(); - } - - public TypeVariable asTypeVariable() { - return wrapped.asTypeVariable(); - } - - public WildcardType asWildcardType() { - return wrapped.asWildcardType(); - } - - public String commentText() { - return wrapped.commentText(); - } - - public int compareTo(Object arg0) { - if (arg0 instanceof WrappedClassDoc) { - WrappedClassDoc other = (WrappedClassDoc) arg0; - return wrapped.compareTo(other.wrapped); - } - return wrapped.compareTo(arg0); - } - - public ConstructorDoc[] constructors() { - return wrapped.constructors(); - } - - public ConstructorDoc[] constructors(boolean arg0) { - return wrapped.constructors(arg0); - } - - public ClassDoc containingClass() { - return wrapped.containingClass(); - } - - public PackageDoc containingPackage() { - return wrapped.containingPackage(); - } - - public boolean definesSerializableFields() { - return wrapped.definesSerializableFields(); - } - - public String dimension() { - return wrapped.dimension(); - } - - public FieldDoc[] enumConstants() { - return wrapped.enumConstants(); - } - - public FieldDoc[] fields() { - return wrapped.fields(); - } - - public FieldDoc[] fields(boolean arg0) { - return wrapped.fields(arg0); - } - - public ClassDoc findClass(String arg0) { - return wrapped.findClass(arg0); - } - - public Tag[] firstSentenceTags() { - return wrapped.firstSentenceTags(); - } - - public String getRawCommentText() { - return wrapped.getRawCommentText(); - } - - /** @deprecated */ - public @Deprecated ClassDoc[] importedClasses() { - return wrapped.importedClasses(); - } - - /** @deprecated */ - public @Deprecated PackageDoc[] importedPackages() { - return wrapped.importedPackages(); - } - - public Tag[] inlineTags() { - return wrapped.inlineTags(); - } - - public ClassDoc[] innerClasses() { - return wrapped.innerClasses(); - } - - public ClassDoc[] innerClasses(boolean arg0) { - return wrapped.innerClasses(arg0); - } - - public ClassDoc[] interfaces() { - return wrapped.interfaces(); - } - - public Type[] interfaceTypes() { - return wrapped.interfaceTypes(); - } - - public boolean isAbstract() { - return wrapped.isAbstract(); - } - - public boolean isAnnotationType() { - return wrapped.isAnnotationType(); - } - - public boolean isAnnotationTypeElement() { - return wrapped.isAnnotationTypeElement(); - } - - public boolean isClass() { - return wrapped.isClass(); - } - - public boolean isConstructor() { - return wrapped.isConstructor(); - } - - public boolean isEnum() { - return wrapped.isEnum(); - } - - public boolean isEnumConstant() { - return wrapped.isEnumConstant(); - } - - public boolean isError() { - return wrapped.isError(); - } - - public boolean isException() { - return wrapped.isException(); - } - - public boolean isExternalizable() { - return wrapped.isExternalizable(); - } - - public boolean isField() { - return wrapped.isField(); - } - - public boolean isFinal() { - return wrapped.isFinal(); - } - - public boolean isIncluded() { - return wrapped.isIncluded(); - } - - public boolean isInterface() { - return wrapped.isInterface(); - } - - public boolean isMethod() { - return wrapped.isMethod(); - } - - public boolean isOrdinaryClass() { - return wrapped.isOrdinaryClass(); - } - - public boolean isPackagePrivate() { - return wrapped.isPackagePrivate(); - } - - public boolean isPrimitive() { - return wrapped.isPrimitive(); - } - - public boolean isPrivate() { - return wrapped.isPrivate(); - } - - public boolean isProtected() { - return wrapped.isProtected(); - } - - public boolean isPublic() { - return wrapped.isPublic(); - } - - public boolean isSerializable() { - return wrapped.isSerializable(); - } - - public boolean isStatic() { - return wrapped.isStatic(); - } - - public MethodDoc[] methods() { - return wrapped.methods(); - } - - public MethodDoc[] methods(boolean arg0) { - return wrapped.methods(arg0); - } - - public String modifiers() { - return wrapped.modifiers(); - } - - public int modifierSpecifier() { - return wrapped.modifierSpecifier(); - } - - public String name() { - if (name == null) - name = wrapped.name(); - return name; - } - - public SourcePosition position() { - return wrapped.position(); - } - - public String qualifiedName() { - return wrapped.qualifiedName(); - } - - public String qualifiedTypeName() { - return wrapped.qualifiedTypeName(); - } - - public SeeTag[] seeTags() { - return wrapped.seeTags(); - } - - public FieldDoc[] serializableFields() { - return wrapped.serializableFields(); - } - - public MethodDoc[] serializationMethods() { - return wrapped.serializationMethods(); - } - - public void setRawCommentText(String arg0) { - wrapped.setRawCommentText(arg0); - } - - public String simpleTypeName() { - return wrapped.simpleTypeName(); - } - - public boolean subclassOf(ClassDoc arg0) { - return wrapped.subclassOf(arg0); - } - - public ClassDoc superclass() { - return wrapped.superclass(); - } - - public Type superclassType() { - return wrapped.superclassType(); - } - - public Tag[] tags() { - if (tags == null) - tags = wrapped.tags(); - return tags; - } - - public Tag[] tags(String arg0) { - return wrapped.tags(arg0); - } - - public String toString() { - if (toString == null) { - toString = wrapped.toString(); - } - return toString; - } - - public String typeName() { - return wrapped.typeName(); - } - - public TypeVariable[] typeParameters() { - return wrapped.typeParameters(); - } - - public ParamTag[] typeParamTags() { - return wrapped.typeParamTags(); - } - -} diff --git a/src/gr/spinellis/umlgraph/doclet/WrappedRootDoc.java b/src/gr/spinellis/umlgraph/doclet/WrappedRootDoc.java deleted file mode 100644 index 2b6e21f..0000000 --- a/src/gr/spinellis/umlgraph/doclet/WrappedRootDoc.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Create a graphviz graph based on the classes in the specified java - * source files. - * - * (C) Copyright 2002-2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.doclet; - -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.PackageDoc; -import com.sun.javadoc.RootDoc; -import com.sun.javadoc.SeeTag; -import com.sun.javadoc.SourcePosition; -import com.sun.javadoc.Tag; - -/** - * RootDoc wrapper that provides WrappedClassDoc instances instead of plain ClassDoc in order - * to optimize the overall performance of UMLDoc. - * @author wolf - */ -public class WrappedRootDoc implements RootDoc { - RootDoc wrapped; - WrappedClassDoc[] wrappedClassDocs; - - public WrappedRootDoc(RootDoc wrapped) { - this.wrapped = wrapped; - ClassDoc[] classes = wrapped.classes(); - wrappedClassDocs = new WrappedClassDoc[classes.length]; - for (int i = 0; i < classes.length; i++) { - wrappedClassDocs[i] = new WrappedClassDoc(classes[i]); - } - } - - public ClassDoc[] classes() { - return wrappedClassDocs; - } - - public ClassDoc classNamed(String arg0) { - return wrapped.classNamed(arg0); - } - - public String commentText() { - return wrapped.commentText(); - } - - public int compareTo(Object arg0) { - return wrapped.compareTo(arg0); - } - - public Tag[] firstSentenceTags() { - return wrapped.firstSentenceTags(); - } - - public String getRawCommentText() { - return wrapped.getRawCommentText(); - } - - public Tag[] inlineTags() { - return wrapped.inlineTags(); - } - - public boolean isAnnotationType() { - return wrapped.isAnnotationType(); - } - - public boolean isAnnotationTypeElement() { - return wrapped.isAnnotationTypeElement(); - } - - public boolean isClass() { - return wrapped.isClass(); - } - - public boolean isConstructor() { - return wrapped.isConstructor(); - } - - public boolean isEnum() { - return wrapped.isEnum(); - } - - public boolean isEnumConstant() { - return wrapped.isEnumConstant(); - } - - public boolean isError() { - return wrapped.isError(); - } - - public boolean isException() { - return wrapped.isException(); - } - - public boolean isField() { - return wrapped.isField(); - } - - public boolean isIncluded() { - return wrapped.isIncluded(); - } - - public boolean isInterface() { - return wrapped.isInterface(); - } - - public boolean isMethod() { - return wrapped.isMethod(); - } - - public boolean isOrdinaryClass() { - return wrapped.isOrdinaryClass(); - } - - public String name() { - return wrapped.name(); - } - - public String[][] options() { - return wrapped.options(); - } - - public PackageDoc packageNamed(String arg0) { - return wrapped.packageNamed(arg0); - } - - public SourcePosition position() { - return wrapped.position(); - } - - public void printError(SourcePosition arg0, String arg1) { - wrapped.printError(arg0, arg1); - } - - public void printError(String arg0) { - wrapped.printError(arg0); - } - - public void printNotice(SourcePosition arg0, String arg1) { - wrapped.printNotice(arg0, arg1); - } - - public void printNotice(String arg0) { - wrapped.printNotice(arg0); - } - - public void printWarning(SourcePosition arg0, String arg1) { - wrapped.printWarning(arg0, arg1); - } - - public void printWarning(String arg0) { - wrapped.printWarning(arg0); - } - - public SeeTag[] seeTags() { - return wrapped.seeTags(); - } - - public void setRawCommentText(String arg0) { - wrapped.setRawCommentText(arg0); - } - - public ClassDoc[] specifiedClasses() { - return wrapped.specifiedClasses(); - } - - public PackageDoc[] specifiedPackages() { - return wrapped.specifiedPackages(); - } - - public Tag[] tags() { - return wrapped.tags(); - } - - public Tag[] tags(String arg0) { - return wrapped.tags(arg0); - } - -} diff --git a/src/gr/spinellis/umlgraph/test/BasicTest.java b/src/gr/spinellis/umlgraph/test/BasicTest.java deleted file mode 100644 index 7206e01..0000000 --- a/src/gr/spinellis/umlgraph/test/BasicTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * UmlGraph class diagram testing framework - * - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.test; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * UmlGraph regression tests - * @author wolf - * - */ -public class BasicTest { - - static String testSourceFolder = "testdata/java"; - - static String testDestFolder = "testdata/dot-out"; - - static String testRefFolder = "testdata/dot-ref"; - - static PrintWriter pw = new PrintWriter(System.out); - - public static void main(String[] args) throws IOException { - List differences = new ArrayList(); - - File outFolder = new File(testDestFolder); - if (!outFolder.exists()) - outFolder.mkdirs(); - - TestUtils.cleanFolder(outFolder, true); - - // don't use windows specific fonts - System.setProperty("os.name", "generic"); - - // run tests - performBasicTests(differences); - performViewTests(differences, outFolder); - if (differences.size() > 0) { - pw.println("ERROR, some files are not structurally equal or some files are missing:"); - for (String className : differences) { - pw.println(className); - } - } else { - pw.println("GOOD, all files are structurally equal"); - } - pw.println(); - pw.println(); - pw.flush(); - } - - private static void performViewTests(List differences, File outFolder) - throws IOException { - String[] options = new String[] { "-docletpath", "build", "-private", "-d", - outFolder.getAbsolutePath(), "-sourcepath", "testdata/java", "-compact", - "-subpackages", "gr.spinellis", "-views" }; - runDoclet(options); - - List viewFiles = new ArrayList(); - viewFiles.addAll(getViewList(new File(testSourceFolder, "gr/spinellis/basic/views"))); - viewFiles.addAll(getViewList(new File(testSourceFolder, "gr/spinellis/context/views"))); - viewFiles.addAll(getViewList(new File(testSourceFolder, "gr/spinellis/iface/views"))); - viewFiles.addAll(getViewList(new File(testSourceFolder, "gr/spinellis/subclass/views"))); - for (String fileName : viewFiles) { - String viewName = fileName.substring(0, fileName.length() - 5); - File dotFile = new File(testDestFolder, viewName + ".dot"); - File refFile = new File(testRefFolder, viewName + ".dot"); - if (viewName.contains("Abstract")) { - // make sure abstract views are not generated - if (dotFile.exists()) { - pw.println("Error, abstract view " + viewName + " has been generated"); - differences.add(dotFile.getName() + " should not be there"); - } - } else { - compare(differences, dotFile, refFile); - } - } - } - - private static List getViewList(File viewFolder) { - if (!viewFolder.exists()) - throw new RuntimeException("The folder " + viewFolder.getAbsolutePath() - + " does not exists."); - else if (!viewFolder.isDirectory()) - throw new RuntimeException(viewFolder.getAbsolutePath() + " is not a folder!."); - else if (!viewFolder.canRead()) - throw new RuntimeException("The folder " + viewFolder.getAbsolutePath() - + " cannot be read."); - - return Arrays.asList(viewFolder.list(new SimpleFileFilter(".java"))); - } - - private static boolean performBasicTests(List differences) throws IOException { - String[] javaFiles = new File(testSourceFolder).list(new SimpleFileFilter(".java")); - boolean equal = true; - for (int i = 0; i < javaFiles.length; i++) { - String javaFileName = javaFiles[i].substring(0, javaFiles[i].length() - 5); - String outFileName = javaFileName + ".dot"; - File dotFile = new File(testDestFolder, outFileName); - dotFile.delete(); - File refFile = new File(testRefFolder, outFileName); - String javaPath = new File(testSourceFolder, javaFiles[i]).getAbsolutePath(); - String[] options = new String[] { "-docletpath", "build", "-hide", "Hidden", - "-compact", "-private", "-d", testDestFolder, "-output", outFileName, javaPath }; - - runDoclet(options); - compare(differences, dotFile, refFile); - } - return equal; - } - - private static void runDoclet(String[] options) { - com.sun.tools.javadoc.Main.execute("UMLGraph test", pw, pw, pw, - "gr.spinellis.umlgraph.doclet.UmlGraph", options); - } - - private static void compare(List differences, File dotFile, File refFile) - throws IOException { - if (!dotFile.exists()) { - pw.println("Error, output file " + dotFile + " has not been generated"); - differences.add(dotFile.getName() + " has not been generated"); - } else if (!refFile.exists()) { - pw.println("Error, reference file " + refFile + " is not available"); - differences.add(refFile.getName() + " reference is not available"); - } else if (!TestUtils.dotFilesEqual(pw, dotFile.getAbsolutePath(), refFile - .getAbsolutePath())) { - differences.add(dotFile.getName() + " is different from the reference"); - } - } - -} diff --git a/src/gr/spinellis/umlgraph/test/DotDiff.java b/src/gr/spinellis/umlgraph/test/DotDiff.java deleted file mode 100644 index 24106c4..0000000 --- a/src/gr/spinellis/umlgraph/test/DotDiff.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * UmlGraph class diagram testing framework - * - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.test; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.StreamTokenizer; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class DotDiff { - - private List nodes1 = new ArrayList(); - - private List nodes2 = new ArrayList(); - - private List arcs1 = new ArrayList(); - - private List arcs2 = new ArrayList(); - - private List extraLines1 = new ArrayList(); - - private List extraLines2 = new ArrayList(); - - /** - * Builds a dot differ on the two files - * - * @param dotFirst - * @param dotSecond - * @throws IOException - */ - public DotDiff(File dotFirst, File dotSecond) throws IOException { - // gather the lines - List lines1 = readGraphLines(dotFirst); - List lines2 = readGraphLines(dotSecond); - - // parse the lines - extraLines1 = parseLines(lines1, nodes1, arcs1); - extraLines2 = parseLines(lines2, nodes2, arcs2); - - // diff extra lines - for (Iterator it = extraLines1.iterator(); it.hasNext();) { - if (extraLines2.remove(it.next())) - it.remove(); - } - - // diff nodes - for (Iterator it = nodes1.iterator(); it.hasNext();) { - if (nodes2.remove(it.next())) - it.remove(); - } - - // diff arcs - for (Iterator it = arcs1.iterator(); it.hasNext();) { - if (arcs2.remove(it.next())) - it.remove(); - } - } - - /** - * Returns true if the dot files are structurally equal, that is, if every - * non comment and non header line of the first file appears in the second, - * and otherwise. - * - * @return - */ - public boolean graphEquals() { - return (extraLines1.size() + extraLines2.size() + nodes1.size() + nodes2.size() - + arcs1.size() + arcs2.size()) == 0; - } - - public List getArcs1() { - return arcs1; - } - - public List getArcs2() { - return arcs2; - } - - public List getExtraLines1() { - return extraLines1; - } - - public List getExtraLines2() { - return extraLines2; - } - - public List getNodes1() { - return nodes1; - } - - public List getNodes2() { - return nodes2; - } - - /** - * Reads all relevant lines from the dot file - * - * @param dotFile - * @return - * @throws IOException - */ - private List readGraphLines(File dotFile) throws IOException { - List lines = new ArrayList(); - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader(dotFile)); - - String line; - while ((line = br.readLine()) != null) { - line = line.trim(); - if (graphDefinitionLine(line)) - lines.add(line); - } - } finally { - if (br != null) - br.close(); - } - - return lines; - } - - /** - * Tells if a line is relevant or not (unrelevant lines are headers, - * comments, "digraf G {" and the closing "}" (to simplify matters we assume - * the file is properly structured). - * - * @param line - * @return - */ - private boolean graphDefinitionLine(String line) { - return !(line.startsWith("#") || line.startsWith("//") || line.equals("digraph G {") || line - .equals("}")); - } - - private List parseLines(List lines, List nodeList, List arcs) - throws IOException { - List extraLines = new ArrayList(); - List arcLines = new ArrayList(); - Map nodes = new HashMap(); - for (String line : lines) { - int openBrackedIdx = line.indexOf('['); - int closedBracketIdx = line.lastIndexOf(']'); - int arrowIdx = line.indexOf("->"); - if (openBrackedIdx < 0 && closedBracketIdx < 0 || line.startsWith("edge") - || line.startsWith("node")) - extraLines.add(line); - else if (arrowIdx > 0 && arrowIdx < openBrackedIdx) { // that's an arc - arcLines.add(line); - } else { // that's a node - String attributes = line.substring(openBrackedIdx + 1, closedBracketIdx); - Map attMap = parseAttributes(attributes); - String name = line.substring(0, openBrackedIdx - 1).trim(); - String label = attMap.get("label"); - DotNode node = new DotNode(name, label, attMap, line); - nodes.put(name, node); - nodeList.add(node); - } - } - for (String line : arcLines) { - int openBrackedIdx = line.indexOf('['); - int closedBracketIdx = line.lastIndexOf(']'); - String attributes = line.substring(openBrackedIdx + 1, closedBracketIdx); - String[] names = line.substring(0, openBrackedIdx).split("->"); - DotNode from = nodes.get(names[0].trim()); - DotNode to = nodes.get(names[1].trim()); - if (from == null) { - from = new DotNode(names[0], "", new HashMap(), ""); - } - if (to == null) { - to = new DotNode(names[1], "", new HashMap(), ""); - } - arcs.add(new DotArc(from, to, parseAttributes(attributes), line)); - } - return extraLines; - } - - private Map parseAttributes(String attributes) throws IOException { - Map map = new HashMap(); - - StreamTokenizer st = new StreamTokenizer(new StringReader(attributes)); - st.wordChars('_', '_'); - st.wordChars('\\', '\\'); - st.wordChars('\'', '\''); - int tokenType; - boolean isValue = false; - String attName = null; - String token = null; - while ((tokenType = st.nextToken()) != StreamTokenizer.TT_EOF) { - switch (tokenType) { - case StreamTokenizer.TT_NUMBER: - token = "" + st.nval; - break; - case StreamTokenizer.TT_WORD: - case '"': - case '\'': - token = st.sval; - break; - } - tokenType = st.nextToken(); - - if (isValue) { - map.put(attName, token); - isValue = false; - } else { - attName = token; - isValue = true; - } - } - - return map; - } - - private static class DotNode { - String name; - - String label; - - Map attributes; - - String line; - - public DotNode(String name, String label, Map attributes, String line) { - this.name = name; - this.label = label.replace("\n", "\\n"); - this.attributes = attributes; - this.line = line.replace("\n", "\\n"); - } - - public boolean equals(Object other) { - if (!(other instanceof DotNode)) - return false; - - DotNode on = (DotNode) other; - if (label == null) // anonymous node - return on.label == null && on.name.equals(name) && on.attributes.equals(attributes); - else - return on.label.equals(label) && on.attributes.equals(attributes); - } - - public int hashCode() { - return name.hashCode() + 17 * attributes.hashCode(); - } - - public String toString() { - return "Node: " + label + "; " + line; - } - - } - - private static class DotArc { - DotNode from; - - DotNode to; - - Map attributes; - - String line; - - public DotArc(DotNode from, DotNode to, Map attributes, String line) { - this.from = from; - this.to = to; - this.attributes = attributes; - this.line = line.replace("\n", "\\n"); - } - - public boolean equals(Object other) { - if (!(other instanceof DotArc)) - return false; - - DotArc oa = (DotArc) other; - return oa.from.equals(from) && oa.to.equals(to) && oa.attributes.equals(attributes); - } - - public int hashCode() { - return from.hashCode() + 17 * (to.hashCode() + 17 * attributes.hashCode()); - } - - public String toString() { - return "Arc: " + from.label + " -> " + to.label + "; " + line; - } - } - -} diff --git a/src/gr/spinellis/umlgraph/test/RunDoc.java b/src/gr/spinellis/umlgraph/test/RunDoc.java deleted file mode 100644 index 4dbb2c6..0000000 --- a/src/gr/spinellis/umlgraph/test/RunDoc.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * UmlGraph class diagram testing framework - * - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.test; - -import java.io.File; -import java.io.PrintWriter; - -public class RunDoc { - - static String sourcesFolder = "src"; - - static String docFolder = "javadoc"; - - static PrintWriter pw = new PrintWriter(System.out); - - public static void main(String[] args) { - File outFolder = new File(docFolder); - if (!outFolder.exists()) - outFolder.mkdirs(); - String[] options = new String[] { "-docletpath", "build", "-private", "-d", docFolder, - "-sourcepath", sourcesFolder, "-subpackages", "gr.spinellis" }; - runDoclet(options); - } - - private static void runDoclet(String[] options) { - com.sun.tools.javadoc.Main.execute("UMLGraph test", pw, pw, pw, - "gr.spinellis.umlgraph.doclet.UmlGraphDoc", options); - } - -} diff --git a/src/gr/spinellis/umlgraph/test/RunOne.java b/src/gr/spinellis/umlgraph/test/RunOne.java deleted file mode 100644 index ce4e3ed..0000000 --- a/src/gr/spinellis/umlgraph/test/RunOne.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * UmlGraph class diagram testing framework - * - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.test; - -import java.io.File; -import java.io.PrintWriter; - -public class RunOne { - - static String testSourceFolder = "testdata/java/"; - - static String testDestFolder = "testdata/dot-out"; - - static PrintWriter pw = new PrintWriter(System.out); - - public static void main(String[] args) { - File outFolder = new File(testDestFolder); - if (!outFolder.exists()) - outFolder.mkdirs(); - -// runView("gr.spinellis.views.ViewChildEmpty"); - runSingleClass("TestHiddenOp"); - } - - public static void runView(String viewClass) { - String[] options = new String[] { "-docletpath", "build", "-private", "-d", - testDestFolder, "-sourcepath", "testdata/java", "-subpackages", - "gr.spinellis", "-view", viewClass}; - runDoclet(options); - } - - public static void runSingleClass(String className) { - String[] options = new String[] { "-docletpath", "build", "-hide", "Hidden", - "-private", "-d", testDestFolder, "-output", className + ".dot", testSourceFolder + className + ".java"}; - runDoclet(options); - } - - private static void runDoclet(String[] options) { - com.sun.tools.javadoc.Main.execute("UMLGraph test", pw, pw, pw, "gr.spinellis.umlgraph.doclet.UmlGraph", options); - } - - -} diff --git a/src/gr/spinellis/umlgraph/test/SimpleFileFilter.java b/src/gr/spinellis/umlgraph/test/SimpleFileFilter.java deleted file mode 100644 index 4b2e7bc..0000000 --- a/src/gr/spinellis/umlgraph/test/SimpleFileFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * UmlGraph class diagram testing framework - * - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ -package gr.spinellis.umlgraph.test; - -import java.io.File; -import java.io.FilenameFilter; - -class SimpleFileFilter implements FilenameFilter { - protected String extension; - - public SimpleFileFilter(String ext) { - this.extension = ext; - } - - public boolean accept(File dir, String name) { - return name.endsWith(extension); - } -} \ No newline at end of file diff --git a/src/gr/spinellis/umlgraph/test/TestUtils.java b/src/gr/spinellis/umlgraph/test/TestUtils.java deleted file mode 100644 index ffc9b42..0000000 --- a/src/gr/spinellis/umlgraph/test/TestUtils.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * UmlGraph class diagram testing framework - * - * Contibuted by Andrea Aime - * (C) Copyright 2005 Diomidis Spinellis - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * $Id$ - * - */ - -package gr.spinellis.umlgraph.test; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.List; - -/** - * Collection of utility methods used by the test classes - * @author wolf - * - */ -public class TestUtils { - - /** - * Simple text file diffing: will tell you if two text files are line by - * line equals, and will stop at the first difference found. - * @throws IOException - */ - public static boolean textFilesEquals(PrintWriter pw, File refTextFile, File outTextFile) - throws IOException { - BufferedReader refReader = null, outReader = null; - String refLine = null, outFile = null; - try { - pw.println("Performing diff:"); - pw.println("out: " + outTextFile.getAbsolutePath()); - pw.println("ref: " + refTextFile.getAbsolutePath()); - - refReader = new BufferedReader(new FileReader(refTextFile)); - outReader = new BufferedReader(new FileReader(outTextFile)); - - // line by line scan, exit when one file ends or lines are not - // equal (and pass over the "Generated by javadoc ..." comments) - for (;;) { - refLine = refReader.readLine(); - outFile = outReader.readLine(); - if (refLine == null || outFile == null) { - break; - } else if (refLine.startsWith("