net.intelie.pipes.util.AutomatonRepr Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pipes-api Show documentation
Show all versions of pipes-api Show documentation
Intelie Pipes' API classes and interfaces
package net.intelie.pipes.util;
import java.util.*;
public class AutomatonRepr {
public static final int DEFAULT_FONT_SIZE = 14;
private final List nodes = new ArrayList<>();
private final List edges = new ArrayList<>();
private final Map aliases = new HashMap<>();
private final Set reserved = new HashSet<>();
private String startId;
public AutomatonRepr(String startId) {
this.startId = startId;
}
private static String prefixId(String prefix, AutomatonRepr to, String id) {
return (to.reserved.contains(id) ? "" : prefix) + id;
}
public String getStartId() {
return startId;
}
public void setStartId(String startId) {
this.startId = startId;
}
public void addNode(String shape, String id, Object label) {
this.nodes.add(new ValueNode(shape, id, label));
}
public static String escapeHTML(String s) {
if (s == null) return "null";
StringBuilder out = new StringBuilder(Math.max(16, s.length()));
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
out.append("");
out.append((int) c);
out.append(';');
} else {
out.append(c);
}
}
return out.toString();
}
public void addAlias(String alias, String to) {
aliases.put(alias, to);
addReserved(alias);
}
public void addReserved(String alias) {
reserved.add(alias);
}
public void addEdge(String from, String to, Object label) {
this.edges.add(new Edge(from, to, String.valueOf(label)));
}
public void addEdge(String from, String prefix, AutomatonRepr to, Object label) {
merge(prefix, to);
this.addEdge(from, prefixId(prefix, to, to.startId), label);
}
public void merge(String prefix, AutomatonRepr repr) {
for (ValueNode node : repr.nodes)
addNode(node.shape, prefixId(prefix, repr, node.id), node.label);
for (Edge edge : repr.edges) {
addEdge(prefixId(prefix, repr, edge.from),
prefixId(prefix, repr, edge.to),
edge.label);
}
for (Map.Entry entry : repr.aliases.entrySet()) {
addAlias(entry.getKey(), prefixId(prefix, repr, entry.getValue()));
}
this.reserved.addAll(repr.reserved);
}
public String toString(boolean tree) {
StringBuilder builder = new StringBuilder();
builder.append("digraph \"\" {\n")
.append(tree ? " ordering=out\n" : " rankdir=LR\n");
for (ValueNode node : nodes) {
builder.append(" ").append(node).append("\n");
}
for (Edge edge : edges) {
builder.append(" ").append(edge.toString(aliases)).append("\n");
}
builder.append("}");
return builder.toString();
}
@Override
public String toString() {
return toString(false);
}
public static class ValueNode {
private final String shape;
private final String id;
private final Object label;
public ValueNode(String shape, String id, Object label) {
this.shape = shape;
this.id = id;
this.label = label;
}
@Override
public String toString() {
LabelLines label = LabelLines.get(this.label);
return String.format((Locale) null, "%s[shape=%s,tooltip=%s,label=%s];",
id,
shape,
label.tooltipRepr(),
label.labelRepr());
}
}
public static class LabelLines {
private final List lines = new ArrayList<>();
private String tooltip = "";
public LabelLines setTooltip(Object tooltip) {
this.tooltip = String.valueOf(tooltip);
return this;
}
public LabelLines addLine(int size, Object text) {
String label = escapeHTML(String.valueOf(text));
if (label.isEmpty()) label = " ";
if (size != DEFAULT_FONT_SIZE)
lines.add("" + label + "");
else
lines.add(label);
return this;
}
public String tooltipRepr() {
return "\"" + tooltip + "\"";
}
public String labelRepr() {
return "<" + Iterables.join("
", lines) + ">";
}
public static LabelLines get(Object label) {
return label instanceof LabelLines ?
(LabelLines) label :
new LabelLines().addLine(DEFAULT_FONT_SIZE, label);
}
}
public static class Edge {
private final String from;
private final String to;
private final Object label;
public Edge(String from, String to, Object label) {
this.from = from;
this.to = to;
this.label = label;
}
public String toString(Map aliases) {
String from = this.from;
String to = this.to;
while (aliases.containsKey(from)) from = aliases.get(from);
while (aliases.containsKey(to)) to = aliases.get(to);
LabelLines label = LabelLines.get(this.label);
return String.format((Locale) null, "%s -> %s [tooltip=%s,label=%s];", from, to,
label.tooltipRepr(), label.labelRepr());
}
}
}