mirror of https://github.com/dspinellis/UMLGraph
Various changes, hard to account for all of them. Yet, basically:
* ability to compute relative links for UmlDoc diagrams (client side image maps) * better handling of sources with annotations and generics usage * avoid relying on specifiedpacakges to check if classes are included in the parsed source, maven 2 does not provide javadoc with them, but with a plain list of classes
This commit is contained in:
parent
a1f3f6ab6c
commit
74a9c16003
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
package gr.spinellis.umlgraph.doclet;
|
package gr.spinellis.umlgraph.doclet;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
@ -411,7 +411,7 @@ class ClassGraph {
|
||||||
return true;
|
return true;
|
||||||
Options opt;
|
Options opt;
|
||||||
if(c instanceof ClassDoc)
|
if(c instanceof ClassDoc)
|
||||||
opt = optionProvider.getOptionsFor(c.toString());
|
opt = optionProvider.getOptionsFor((ClassDoc) c);
|
||||||
else
|
else
|
||||||
opt = optionProvider.getOptionsFor(c.containingClass());
|
opt = optionProvider.getOptionsFor(c.containingClass());
|
||||||
return opt.matchesHideExpression(c.toString());
|
return opt.matchesHideExpression(c.toString());
|
||||||
|
|
@ -439,8 +439,14 @@ class ClassGraph {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Prints the class if needed */
|
/**
|
||||||
public String printClass(ClassDoc c) {
|
* Prints the class if needed.
|
||||||
|
* <p>
|
||||||
|
* 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;
|
ClassInfo ci;
|
||||||
boolean toPrint;
|
boolean toPrint;
|
||||||
Options opt = optionProvider.getOptionsFor(c);
|
Options opt = optionProvider.getOptionsFor(c);
|
||||||
|
|
@ -458,7 +464,7 @@ class ClassGraph {
|
||||||
w.println("\t// " + r);
|
w.println("\t// " + r);
|
||||||
// Create label
|
// Create label
|
||||||
w.print("\t" + ci.name + " [label=");
|
w.print("\t" + ci.name + " [label=");
|
||||||
externalTableStart(opt, c.qualifiedName(), classToUrl(c));
|
externalTableStart(opt, c.qualifiedName(), classToUrl(c, rootClass));
|
||||||
innerTableStart();
|
innerTableStart();
|
||||||
if (c.isInterface())
|
if (c.isInterface())
|
||||||
tableLine(Align.CENTER, guilWrap(opt, "interface"));
|
tableLine(Align.CENTER, guilWrap(opt, "interface"));
|
||||||
|
|
@ -467,7 +473,12 @@ class ClassGraph {
|
||||||
stereotype(opt, c, Align.CENTER);
|
stereotype(opt, c, Align.CENTER);
|
||||||
Font font = c.isAbstract() && !c.isInterface() ? Font.CLASS_ABSTRACT : Font.CLASS;
|
Font font = c.isAbstract() && !c.isInterface() ? Font.CLASS_ABSTRACT : Font.CLASS;
|
||||||
String qualifiedName = qualifiedName(opt, r);
|
String qualifiedName = qualifiedName(opt, r);
|
||||||
int idx = qualifiedName.lastIndexOf(".");
|
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)) {
|
if(opt.postfixPackage && idx > 0 && idx < (qualifiedName.length() - 1)) {
|
||||||
String packageName = qualifiedName.substring(0, idx);
|
String packageName = qualifiedName.substring(0, idx);
|
||||||
String cn = className.substring(idx + 1);
|
String cn = className.substring(idx + 1);
|
||||||
|
|
@ -611,7 +622,7 @@ class ClassGraph {
|
||||||
/** Print a class's relations */
|
/** Print a class's relations */
|
||||||
public void printRelations(ClassDoc c) {
|
public void printRelations(ClassDoc c) {
|
||||||
Options opt = optionProvider.getOptionsFor(c);
|
Options opt = optionProvider.getOptionsFor(c);
|
||||||
if (hidden(c))
|
if (hidden(c) || c.name().equals("")) // avoid phantom classes, they may pop up when the source uses annotations
|
||||||
return;
|
return;
|
||||||
String className = c.toString();
|
String className = c.toString();
|
||||||
String cs = getNodeName(c);
|
String cs = getNodeName(c);
|
||||||
|
|
@ -639,8 +650,8 @@ class ClassGraph {
|
||||||
for (Type iface : c.interfaceTypes()) {
|
for (Type iface : c.interfaceTypes()) {
|
||||||
ClassDoc ic = iface.asClassDoc();
|
ClassDoc ic = iface.asClassDoc();
|
||||||
if (!hidden(ic)) {
|
if (!hidden(ic)) {
|
||||||
w.println("\t" + getNodeName(ic) + ":p -> " + cs + ":p [dir=back,arrowtail=empty,style=dashed];" +
|
w.println("\t//" + c + " implements " + ic + "\n\t" + getNodeName(ic) + ":p -> " + cs + ":p [dir=back,arrowtail=empty,style=dashed];"
|
||||||
"\t//" + c + " implements " + ic);
|
);
|
||||||
getClassInfo(className).addRelation(ic.toString());
|
getClassInfo(className).addRelation(ic.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -660,7 +671,7 @@ class ClassGraph {
|
||||||
if (!info.nodePrinted) {
|
if (!info.nodePrinted) {
|
||||||
ClassDoc c = root.classNamed(className);
|
ClassDoc c = root.classNamed(className);
|
||||||
if(c != null) {
|
if(c != null) {
|
||||||
printClass(c);
|
printClass(c, false);
|
||||||
} else {
|
} else {
|
||||||
Options opt = optionProvider.getOptionsFor(className);
|
Options opt = optionProvider.getOptionsFor(className);
|
||||||
if(opt.matchesHideExpression(className))
|
if(opt.matchesHideExpression(className))
|
||||||
|
|
@ -711,6 +722,10 @@ class ClassGraph {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (FieldDoc field : c.fields(false)) {
|
for (FieldDoc field : c.fields(false)) {
|
||||||
|
// skip statics
|
||||||
|
if(field.isStatic())
|
||||||
|
continue;
|
||||||
|
|
||||||
// skip primitives
|
// skip primitives
|
||||||
FieldRelationInfo fri = getFieldRelationInfo(field);
|
FieldRelationInfo fri = getFieldRelationInfo(field);
|
||||||
if (fri == null)
|
if (fri == null)
|
||||||
|
|
@ -769,6 +784,12 @@ class ClassGraph {
|
||||||
ParameterizedType pt = c.asParameterizedType();
|
ParameterizedType pt = c.asParameterizedType();
|
||||||
types.addAll(Arrays.asList(pt.typeArguments()));
|
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
|
// and finally check for explicitly imported classes (this
|
||||||
// assumes there are no unused imports...)
|
// assumes there are no unused imports...)
|
||||||
if (opt.useImports)
|
if (opt.useImports)
|
||||||
|
|
@ -779,7 +800,7 @@ class ClassGraph {
|
||||||
// skip primitives and type variables, as well as dependencies
|
// skip primitives and type variables, as well as dependencies
|
||||||
// on the source class
|
// on the source class
|
||||||
if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable
|
if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable
|
||||||
|| c.equals(type.asClassDoc()))
|
|| c.toString().equals(type.asClassDoc().toString()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check if the destination is excluded from inference
|
// check if the destination is excluded from inference
|
||||||
|
|
@ -851,7 +872,7 @@ class ClassGraph {
|
||||||
|
|
||||||
/** Removes the template specs from a class name. */
|
/** Removes the template specs from a class name. */
|
||||||
private String removeTemplate(String name) {
|
private String removeTemplate(String name) {
|
||||||
int openIdx = name.indexOf("<");
|
int openIdx = name.indexOf('<');
|
||||||
if(openIdx == -1)
|
if(openIdx == -1)
|
||||||
return name;
|
return name;
|
||||||
else
|
else
|
||||||
|
|
@ -875,9 +896,9 @@ class ClassGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convert the class name into a corresponding URL */
|
/** Convert the class name into a corresponding URL */
|
||||||
public String classToUrl(ClassDoc cd) {
|
public String classToUrl(ClassDoc cd, boolean rootClass) {
|
||||||
// building relative path for context and package diagrams
|
// building relative path for context and package diagrams
|
||||||
if(contextDoc != null && isSpecifiedPackage(cd)) {
|
if(contextDoc != null && rootClass) {
|
||||||
// determine the context path, relative to the root
|
// determine the context path, relative to the root
|
||||||
String[] contextClassPath = null;
|
String[] contextClassPath = null;
|
||||||
if(contextDoc instanceof ClassDoc) {
|
if(contextDoc instanceof ClassDoc) {
|
||||||
|
|
@ -979,7 +1000,7 @@ class ClassGraph {
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
|
|
||||||
// print plologue
|
// print plologue
|
||||||
w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, opt.outputEncoding)));
|
w = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(fos), opt.outputEncoding));
|
||||||
w.println(
|
w.println(
|
||||||
"#!/usr/local/bin/dot\n" +
|
"#!/usr/local/bin/dot\n" +
|
||||||
"#\n" +
|
"#\n" +
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
package gr.spinellis.umlgraph.doclet;
|
package gr.spinellis.umlgraph.doclet;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
@ -411,7 +411,7 @@ class ClassGraph {
|
||||||
return true;
|
return true;
|
||||||
Options opt;
|
Options opt;
|
||||||
if(c instanceof ClassDoc)
|
if(c instanceof ClassDoc)
|
||||||
opt = optionProvider.getOptionsFor(c.toString());
|
opt = optionProvider.getOptionsFor((ClassDoc) c);
|
||||||
else
|
else
|
||||||
opt = optionProvider.getOptionsFor(c.containingClass());
|
opt = optionProvider.getOptionsFor(c.containingClass());
|
||||||
return opt.matchesHideExpression(c.toString());
|
return opt.matchesHideExpression(c.toString());
|
||||||
|
|
@ -439,8 +439,14 @@ class ClassGraph {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Prints the class if needed */
|
/**
|
||||||
public String printClass(ClassDoc c) {
|
* Prints the class if needed.
|
||||||
|
* <p>
|
||||||
|
* 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;
|
ClassInfo ci;
|
||||||
boolean toPrint;
|
boolean toPrint;
|
||||||
Options opt = optionProvider.getOptionsFor(c);
|
Options opt = optionProvider.getOptionsFor(c);
|
||||||
|
|
@ -458,7 +464,7 @@ class ClassGraph {
|
||||||
w.println("\t// " + r);
|
w.println("\t// " + r);
|
||||||
// Create label
|
// Create label
|
||||||
w.print("\t" + ci.name + " [label=");
|
w.print("\t" + ci.name + " [label=");
|
||||||
externalTableStart(opt, c.qualifiedName(), classToUrl(c));
|
externalTableStart(opt, c.qualifiedName(), classToUrl(c, rootClass));
|
||||||
innerTableStart();
|
innerTableStart();
|
||||||
if (c.isInterface())
|
if (c.isInterface())
|
||||||
tableLine(Align.CENTER, guilWrap(opt, "interface"));
|
tableLine(Align.CENTER, guilWrap(opt, "interface"));
|
||||||
|
|
@ -467,7 +473,12 @@ class ClassGraph {
|
||||||
stereotype(opt, c, Align.CENTER);
|
stereotype(opt, c, Align.CENTER);
|
||||||
Font font = c.isAbstract() && !c.isInterface() ? Font.CLASS_ABSTRACT : Font.CLASS;
|
Font font = c.isAbstract() && !c.isInterface() ? Font.CLASS_ABSTRACT : Font.CLASS;
|
||||||
String qualifiedName = qualifiedName(opt, r);
|
String qualifiedName = qualifiedName(opt, r);
|
||||||
int idx = qualifiedName.lastIndexOf(".");
|
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)) {
|
if(opt.postfixPackage && idx > 0 && idx < (qualifiedName.length() - 1)) {
|
||||||
String packageName = qualifiedName.substring(0, idx);
|
String packageName = qualifiedName.substring(0, idx);
|
||||||
String cn = className.substring(idx + 1);
|
String cn = className.substring(idx + 1);
|
||||||
|
|
@ -611,7 +622,7 @@ class ClassGraph {
|
||||||
/** Print a class's relations */
|
/** Print a class's relations */
|
||||||
public void printRelations(ClassDoc c) {
|
public void printRelations(ClassDoc c) {
|
||||||
Options opt = optionProvider.getOptionsFor(c);
|
Options opt = optionProvider.getOptionsFor(c);
|
||||||
if (hidden(c))
|
if (hidden(c) || c.name().equals("")) // avoid phantom classes, they may pop up when the source uses annotations
|
||||||
return;
|
return;
|
||||||
String className = c.toString();
|
String className = c.toString();
|
||||||
String cs = getNodeName(c);
|
String cs = getNodeName(c);
|
||||||
|
|
@ -639,8 +650,8 @@ class ClassGraph {
|
||||||
for (Type iface : c.interfaceTypes()) {
|
for (Type iface : c.interfaceTypes()) {
|
||||||
ClassDoc ic = iface.asClassDoc();
|
ClassDoc ic = iface.asClassDoc();
|
||||||
if (!hidden(ic)) {
|
if (!hidden(ic)) {
|
||||||
w.println("\t" + getNodeName(ic) + ":p -> " + cs + ":p [dir=back,arrowtail=empty,style=dashed];" +
|
w.println("\t//" + c + " implements " + ic + "\n\t" + getNodeName(ic) + ":p -> " + cs + ":p [dir=back,arrowtail=empty,style=dashed];"
|
||||||
"\t//" + c + " implements " + ic);
|
);
|
||||||
getClassInfo(className).addRelation(ic.toString());
|
getClassInfo(className).addRelation(ic.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -660,7 +671,7 @@ class ClassGraph {
|
||||||
if (!info.nodePrinted) {
|
if (!info.nodePrinted) {
|
||||||
ClassDoc c = root.classNamed(className);
|
ClassDoc c = root.classNamed(className);
|
||||||
if(c != null) {
|
if(c != null) {
|
||||||
printClass(c);
|
printClass(c, false);
|
||||||
} else {
|
} else {
|
||||||
Options opt = optionProvider.getOptionsFor(className);
|
Options opt = optionProvider.getOptionsFor(className);
|
||||||
if(opt.matchesHideExpression(className))
|
if(opt.matchesHideExpression(className))
|
||||||
|
|
@ -711,6 +722,10 @@ class ClassGraph {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (FieldDoc field : c.fields(false)) {
|
for (FieldDoc field : c.fields(false)) {
|
||||||
|
// skip statics
|
||||||
|
if(field.isStatic())
|
||||||
|
continue;
|
||||||
|
|
||||||
// skip primitives
|
// skip primitives
|
||||||
FieldRelationInfo fri = getFieldRelationInfo(field);
|
FieldRelationInfo fri = getFieldRelationInfo(field);
|
||||||
if (fri == null)
|
if (fri == null)
|
||||||
|
|
@ -769,6 +784,12 @@ class ClassGraph {
|
||||||
ParameterizedType pt = c.asParameterizedType();
|
ParameterizedType pt = c.asParameterizedType();
|
||||||
types.addAll(Arrays.asList(pt.typeArguments()));
|
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
|
// and finally check for explicitly imported classes (this
|
||||||
// assumes there are no unused imports...)
|
// assumes there are no unused imports...)
|
||||||
if (opt.useImports)
|
if (opt.useImports)
|
||||||
|
|
@ -779,7 +800,7 @@ class ClassGraph {
|
||||||
// skip primitives and type variables, as well as dependencies
|
// skip primitives and type variables, as well as dependencies
|
||||||
// on the source class
|
// on the source class
|
||||||
if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable
|
if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable
|
||||||
|| c.equals(type.asClassDoc()))
|
|| c.toString().equals(type.asClassDoc().toString()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check if the destination is excluded from inference
|
// check if the destination is excluded from inference
|
||||||
|
|
@ -851,7 +872,7 @@ class ClassGraph {
|
||||||
|
|
||||||
/** Removes the template specs from a class name. */
|
/** Removes the template specs from a class name. */
|
||||||
private String removeTemplate(String name) {
|
private String removeTemplate(String name) {
|
||||||
int openIdx = name.indexOf("<");
|
int openIdx = name.indexOf('<');
|
||||||
if(openIdx == -1)
|
if(openIdx == -1)
|
||||||
return name;
|
return name;
|
||||||
else
|
else
|
||||||
|
|
@ -875,9 +896,9 @@ class ClassGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convert the class name into a corresponding URL */
|
/** Convert the class name into a corresponding URL */
|
||||||
public String classToUrl(ClassDoc cd) {
|
public String classToUrl(ClassDoc cd, boolean rootClass) {
|
||||||
// building relative path for context and package diagrams
|
// building relative path for context and package diagrams
|
||||||
if(contextDoc != null && isSpecifiedPackage(cd)) {
|
if(contextDoc != null && rootClass) {
|
||||||
// determine the context path, relative to the root
|
// determine the context path, relative to the root
|
||||||
String[] contextClassPath = null;
|
String[] contextClassPath = null;
|
||||||
if(contextDoc instanceof ClassDoc) {
|
if(contextDoc instanceof ClassDoc) {
|
||||||
|
|
@ -979,7 +1000,7 @@ class ClassGraph {
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
|
|
||||||
// print plologue
|
// print plologue
|
||||||
w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, opt.outputEncoding)));
|
w = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(fos), opt.outputEncoding));
|
||||||
w.println(
|
w.println(
|
||||||
"#!/usr/local/bin/dot\n" +
|
"#!/usr/local/bin/dot\n" +
|
||||||
"#\n" +
|
"#\n" +
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue