Skip to content
Permalink
Browse files
8274311: Make build.tools.jigsaw.GenGraphs more configurable
Reviewed-by: alanb, iris
  • Loading branch information
Mandy Chung committed Sep 27, 2021
1 parent 2cffe4c commit daaa47e2005cfa1d72f94a32e7756255f24c4d1f
Showing 3 changed files with 134 additions and 67 deletions.
@@ -36,6 +36,7 @@
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 static void main(String[] args) throws Exception {
/**
* 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 int weightOf(String s, String t) {
return 1;
}

public void weight(String s, String t, int w) {
weights.put(s + ":" + t, w);
}

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))));
/*
* 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();

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;
}
}

@@ -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
@@ -197,7 +197,7 @@ public interface Attributes {
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 interface Attributes {
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 @@ default String javaSubgraphColor() {
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 String arrowColor() {
}

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 void build(Path filename) throws IOException {
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 void printNode(PrintWriter out, ModuleDescriptor md, Set<String> edges) {

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);

1 comment on commit daaa47e

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on daaa47e Sep 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.