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.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -115,102 +116,112 @@ public class GenGraphs {
/** /**
* Custom dot file attributes. * Custom dot file attributes.
*/ */
static class ModuleGraphAttributes implements ModuleDotGraph.Attributes { static class ModuleGraphAttributes extends ModuleDotGraph.DotGraphAttributes {
static Map<String, String> DEFAULT_ATTRIBUTES = Map.of( final Properties attrs;
"ranksep", "0.6", final Map<String, Integer> weights;
"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;
}
ModuleGraphAttributes() { ModuleGraphAttributes() {
this(DEFAULT_ATTRIBUTES); this(new Properties());
} };
ModuleGraphAttributes(Properties props) { 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 @Override
public double rankSep() { public double rankSep() {
return Double.valueOf(attrs.get("ranksep")); String v = attrs.getProperty("ranksep");
return v != null ? Double.valueOf(v) : super.rankSep();
} }
@Override @Override
public int fontSize() { public int fontSize() {
return Integer.valueOf(attrs.get("fontsize")); String v = attrs.getProperty("fontsize");
return v != null ? Integer.valueOf(v) : super.fontSize();
} }
@Override @Override
public String fontName() { public String fontName() {
return attrs.get("fontname"); String v = attrs.getProperty("fontname");
return v != null ? v : super.fontName();
} }
@Override @Override
public String fontColor() { public String fontColor() {
return attrs.get("fontcolor"); String v = attrs.getProperty("fontcolor");
return v != null ? v : super.fontColor();
} }
@Override @Override
public int arrowSize() { public int arrowSize() {
return Integer.valueOf(attrs.get("arrowsize")); String v = attrs.getProperty("arrowsize");
return v != null ? Integer.valueOf(v) : super.arrowSize();
} }
@Override @Override
public int arrowWidth() { public int arrowWidth() {
return Integer.valueOf(attrs.get("arrowwidth")); String v = attrs.getProperty("arrowwidth");
return v != null ? Integer.valueOf(v) : super.arrowWidth();
} }
@Override @Override
public String arrowColor() { public String arrowColor() {
return attrs.get("arrowcolor"); String v = attrs.getProperty("arrowcolor");
return v != null ? v : super.arrowColor();
} }
@Override @Override
public List<Set<String>> ranks() { 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 @Override
public String requiresMandatedColor() { public String requiresMandatedColor() {
return attrs.get("requiresMandatedColor"); String v = attrs.getProperty("requiresMandatedColor");
return v != null ? v : super.requiresMandatedColor();
} }
@Override @Override
public String javaSubgraphColor() { public String javaSubgraphColor() {
return attrs.get("javaSubgraphColor"); String v = attrs.getProperty("javaSubgraphColor");
return v != null ? v : super.javaSubgraphColor();
} }
@Override @Override
public String jdkSubgraphColor() { 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 @Override
public int weightOf(String s, String t) { public int weightOf(String s, String t) {
int w = weights.getOrDefault(s + ":" + t, 1); int w = weights.getOrDefault(s + ":" + t, 1);
@ -221,14 +232,25 @@ public class GenGraphs {
return 1; 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) { Map<String, Integer> weights = new HashMap<>();
return DEFAULT_ATTRIBUTES.keySet().stream() String mn = modules[0];
.collect(Collectors.toMap(Function.identity(), int w = 10000;
k -> props.getProperty(k, DEFAULT_ATTRIBUTES.get(k)))); 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 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 ORANGE = "#e76f00";
static final String BLUE = "#437291"; static final String BLUE = "#437291";
static final String BLACK = "#000000"; static final String BLACK = "#000000";
static final String DARK_GRAY = "#999999"; static final String DARK_GRAY = "#a9a9a9";
static final String LIGHT_GRAY = "#dddddd"; static final String LIGHT_GRAY = "#dddddd";
int fontSize(); int fontSize();
@ -208,8 +208,12 @@ public class ModuleDotGraph {
int arrowWidth(); int arrowWidth();
String arrowColor(); String arrowColor();
default double nodeSep() {
return 0.5;
}
default double rankSep() { default double rankSep() {
return 1; return 0.6;
} }
default List<Set<String>> ranks() { default List<Set<String>> ranks() {
@ -231,9 +235,15 @@ public class ModuleDotGraph {
default String jdkSubgraphColor() { default String jdkSubgraphColor() {
return BLUE; 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 DotGraphAttributes DEFAULT = new DotGraphAttributes();
static final String FONT_NAME = "DejaVuSans"; static final String FONT_NAME = "DejaVuSans";
@ -273,9 +283,6 @@ public class ModuleDotGraph {
} }
private static class DotGraphBuilder { 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> JAVA_SE_SUBGRAPH = javaSE();
static final Set<String> JDK_SUBGRAPH = jdk(); static final Set<String> JDK_SUBGRAPH = jdk();
@ -347,14 +354,15 @@ public class ModuleDotGraph {
PrintWriter out = new PrintWriter(writer)) { PrintWriter out = new PrintWriter(writer)) {
out.format("digraph \"%s\" {%n", name); 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((Locale)null, " ranksep=%f;%n", attributes.rankSep());
out.format(" pencolor=transparent;%n"); out.format(" pencolor=transparent;%n");
out.format(" node [shape=plaintext, fontcolor=\"%s\", fontname=\"%s\"," out.format(" node [shape=plaintext, fontcolor=\"%s\", fontname=\"%s\","
+ " fontsize=%d, margin=\".2,.2\"];%n", + " fontsize=%d, margin=\"%s\"];%n",
attributes.fontColor(), attributes.fontColor(),
attributes.fontName(), attributes.fontName(),
attributes.fontSize()); attributes.fontSize(),
attributes.nodeMargin());
out.format(" edge [penwidth=%d, color=\"%s\", arrowhead=open, arrowsize=%d];%n", out.format(" edge [penwidth=%d, color=\"%s\", arrowhead=open, arrowsize=%d];%n",
attributes.arrowWidth(), attributes.arrowWidth(),
attributes.arrowColor(), attributes.arrowColor(),
@ -407,11 +415,15 @@ public class ModuleDotGraph {
String mn = md.name(); String mn = md.name();
edges.forEach(dn -> { edges.forEach(dn -> {
String attr; String attr = "";
if (dn.equals("java.base")) { if (dn.equals("java.base")) {
attr = "color=\"" + attributes.requiresMandatedColor() + "\""; attr = "color=\"" + attributes.requiresMandatedColor() + "\"";
} else { } 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); int w = attributes.weightOf(mn, dn);