diff --git a/src/main/java/org/umlgraph/doclet/ClassGraph.java b/src/main/java/org/umlgraph/doclet/ClassGraph.java index 20de963..8e0ee3f 100644 --- a/src/main/java/org/umlgraph/doclet/ClassGraph.java +++ b/src/main/java/org/umlgraph/doclet/ClassGraph.java @@ -162,18 +162,40 @@ class ClassGraph { linePostfix = opt.compact ? "" : "\n"; } - /** Return the class's name, possibly by stripping the leading path */ - private String qualifiedName(Options opt, Name className) { - if (opt.hideGenerics) { - className = removeTemplate(elementUtils, className); + /** Return the class's name, possibly by stripping the leading path + * @param list */ + private String qualifiedName(Options opt, Name className, List typeParameters) { + String genericsInfo = ""; + if (opt.hideGenerics || typeParameters == null || typeParameters.isEmpty()) { + // nothing to do + } else { + for (int i = 0; i < typeParameters.size(); i++) { + if (i == 0) { + genericsInfo += "<"; + } + TypeParameterElement type = typeParameters.get(i); + List mirrors = type.getBounds(); + if (opt.showQualifiedGenerics && mirrors != null && !mirrors.isEmpty()) { + for (TypeMirror m : mirrors) { + genericsInfo += ElementUtil.getQualifiedName(types, m); + } + } else { + genericsInfo += type.getSimpleName(); + } + if (i < typeParameters.size() - 1) { + genericsInfo += ", "; + } else if (i == typeParameters.size() - 1) { + genericsInfo += ">"; + } + } } - // Fast path - nothing to do: - if (opt.showQualified && (opt.showQualifiedGenerics || className.toString().indexOf('<') < 0)) { - return className.toString(); + + if (opt.showQualified) { + return className.toString() + genericsInfo; } StringBuilder buf = new StringBuilder(className.length()); qualifiedNameInner(opt, className, buf, 0, !opt.showQualified); - return buf.toString(); + return buf.toString() + genericsInfo; } private static int qualifiedNameInner(Options opt, Name r, StringBuilder buf, int last, boolean strip) { @@ -428,7 +450,7 @@ class ClassGraph { } stereotype(opt, c, Align.CENTER); Font font = c.getModifiers().contains(Modifier.ABSTRACT) && c.getKind() != ElementKind.INTERFACE ? Font.CLASS_ABSTRACT : Font.CLASS; - String qualifiedName = qualifiedName(opt, c.getQualifiedName()); + String qualifiedName = qualifiedName(opt, c.getQualifiedName(), c.getTypeParameters()); int idx = splitPackageClass(qualifiedName); if (opt.showComment) { tableLine(Align.LEFT, Font.CLASS.wrap(opt, htmlNewline(escape(TagUtil.getComment(docTrees, c))))); @@ -680,7 +702,7 @@ class ClassGraph { w.print(linePrefix + info.name + "[label="); externalTableStart(opt, className, classToUrl(className)); innerTableStart(); - String qualifiedName = qualifiedName(opt, className); + String qualifiedName = qualifiedName(opt, className, null); int startTemplate = qualifiedName.indexOf('<'); int idx = qualifiedName.lastIndexOf('.', startTemplate < 0 ? qualifiedName.length() - 1 : startTemplate); if (opt.postfixPackage && idx > 0 && idx < (qualifiedName.length() - 1)) { diff --git a/src/main/java/org/umlgraph/doclet/UmlGraph.java b/src/main/java/org/umlgraph/doclet/UmlGraph.java index dba68e5..8d4cad1 100644 --- a/src/main/java/org/umlgraph/doclet/UmlGraph.java +++ b/src/main/java/org/umlgraph/doclet/UmlGraph.java @@ -137,19 +137,21 @@ public class UmlGraph implements Doclet { */ public static Options buildOptions(DocletEnvironment root, Options o) { commentOptions = o.clone(); - commentOptions.setOptions(root.getDocTrees(), findClass(root, "UMLNoteOptions")); + commentOptions.setOptions(root.getDocTrees(), findClass(root, "UMLNoteOptions", false)); commentOptions.shape = Shape.NOTE; Options opt = o.clone(); - opt.setOptions(root.getDocTrees(), findClass(root, "UMLOptions")); + opt.setOptions(root.getDocTrees(), findClass(root, "UMLOptions", false)); return opt; } /** Return the ClassDoc for the specified class; null if not found. */ - private static TypeElement findClass(DocletEnvironment root, String name) { + private static TypeElement findClass(DocletEnvironment root, String name, boolean qualified) { Set classes = root.getIncludedElements(); for (Element element : classes) { - if (element instanceof TypeElement && ((TypeElement) element).getQualifiedName().toString().equals(name)) { + if (qualified && element instanceof TypeElement && ((TypeElement) element).getQualifiedName().toString().equals(name)) { + return (TypeElement) element; + } else if (!qualified && element instanceof TypeElement && element.getSimpleName().toString().equals(name)) { return (TypeElement) element; } } @@ -206,7 +208,7 @@ public class UmlGraph implements Doclet { */ public static List buildViews(Options opt, DocletEnvironment srcRootDoc, DocletEnvironment viewRootDoc) { if (opt.viewName != null) { - TypeElement viewClass = findClass(viewRootDoc, opt.viewName); + TypeElement viewClass = findClass(viewRootDoc, opt.viewName, true); if (viewClass == null) { System.out.println("View " + opt.viewName + " not found! Exiting without generating any output."); return null; diff --git a/src/main/java/org/umlgraph/doclet/UmlGraphDoc.java b/src/main/java/org/umlgraph/doclet/UmlGraphDoc.java index 6bee5af..01c58c9 100644 --- a/src/main/java/org/umlgraph/doclet/UmlGraphDoc.java +++ b/src/main/java/org/umlgraph/doclet/UmlGraphDoc.java @@ -122,8 +122,8 @@ public class UmlGraphDoc implements Doclet { } else { continue; } - if (!packages.contains(packageDoc.getSimpleName())) { - packages.add(packageDoc.getSimpleName()); + if (!packages.contains(packageDoc.getQualifiedName())) { + packages.add(packageDoc.getQualifiedName()); OptionProvider view = new PackageView(outputFolder, packageDoc, root, opt); UmlGraph.buildGraph(reporter, root, opt, view, packageDoc); runGraphviz(opt.dotExecutable, outputFolder, ElementUtil.getModuleOf(root, packageDoc), packageDoc.getQualifiedName(), packageDoc.getSimpleName(), reporter); diff --git a/src/main/java/org/umlgraph/doclet/util/ElementUtil.java b/src/main/java/org/umlgraph/doclet/util/ElementUtil.java index 4597cbd..2ce068d 100644 --- a/src/main/java/org/umlgraph/doclet/util/ElementUtil.java +++ b/src/main/java/org/umlgraph/doclet/util/ElementUtil.java @@ -15,6 +15,7 @@ import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; @@ -68,6 +69,9 @@ public class ElementUtil { if (element instanceof TypeElement) { return ((TypeElement) element).getQualifiedName(); } + if (element instanceof TypeVariable) { + return element.getSimpleName(); + } return ""; }