001/*
002 * To change this license header, choose License Headers in Project Properties.
003 * To change this template file, choose Tools | Templates
004 * and open the template in the editor.
005 */
006package org.anarres.graphviz.builder.jgrapht;
007
008import com.google.common.base.Function;
009import com.google.common.base.Functions;
010import com.google.common.base.MoreObjects;
011import javax.annotation.CheckForNull;
012import javax.annotation.Nonnull;
013import org.anarres.graphviz.builder.GraphVizEdge;
014import org.anarres.graphviz.builder.GraphVizGraph;
015import org.anarres.graphviz.builder.GraphVizNode;
016import org.anarres.graphviz.builder.GraphVizScope;
017import org.anarres.graphviz.builder.GraphVizable;
018import org.jgrapht.Graph;
019
020/**
021 *
022 * @author shevek
023 */
024public class JGraphTGraphVizBuilder<V, E> implements GraphVizScope, GraphVizable {
025
026    private static final Function<Object, String> EDGE_LABEL_NULL = Functions.constant(null);
027
028    private final Graph<V, E> graph;
029    private final GraphVizScope scope = this;
030    private Function<? super V, String> nodeLabelFunction = Functions.toStringFunction();
031    private Function<? super E, String> edgeLabelFunction = EDGE_LABEL_NULL;
032    private Function<? super E, String> edgeHeadLabelFunction = EDGE_LABEL_NULL;
033    private Function<? super E, String> edgeTailLabelFunction = EDGE_LABEL_NULL;
034
035    public JGraphTGraphVizBuilder(@Nonnull Graph<V, E> graph, @CheckForNull Function<? super V, String> nodeLabelFunction) {
036        this.graph = graph;
037        this.nodeLabelFunction = (Function<? super V, String>) MoreObjects.firstNonNull(nodeLabelFunction, Functions.toStringFunction());
038    }
039
040    public JGraphTGraphVizBuilder(@Nonnull Graph<V, E> graph) {
041        this(graph, null);
042    }
043
044    @Nonnull
045    public JGraphTGraphVizBuilder<V, E> withNodeLabelFunction(Function<? super V, String> nodeLabelFunction) {
046        this.nodeLabelFunction = nodeLabelFunction;
047        return this;
048    }
049
050    @Nonnull
051    public JGraphTGraphVizBuilder<V, E> withEdgeLabelFunction(Function<? super E, String> edgeLabelFunction) {
052        this.edgeLabelFunction = edgeLabelFunction;
053        return this;
054    }
055
056    @Nonnull
057    public JGraphTGraphVizBuilder<V, E> withEdgeHeadLabelFunction(Function<? super E, String> edgeHeadLabelFunction) {
058        this.edgeHeadLabelFunction = edgeHeadLabelFunction;
059        return this;
060    }
061
062    @Nonnull
063    public JGraphTGraphVizBuilder<V, E> withEdgeTailLabelFunction(Function<? super E, String> edgeTailLabelFunction) {
064        this.edgeTailLabelFunction = edgeTailLabelFunction;
065        return this;
066    }
067
068    @Override
069    public void toGraphViz(@Nonnull GraphVizGraph out) {
070        for (V node : graph.vertexSet()) {
071            GraphVizNode n = out.node(scope, node);
072            String label = nodeLabelFunction.apply(node);
073            if (label != null)
074                n.label(label);
075        }
076        for (E edge : graph.edgeSet()) {
077            GraphVizEdge e = out.edge(scope, graph.getEdgeSource(edge), graph.getEdgeTarget(edge));
078            String label = edgeLabelFunction.apply(edge);
079            if (label != null)
080                e.label(label);
081            String headLabel = edgeHeadLabelFunction.apply(edge);
082            if (headLabel != null)
083                e.headLabel(headLabel);
084            String tailLabel = edgeTailLabelFunction.apply(edge);
085            if (tailLabel != null)
086                e.tailLabel(tailLabel);
087        }
088    }
089
090    /** Use {@link #toGraphViz(GraphVizGraph)}. */
091    @Deprecated
092    public void build(@Nonnull GraphVizGraph out) {
093        toGraphViz(out);
094    }
095}