WorkflowSemanticValueFormatter.java
package org.hammer.audio.workflow;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.TreeMap;
/** Canonical textual evidence for semantic workflow comparison and merge conflicts. */
public final class WorkflowSemanticValueFormatter {
private WorkflowSemanticValueFormatter() {
throw new UnsupportedOperationException("Utility class");
}
/** Returns a canonical value for one complete node snapshot. */
public static String node(Node node) {
return "node{id="
+ quote(node.id())
+ ",type="
+ quote(node.type())
+ ",label="
+ quote(node.label())
+ ",inputPorts="
+ ports(node.inputPorts())
+ ",outputPorts="
+ ports(node.outputPorts())
+ ",metadata="
+ metadata(node.metadata())
+ "}";
}
/** Returns a canonical value for one complete edge snapshot. */
public static String edge(Edge edge) {
return "edge{id="
+ quote(edge.id())
+ ",source="
+ endpoint(edge.sourceNodeId(), edge.sourcePortId())
+ ",target="
+ endpoint(edge.targetNodeId(), edge.targetPortId())
+ ",metadata="
+ metadata(edge.metadata())
+ "}";
}
/** Returns a canonical node snapshot together with all incident edges. */
public static String neighborhood(Node node, List<Edge> connectedEdges) {
if (node == null) {
return null;
}
StringJoiner edges = new StringJoiner(",", "[", "]");
connectedEdges.stream()
.sorted(Comparator.comparing(Edge::id))
.map(WorkflowSemanticValueFormatter::edge)
.forEach(edges::add);
return "neighborhood{node=" + node(node) + ",edges=" + edges + "}";
}
/** Returns canonical source and target endpoints for one edge. */
public static String endpoints(Edge edge) {
return endpoint(edge.sourceNodeId(), edge.sourcePortId())
+ "->"
+ endpoint(edge.targetNodeId(), edge.targetPortId());
}
/** Returns canonical declared-order port evidence. */
public static String ports(List<Port> ports) {
StringJoiner values = new StringJoiner(",", "[", "]");
for (Port port : ports) {
values.add(port(port));
}
return values.toString();
}
/** Returns canonical key-ordered metadata evidence. */
public static String metadata(Metadata metadata) {
return metadata(metadata.entries());
}
/** Returns canonical key-ordered metadata-map evidence. */
public static String metadata(Map<String, String> entries) {
StringJoiner values = new StringJoiner(",", "{", "}");
for (Map.Entry<String, String> entry : new TreeMap<>(entries).entrySet()) {
values.add(quote(entry.getKey()) + ":" + quote(entry.getValue()));
}
return values.toString();
}
private static String port(Port port) {
return "port{id="
+ quote(port.id())
+ ",name="
+ quote(port.name())
+ ",direction="
+ port.direction().name()
+ ",dataType="
+ quote(port.dataType().id())
+ ",required="
+ port.required()
+ ",multiplicity="
+ port.multiplicity().name()
+ ",metadata="
+ metadata(port.metadata())
+ "}";
}
private static String endpoint(String nodeId, String portId) {
return quote(nodeId) + ":" + quote(portId);
}
private static String quote(String value) {
return "\"" + escape(value) + "\"";
}
private static String escape(String value) {
return value
.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r");
}
}