") && 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("  ");
- 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(" |