mirror of https://github.com/dspinellis/UMLGraph
View support code
This commit is contained in:
parent
7fe982d20e
commit
956673ffb7
|
|
@ -60,6 +60,9 @@ class Options implements Cloneable {
|
|||
String apiDocMapFileName;
|
||||
String apiDocRoot;
|
||||
boolean useGuillemot;
|
||||
boolean findViews;
|
||||
String viewName;
|
||||
String outputDirectory;
|
||||
/** Guillemot left (open) */
|
||||
String guilOpen = "\u00ab";
|
||||
/** Guillemot right (close) */
|
||||
|
|
@ -90,6 +93,8 @@ class Options implements Cloneable {
|
|||
apiDocMapFileName = null;
|
||||
apiDocRoot = null;
|
||||
useGuillemot = true;
|
||||
findViews = false;
|
||||
viewName = null;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
|
|
@ -127,7 +132,10 @@ class Options implements Cloneable {
|
|||
option.equals("-visibility") ||
|
||||
option.equals("-types") ||
|
||||
option.equals("-all") ||
|
||||
option.equals("-noguillemot"))
|
||||
option.equals("-noguillemot") ||
|
||||
option.equals("-hideall") ||
|
||||
option.equals("-views"))
|
||||
|
||||
return 1;
|
||||
else if(option.equals("-nodefillcolor") ||
|
||||
option.equals("-nodefontcolor") ||
|
||||
|
|
@ -143,14 +151,82 @@ class Options implements Cloneable {
|
|||
option.equals("-bgcolor") ||
|
||||
option.equals("-hide") ||
|
||||
option.equals("-apidocroot") ||
|
||||
option.equals("-apidocmap"))
|
||||
option.equals("-apidocmap") ||
|
||||
option.equals("-d") ||
|
||||
option.equals("-view"))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Resets the specified option to its default value */
|
||||
void resetOption(String[] opt) {
|
||||
if (opt[0].equals("-qualify")) {
|
||||
showQualified = false;
|
||||
} else if (opt[0].equals("-horizontal")) {
|
||||
horizontal = false;
|
||||
} else if (opt[0].equals("-attributes")) {
|
||||
showAttributes = false;
|
||||
} else if (opt[0].equals("-enumconstants")) {
|
||||
showEnumConstants = false;
|
||||
} else if (opt[0].equals("-operations")) {
|
||||
showOperations = false;
|
||||
} else if (opt[0].equals("-enumerations")) {
|
||||
showEnumerations = false;
|
||||
} else if (opt[0].equals("-constructors")) {
|
||||
showConstructors = false;
|
||||
} else if (opt[0].equals("-visibility")) {
|
||||
showVisibility = false;
|
||||
} else if (opt[0].equals("-types")) {
|
||||
showType = false;
|
||||
} else if (opt[0].equals("-bgcolor")) {
|
||||
bgColor = null;
|
||||
} else if (opt[0].equals("-edgecolor")) {
|
||||
edgeColor = "black";
|
||||
} else if (opt[0].equals("-edgefontcolor")) {
|
||||
edgeFontColor = "black";
|
||||
} else if (opt[0].equals("-edgefontname")) {
|
||||
edgeFontName = "Helvetica";
|
||||
} else if (opt[0].equals("-edgefontsize")) {
|
||||
edgeFontSize = 10;
|
||||
} else if (opt[0].equals("-nodefontcolor")) {
|
||||
nodeFontColor = "black";
|
||||
} else if (opt[0].equals("-nodefontname")) {
|
||||
nodeFontName = "Helvetica";
|
||||
} else if (opt[0].equals("-nodefontabstractname")) {
|
||||
nodeFontAbstractName = "Helvetica-Oblique";
|
||||
} else if (opt[0].equals("-nodefontsize")) {
|
||||
nodeFontSize = 10;
|
||||
} else if (opt[0].equals("-nodefillcolor")) {
|
||||
nodeFillColor = null;
|
||||
} else if (opt[0].equals("-output")) {
|
||||
outputFileName = "graph.dot";
|
||||
} else if (opt[0].equals("-outputencoding")) {
|
||||
outputEncoding = "ISO-8859-1";
|
||||
} else if (opt[0].equals("-hide")) {
|
||||
new Vector<Pattern>();
|
||||
} else if (opt[0].equals("-apidocroot")) {
|
||||
apiDocRoot = null;
|
||||
} else if (opt[0].equals("-apidocmap")) {
|
||||
apiDocMapFileName = null;
|
||||
} else if (opt[0].equals("-noguillemot")) {
|
||||
guilOpen = "\u00ab";
|
||||
guilClose = "\u00bb";
|
||||
} else if (opt[0].equals("-view")) {
|
||||
viewName = null;
|
||||
} else if (opt[0].equals("-views")) {
|
||||
findViews = false;
|
||||
} else if (opt[0].equals("-d")) {
|
||||
outputDirectory = null;
|
||||
} else if (opt[0].equals("-hideall")) {
|
||||
hidePatterns.clear();
|
||||
} else
|
||||
; // Do nothing, javadoc will handle the option or complain, if
|
||||
// needed.
|
||||
}
|
||||
|
||||
/** Set the options based on a lingle option and its arguments */
|
||||
private void setOption(String[] opt) {
|
||||
void setOption(String[] opt) {
|
||||
if(opt[0].equals("-qualify")) {
|
||||
showQualified = true;
|
||||
} else if(opt[0].equals("-horizontal")) {
|
||||
|
|
@ -195,6 +271,8 @@ class Options implements Cloneable {
|
|||
outputFileName = opt[1];
|
||||
} else if(opt[0].equals("-outputencoding")) {
|
||||
outputEncoding = opt[1];
|
||||
} else if(opt[0].equals("-hideall")) {
|
||||
hidePatterns.add(Pattern.compile(".*"));
|
||||
} else if(opt[0].equals("-hide")) {
|
||||
try {
|
||||
hidePatterns.add(Pattern.compile(opt[1]));
|
||||
|
|
@ -208,6 +286,12 @@ class Options implements Cloneable {
|
|||
} else if(opt[0].equals("-noguillemot")) {
|
||||
guilOpen = "\\<\\<";
|
||||
guilClose = "\\>\\>";
|
||||
} else if (opt[0].equals("-view")) {
|
||||
viewName = opt[1];
|
||||
} else if (opt[0].equals("-views")) {
|
||||
findViews = true;
|
||||
} else if (opt[0].equals("-d")) {
|
||||
outputDirectory = opt[1];
|
||||
} else
|
||||
; // Do nothing, javadoc will handle the option or complain, if needed.
|
||||
}
|
||||
|
|
@ -235,6 +319,11 @@ class Options implements Cloneable {
|
|||
FileOutputStream fos = new FileOutputStream(outputFileName);
|
||||
w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, outputEncoding)));
|
||||
}
|
||||
|
||||
public void closeFile() {
|
||||
w.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the supplied string matches an entity specified
|
||||
|
|
|
|||
|
|
@ -20,9 +20,13 @@
|
|||
|
||||
package gr.spinellis.umlgraph.doclet;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.LanguageVersion;
|
||||
import com.sun.javadoc.RootDoc;
|
||||
|
||||
/**
|
||||
* Doclet API implementation
|
||||
|
|
@ -37,34 +41,80 @@ public class UmlGraph {
|
|||
/** Entry point */
|
||||
public static boolean start(RootDoc root) throws IOException {
|
||||
Options opt = new Options();
|
||||
ClassInfo.reset();
|
||||
|
||||
opt.setOptions(root.options());
|
||||
opt.openFile();
|
||||
opt.setOptions(root.classNamed("UMLOptions"));
|
||||
|
||||
View[] views = buildViews(opt, root);
|
||||
if (views.length == 0) {
|
||||
buildGraph(root, null, opt);
|
||||
} else {
|
||||
for (int i = 0; i < views.length; i++) {
|
||||
buildGraph(root, views[i], (Options) opt.clone());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and outputs a single graph according to the view overrides
|
||||
*/
|
||||
private static void buildGraph(RootDoc root, View view, Options opt) throws IOException {
|
||||
if (view != null)
|
||||
view.applyOverrides(opt);
|
||||
opt.openFile();
|
||||
prologue(opt);
|
||||
ClassDoc[] classes = root.classes();
|
||||
|
||||
ClassGraph c = new ClassGraph(root.specifiedPackages(),
|
||||
opt.apiDocRoot, opt.apiDocMapFileName);
|
||||
for (ClassDoc cd : classes) {
|
||||
ClassGraph c = new ClassGraph(root.specifiedPackages(), opt.apiDocRoot,
|
||||
opt.apiDocMapFileName);
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
// Process class-local options (through @opt tags)
|
||||
Options localOpt = (Options) opt.clone();
|
||||
localOpt.setOptions(cd);
|
||||
c.printClass(localOpt, cd);
|
||||
localOpt.setOptions(classes[i]);
|
||||
if (view != null)
|
||||
view.applyOverrides(localOpt, classes[i]);
|
||||
c.printClass(localOpt, classes[i]);
|
||||
}
|
||||
for (ClassDoc cd : classes) {
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
// Process class-local options (through @opt tags)
|
||||
Options localOpt = (Options) opt.clone();
|
||||
localOpt.setOptions(cd);
|
||||
c.printRelations(localOpt, cd);
|
||||
localOpt.setOptions(classes[i]);
|
||||
if (view != null)
|
||||
view.applyOverrides(localOpt, classes[i]);
|
||||
c.printRelations(localOpt, classes[i]);
|
||||
}
|
||||
|
||||
c.printExtraClasses(opt, root);
|
||||
epilogue(opt);
|
||||
return true;
|
||||
opt.closeFile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Builds the views according to the parameters on the command line
|
||||
*/
|
||||
private static View[] buildViews(Options opt, RootDoc root) {
|
||||
if (opt.findViews) {
|
||||
List<View> views = new ArrayList<View>();
|
||||
ClassDoc[] classes = root.classes();
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
if (classes[i].tags("view").length > 0) {
|
||||
views.add(new View(classes[i]));
|
||||
}
|
||||
}
|
||||
return views.toArray(new View[views.size()]);
|
||||
} else if (opt.viewName != null) {
|
||||
ClassDoc viewClass = root.classNamed(opt.viewName);
|
||||
return new View[] { new View(viewClass) };
|
||||
} else {
|
||||
return new View[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Option checking */
|
||||
public static int optionLength(String option) {
|
||||
return Options.optionLength(option);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.File;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
class View {
|
||||
Map<Pattern, String[]> optionOverrides = new LinkedHashMap<Pattern, String[]>();
|
||||
ClassDoc viewDoc;
|
||||
|
||||
public View(ClassDoc c) {
|
||||
this.viewDoc = c;
|
||||
Tag[] tags = c.tags("opt_override");
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
String[] opts = StringUtil.tokenize(tags[i].text());
|
||||
try {
|
||||
optionOverrides.put(Pattern.compile(opts[0]), opts);
|
||||
} catch (PatternSyntaxException e) {
|
||||
System.err.println("Skipping invalid pattern " + opts[0] + " in view "
|
||||
+ c.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies global view overrides
|
||||
*/
|
||||
public void applyOverrides(Options o) {
|
||||
o.setOptions(viewDoc);
|
||||
File dotFile = new File(o.outputDirectory, viewDoc.name() + ".dot");
|
||||
o.setOption(new String[] {"-output", dotFile.getPath()});
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies local view overrides
|
||||
*/
|
||||
public void applyOverrides(Options o, ClassDoc c) {
|
||||
String className = c.toString();
|
||||
for (Iterator<Map.Entry<Pattern, String[]>> iter = optionOverrides.entrySet().iterator(); iter
|
||||
.hasNext();) {
|
||||
Map.Entry<Pattern, String[]> mapEntry = iter.next();
|
||||
Pattern regex = mapEntry.getKey();
|
||||
Matcher matcher = regex.matcher(className);
|
||||
if (matcher.matches()) {
|
||||
String[] overrides = mapEntry.getValue(); // the first element is in fact the pattern
|
||||
for (int i = 1; i < overrides.length; i++) {
|
||||
String[] option = null;
|
||||
boolean reset = false;
|
||||
if (overrides[i].contains("=")) {
|
||||
option = overrides[i].split("=");
|
||||
} else {
|
||||
option = new String[] { overrides[i] };
|
||||
}
|
||||
if (option[0].charAt(0) == '!') {
|
||||
reset = true;
|
||||
option[0] = option[0].substring(1);
|
||||
}
|
||||
option[0] = "-" + option[0];
|
||||
if (reset) {
|
||||
o.resetOption(option);
|
||||
} else {
|
||||
o.setOption(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,9 @@ class Options implements Cloneable {
|
|||
String apiDocMapFileName;
|
||||
String apiDocRoot;
|
||||
boolean useGuillemot;
|
||||
boolean findViews;
|
||||
String viewName;
|
||||
String outputDirectory;
|
||||
/** Guillemot left (open) */
|
||||
String guilOpen = "\u00ab";
|
||||
/** Guillemot right (close) */
|
||||
|
|
@ -90,6 +93,8 @@ class Options implements Cloneable {
|
|||
apiDocMapFileName = null;
|
||||
apiDocRoot = null;
|
||||
useGuillemot = true;
|
||||
findViews = false;
|
||||
viewName = null;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
|
|
@ -127,7 +132,10 @@ class Options implements Cloneable {
|
|||
option.equals("-visibility") ||
|
||||
option.equals("-types") ||
|
||||
option.equals("-all") ||
|
||||
option.equals("-noguillemot"))
|
||||
option.equals("-noguillemot") ||
|
||||
option.equals("-hideall") ||
|
||||
option.equals("-views"))
|
||||
|
||||
return 1;
|
||||
else if(option.equals("-nodefillcolor") ||
|
||||
option.equals("-nodefontcolor") ||
|
||||
|
|
@ -143,14 +151,82 @@ class Options implements Cloneable {
|
|||
option.equals("-bgcolor") ||
|
||||
option.equals("-hide") ||
|
||||
option.equals("-apidocroot") ||
|
||||
option.equals("-apidocmap"))
|
||||
option.equals("-apidocmap") ||
|
||||
option.equals("-d") ||
|
||||
option.equals("-view"))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Resets the specified option to its default value */
|
||||
void resetOption(String[] opt) {
|
||||
if (opt[0].equals("-qualify")) {
|
||||
showQualified = false;
|
||||
} else if (opt[0].equals("-horizontal")) {
|
||||
horizontal = false;
|
||||
} else if (opt[0].equals("-attributes")) {
|
||||
showAttributes = false;
|
||||
} else if (opt[0].equals("-enumconstants")) {
|
||||
showEnumConstants = false;
|
||||
} else if (opt[0].equals("-operations")) {
|
||||
showOperations = false;
|
||||
} else if (opt[0].equals("-enumerations")) {
|
||||
showEnumerations = false;
|
||||
} else if (opt[0].equals("-constructors")) {
|
||||
showConstructors = false;
|
||||
} else if (opt[0].equals("-visibility")) {
|
||||
showVisibility = false;
|
||||
} else if (opt[0].equals("-types")) {
|
||||
showType = false;
|
||||
} else if (opt[0].equals("-bgcolor")) {
|
||||
bgColor = null;
|
||||
} else if (opt[0].equals("-edgecolor")) {
|
||||
edgeColor = "black";
|
||||
} else if (opt[0].equals("-edgefontcolor")) {
|
||||
edgeFontColor = "black";
|
||||
} else if (opt[0].equals("-edgefontname")) {
|
||||
edgeFontName = "Helvetica";
|
||||
} else if (opt[0].equals("-edgefontsize")) {
|
||||
edgeFontSize = 10;
|
||||
} else if (opt[0].equals("-nodefontcolor")) {
|
||||
nodeFontColor = "black";
|
||||
} else if (opt[0].equals("-nodefontname")) {
|
||||
nodeFontName = "Helvetica";
|
||||
} else if (opt[0].equals("-nodefontabstractname")) {
|
||||
nodeFontAbstractName = "Helvetica-Oblique";
|
||||
} else if (opt[0].equals("-nodefontsize")) {
|
||||
nodeFontSize = 10;
|
||||
} else if (opt[0].equals("-nodefillcolor")) {
|
||||
nodeFillColor = null;
|
||||
} else if (opt[0].equals("-output")) {
|
||||
outputFileName = "graph.dot";
|
||||
} else if (opt[0].equals("-outputencoding")) {
|
||||
outputEncoding = "ISO-8859-1";
|
||||
} else if (opt[0].equals("-hide")) {
|
||||
new Vector<Pattern>();
|
||||
} else if (opt[0].equals("-apidocroot")) {
|
||||
apiDocRoot = null;
|
||||
} else if (opt[0].equals("-apidocmap")) {
|
||||
apiDocMapFileName = null;
|
||||
} else if (opt[0].equals("-noguillemot")) {
|
||||
guilOpen = "\u00ab";
|
||||
guilClose = "\u00bb";
|
||||
} else if (opt[0].equals("-view")) {
|
||||
viewName = null;
|
||||
} else if (opt[0].equals("-views")) {
|
||||
findViews = false;
|
||||
} else if (opt[0].equals("-d")) {
|
||||
outputDirectory = null;
|
||||
} else if (opt[0].equals("-hideall")) {
|
||||
hidePatterns.clear();
|
||||
} else
|
||||
; // Do nothing, javadoc will handle the option or complain, if
|
||||
// needed.
|
||||
}
|
||||
|
||||
/** Set the options based on a lingle option and its arguments */
|
||||
private void setOption(String[] opt) {
|
||||
void setOption(String[] opt) {
|
||||
if(opt[0].equals("-qualify")) {
|
||||
showQualified = true;
|
||||
} else if(opt[0].equals("-horizontal")) {
|
||||
|
|
@ -195,6 +271,8 @@ class Options implements Cloneable {
|
|||
outputFileName = opt[1];
|
||||
} else if(opt[0].equals("-outputencoding")) {
|
||||
outputEncoding = opt[1];
|
||||
} else if(opt[0].equals("-hideall")) {
|
||||
hidePatterns.add(Pattern.compile(".*"));
|
||||
} else if(opt[0].equals("-hide")) {
|
||||
try {
|
||||
hidePatterns.add(Pattern.compile(opt[1]));
|
||||
|
|
@ -208,6 +286,12 @@ class Options implements Cloneable {
|
|||
} else if(opt[0].equals("-noguillemot")) {
|
||||
guilOpen = "\\<\\<";
|
||||
guilClose = "\\>\\>";
|
||||
} else if (opt[0].equals("-view")) {
|
||||
viewName = opt[1];
|
||||
} else if (opt[0].equals("-views")) {
|
||||
findViews = true;
|
||||
} else if (opt[0].equals("-d")) {
|
||||
outputDirectory = opt[1];
|
||||
} else
|
||||
; // Do nothing, javadoc will handle the option or complain, if needed.
|
||||
}
|
||||
|
|
@ -235,6 +319,11 @@ class Options implements Cloneable {
|
|||
FileOutputStream fos = new FileOutputStream(outputFileName);
|
||||
w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, outputEncoding)));
|
||||
}
|
||||
|
||||
public void closeFile() {
|
||||
w.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the supplied string matches an entity specified
|
||||
|
|
|
|||
|
|
@ -20,9 +20,13 @@
|
|||
|
||||
package gr.spinellis.umlgraph.doclet;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.LanguageVersion;
|
||||
import com.sun.javadoc.RootDoc;
|
||||
|
||||
/**
|
||||
* Doclet API implementation
|
||||
|
|
@ -37,34 +41,80 @@ public class UmlGraph {
|
|||
/** Entry point */
|
||||
public static boolean start(RootDoc root) throws IOException {
|
||||
Options opt = new Options();
|
||||
ClassInfo.reset();
|
||||
|
||||
opt.setOptions(root.options());
|
||||
opt.openFile();
|
||||
opt.setOptions(root.classNamed("UMLOptions"));
|
||||
|
||||
View[] views = buildViews(opt, root);
|
||||
if (views.length == 0) {
|
||||
buildGraph(root, null, opt);
|
||||
} else {
|
||||
for (int i = 0; i < views.length; i++) {
|
||||
buildGraph(root, views[i], (Options) opt.clone());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and outputs a single graph according to the view overrides
|
||||
*/
|
||||
private static void buildGraph(RootDoc root, View view, Options opt) throws IOException {
|
||||
if (view != null)
|
||||
view.applyOverrides(opt);
|
||||
opt.openFile();
|
||||
prologue(opt);
|
||||
ClassDoc[] classes = root.classes();
|
||||
|
||||
ClassGraph c = new ClassGraph(root.specifiedPackages(),
|
||||
opt.apiDocRoot, opt.apiDocMapFileName);
|
||||
for (ClassDoc cd : classes) {
|
||||
ClassGraph c = new ClassGraph(root.specifiedPackages(), opt.apiDocRoot,
|
||||
opt.apiDocMapFileName);
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
// Process class-local options (through @opt tags)
|
||||
Options localOpt = (Options) opt.clone();
|
||||
localOpt.setOptions(cd);
|
||||
c.printClass(localOpt, cd);
|
||||
localOpt.setOptions(classes[i]);
|
||||
if (view != null)
|
||||
view.applyOverrides(localOpt, classes[i]);
|
||||
c.printClass(localOpt, classes[i]);
|
||||
}
|
||||
for (ClassDoc cd : classes) {
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
// Process class-local options (through @opt tags)
|
||||
Options localOpt = (Options) opt.clone();
|
||||
localOpt.setOptions(cd);
|
||||
c.printRelations(localOpt, cd);
|
||||
localOpt.setOptions(classes[i]);
|
||||
if (view != null)
|
||||
view.applyOverrides(localOpt, classes[i]);
|
||||
c.printRelations(localOpt, classes[i]);
|
||||
}
|
||||
|
||||
c.printExtraClasses(opt, root);
|
||||
epilogue(opt);
|
||||
return true;
|
||||
opt.closeFile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Builds the views according to the parameters on the command line
|
||||
*/
|
||||
private static View[] buildViews(Options opt, RootDoc root) {
|
||||
if (opt.findViews) {
|
||||
List<View> views = new ArrayList<View>();
|
||||
ClassDoc[] classes = root.classes();
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
if (classes[i].tags("view").length > 0) {
|
||||
views.add(new View(classes[i]));
|
||||
}
|
||||
}
|
||||
return views.toArray(new View[views.size()]);
|
||||
} else if (opt.viewName != null) {
|
||||
ClassDoc viewClass = root.classNamed(opt.viewName);
|
||||
return new View[] { new View(viewClass) };
|
||||
} else {
|
||||
return new View[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Option checking */
|
||||
public static int optionLength(String option) {
|
||||
return Options.optionLength(option);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.File;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
class View {
|
||||
Map<Pattern, String[]> optionOverrides = new LinkedHashMap<Pattern, String[]>();
|
||||
ClassDoc viewDoc;
|
||||
|
||||
public View(ClassDoc c) {
|
||||
this.viewDoc = c;
|
||||
Tag[] tags = c.tags("opt_override");
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
String[] opts = StringUtil.tokenize(tags[i].text());
|
||||
try {
|
||||
optionOverrides.put(Pattern.compile(opts[0]), opts);
|
||||
} catch (PatternSyntaxException e) {
|
||||
System.err.println("Skipping invalid pattern " + opts[0] + " in view "
|
||||
+ c.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies global view overrides
|
||||
*/
|
||||
public void applyOverrides(Options o) {
|
||||
o.setOptions(viewDoc);
|
||||
File dotFile = new File(o.outputDirectory, viewDoc.name() + ".dot");
|
||||
o.setOption(new String[] {"-output", dotFile.getPath()});
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies local view overrides
|
||||
*/
|
||||
public void applyOverrides(Options o, ClassDoc c) {
|
||||
String className = c.toString();
|
||||
for (Iterator<Map.Entry<Pattern, String[]>> iter = optionOverrides.entrySet().iterator(); iter
|
||||
.hasNext();) {
|
||||
Map.Entry<Pattern, String[]> mapEntry = iter.next();
|
||||
Pattern regex = mapEntry.getKey();
|
||||
Matcher matcher = regex.matcher(className);
|
||||
if (matcher.matches()) {
|
||||
String[] overrides = mapEntry.getValue(); // the first element is in fact the pattern
|
||||
for (int i = 1; i < overrides.length; i++) {
|
||||
String[] option = null;
|
||||
boolean reset = false;
|
||||
if (overrides[i].contains("=")) {
|
||||
option = overrides[i].split("=");
|
||||
} else {
|
||||
option = new String[] { overrides[i] };
|
||||
}
|
||||
if (option[0].charAt(0) == '!') {
|
||||
reset = true;
|
||||
option[0] = option[0].substring(1);
|
||||
}
|
||||
option[0] = "-" + option[0];
|
||||
if (reset) {
|
||||
o.resetOption(option);
|
||||
} else {
|
||||
o.setOption(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue