All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.intelie.pipes.util.AutomatonRepr Maven / Gradle / Ivy

There is a newer version: 0.25.5
Show newest version
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()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy