8274311: Make build.tools.jigsaw.GenGraphs more configurable

Reviewed-by: alanb, iris
This commit is contained in:
Mandy Chung 2021-09-27 16:56:33 +00:00
parent 2cffe4c8e0
commit daaa47e200
3 changed files with 133 additions and 66 deletions

View File

@ -36,6 +36,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -115,102 +116,112 @@ public class GenGraphs {
/**
* Custom dot file attributes.
*/
static class ModuleGraphAttributes implements ModuleDotGraph.Attributes {
static Map<String, String> DEFAULT_ATTRIBUTES = Map.of(
"ranksep", "0.6",
"fontsize", "12",
"fontcolor", BLACK,
"fontname", "DejaVuSans",
"arrowsize", "1",
"arrowwidth", "2",
"arrowcolor", DARK_GRAY,
// custom
"requiresMandatedColor", LIGHT_GRAY,
"javaSubgraphColor", ORANGE,
"jdkSubgraphColor", BLUE
);
final Map<String, Integer> weights = new HashMap<>();
final List<Set<String>> ranks = new ArrayList<>();
final Map<String, String> attrs;
ModuleGraphAttributes(Map<String, String> attrs) {
int h = 1000;
weight("java.se", "java.sql.rowset", h * 10);
weight("java.sql.rowset", "java.sql", h * 10);
weight("java.sql", "java.xml", h * 10);
weight("java.xml", "java.base", h * 10);
ranks.add(Set.of("java.logging", "java.scripting", "java.xml"));
ranks.add(Set.of("java.sql"));
ranks.add(Set.of("java.transaction.xa"));
ranks.add(Set.of("java.compiler", "java.instrument"));
ranks.add(Set.of("java.desktop", "java.management"));
this.attrs = attrs;
}
static class ModuleGraphAttributes extends ModuleDotGraph.DotGraphAttributes {
final Properties attrs;
final Map<String, Integer> weights;
ModuleGraphAttributes() {
this(DEFAULT_ATTRIBUTES);
}
this(new Properties());
};
ModuleGraphAttributes(Properties props) {
this(toAttributes(props));
this.attrs = props;
this.weights = initWeights(props);
}
@Override
public double nodeSep() {
String v = attrs.getProperty("nodesep");
return v != null ? Double.valueOf(v) : super.nodeSep();
}
@Override
public double rankSep() {
return Double.valueOf(attrs.get("ranksep"));
String v = attrs.getProperty("ranksep");
return v != null ? Double.valueOf(v) : super.rankSep();
}
@Override
public int fontSize() {
return Integer.valueOf(attrs.get("fontsize"));
String v = attrs.getProperty("fontsize");
return v != null ? Integer.valueOf(v) : super.fontSize();
}
@Override
public String fontName() {
return attrs.get("fontname");
String v = attrs.getProperty("fontname");
return v != null ? v : super.fontName();
}
@Override
public String fontColor() {
return attrs.get("fontcolor");
String v = attrs.getProperty("fontcolor");
return v != null ? v : super.fontColor();
}
@Override
public int arrowSize() {
return Integer.valueOf(attrs.get("arrowsize"));
String v = attrs.getProperty("arrowsize");
return v != null ? Integer.valueOf(v) : super.arrowSize();
}
@Override
public int arrowWidth() {
return Integer.valueOf(attrs.get("arrowwidth"));
String v = attrs.getProperty("arrowwidth");
return v != null ? Integer.valueOf(v) : super.arrowWidth();
}
@Override
public String arrowColor() {
return attrs.get("arrowcolor");
String v = attrs.getProperty("arrowcolor");
return v != null ? v : super.arrowColor();
}
@Override
public List<Set<String>> ranks() {
return ranks;
return attrs.stringPropertyNames().stream()
.filter(k -> k.startsWith("ranks."))
.sorted()
.map(k -> Arrays.stream(attrs.getProperty(k).split(","))
.collect(Collectors.toSet()))
.toList();
}
@Override
public String requiresMandatedColor() {
return attrs.get("requiresMandatedColor");
String v = attrs.getProperty("requiresMandatedColor");
return v != null ? v : super.requiresMandatedColor();
}
@Override
public String javaSubgraphColor() {
return attrs.get("javaSubgraphColor");
String v = attrs.getProperty("javaSubgraphColor");
return v != null ? v : super.javaSubgraphColor();
}
@Override
public String jdkSubgraphColor() {
return attrs.get("jdkSubgraphColor");
String v = attrs.getProperty("jdkSubgraphColor");
return v != null ? v : super.jdkSubgraphColor();
}
@Override
public String nodeMargin() {
String v = attrs.getProperty("node-margin");
return v != null ? v : super.nodeMargin();
}
@Override
public String requiresStyle() {
String v = attrs.getProperty("requiresStyle");
return v != null ? v : super.requiresStyle();
};
@Override
public String requiresTransitiveStyle() {
String v = attrs.getProperty("requiresTransitiveStyle");
return v != null ? v : super.requiresTransitiveStyle();
};
@Override
public int weightOf(String s, String t) {
int w = weights.getOrDefault(s + ":" + t, 1);
@ -221,14 +232,25 @@ public class GenGraphs {
return 1;
}
public void weight(String s, String t, int w) {
weights.put(s + ":" + t, w);
}
/*
* Create a map of <mn>:<dep> with a weight trying to line up
* the modules in the weights property in the specified order.
*/
public static Map<String, Integer> initWeights(Properties props) {
String[] modules = props.getProperty("weights", "").split(",");
int len = modules.length;
if (len == 0) return Map.of();
static Map<String, String> toAttributes(Properties props) {
return DEFAULT_ATTRIBUTES.keySet().stream()
.collect(Collectors.toMap(Function.identity(),
k -> props.getProperty(k, DEFAULT_ATTRIBUTES.get(k))));
Map<String, Integer> weights = new HashMap<>();
String mn = modules[0];
int w = 10000;
for (int i = 1; i < len; i++) {
String dep = modules[i];
weights.put(mn + ":" + dep, w);
mn = dep;
}
weights.put(mn + ":java.base", w);
return weights;
}
}

View File

@ -1,2 +1,35 @@
# Configuration file for build.tools.jigsaw.GenGraphs
nodesep=.5
node-margin=.2,.2
ranksep=0.6
fontsize=12
fontcolor=#000000
fontname=DejaVuSans
arrowsize=1
arrowwidth=2
# requires edge: gray
arrowcolor=#999999
requiresMandatedColor=#999999
# requires mandated java.base edge: light gray
requiresMandatedColor=#dddddd
requiresTransitiveStyle=
requiresStyle=dashed
# java.* modules: orange
javaSubgraphColor=#e76f00
# jdk.* modules: blue
jdkSubgraphColor=#437291
# configure the group of modules in the same rank
ranks.1=java.logging,java.scripting,java.xml
ranks.2=java.sql
ranks.4=java.compiler,java.instrument
ranks.5=java.desktop,java.management
# configure the edges A -> B -> C .... with the same weight
# that should get these modules lined in a straight line
weights=java.se,java.sql.rowset,java.sql,java.xml

View File

@ -197,7 +197,7 @@ public class ModuleDotGraph {
static final String ORANGE = "#e76f00";
static final String BLUE = "#437291";
static final String BLACK = "#000000";
static final String DARK_GRAY = "#999999";
static final String DARK_GRAY = "#a9a9a9";
static final String LIGHT_GRAY = "#dddddd";
int fontSize();
@ -208,8 +208,12 @@ public class ModuleDotGraph {
int arrowWidth();
String arrowColor();
default double nodeSep() {
return 0.5;
}
default double rankSep() {
return 1;
return 0.6;
}
default List<Set<String>> ranks() {
@ -231,9 +235,15 @@ public class ModuleDotGraph {
default String jdkSubgraphColor() {
return BLUE;
}
default String nodeMargin() { return ".2, .2"; }
default String requiresStyle() { return "dashed"; };
default String requiresTransitiveStyle() { return ""; };
}
static class DotGraphAttributes implements Attributes {
public static class DotGraphAttributes implements Attributes {
static final DotGraphAttributes DEFAULT = new DotGraphAttributes();
static final String FONT_NAME = "DejaVuSans";
@ -273,9 +283,6 @@ public class ModuleDotGraph {
}
private static class DotGraphBuilder {
static final String REEXPORTS = "";
static final String REQUIRES = "style=\"dashed\"";
static final Set<String> JAVA_SE_SUBGRAPH = javaSE();
static final Set<String> JDK_SUBGRAPH = jdk();
@ -347,14 +354,15 @@ public class ModuleDotGraph {
PrintWriter out = new PrintWriter(writer)) {
out.format("digraph \"%s\" {%n", name);
out.format(" nodesep=.5;%n");
out.format(" nodesep=%f;%n", attributes.nodeSep());
out.format((Locale)null, " ranksep=%f;%n", attributes.rankSep());
out.format(" pencolor=transparent;%n");
out.format(" node [shape=plaintext, fontcolor=\"%s\", fontname=\"%s\","
+ " fontsize=%d, margin=\".2,.2\"];%n",
+ " fontsize=%d, margin=\"%s\"];%n",
attributes.fontColor(),
attributes.fontName(),
attributes.fontSize());
attributes.fontSize(),
attributes.nodeMargin());
out.format(" edge [penwidth=%d, color=\"%s\", arrowhead=open, arrowsize=%d];%n",
attributes.arrowWidth(),
attributes.arrowColor(),
@ -407,11 +415,15 @@ public class ModuleDotGraph {
String mn = md.name();
edges.forEach(dn -> {
String attr;
String attr = "";
if (dn.equals("java.base")) {
attr = "color=\"" + attributes.requiresMandatedColor() + "\"";
} else {
attr = (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES);
String style = requiresTransitive.contains(dn) ? attributes.requiresTransitiveStyle()
: attributes.requiresStyle();
if (!style.isEmpty()) {
attr = "style=\"" + style + "\"";
}
}
int w = attributes.weightOf(mn, dn);