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

guru.nidi.graphviz.model.MutableGraph Maven / Gradle / Ivy

There is a newer version: 0.18.1
Show newest version
/*
 * Copyright © 2015 Stefan Niederhauser ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package guru.nidi.graphviz.model;

import guru.nidi.graphviz.attribute.*;

import javax.annotation.Nullable;
import java.util.*;

import static java.util.Arrays.asList;

public class MutableGraph implements LinkSource, LinkTarget {
    private static final SafeRecursion RECURSION = new SafeRecursion<>();
    protected boolean strict;
    protected boolean directed;
    protected boolean cluster;
    protected String name;
    protected final Set nodes;
    protected final Set subgraphs;
    protected final LinkList links;
    protected final MutableAttributed nodeAttrs;
    protected final MutableAttributed linkAttrs;
    protected final MutableAttributed graphAttrs;

    MutableGraph() {
        this(false, false, false, "", new LinkedHashSet<>(), new LinkedHashSet<>(), new ArrayList<>(),
                null, null, null);
        CreationContext.current().ifPresent(ctx -> graphAttrs().add(ctx.graphAttrs()));
    }

    protected MutableGraph(boolean strict, boolean directed, boolean cluster, String name,
                           LinkedHashSet nodes, LinkedHashSet subgraphs, List links,
                           @Nullable Attributes nodeAttrs,
                           @Nullable Attributes linkAttrs,
                           @Nullable Attributes graphAttrs) {
        this.strict = strict;
        this.directed = directed;
        this.cluster = cluster;
        this.name = name;
        this.nodes = nodes;
        this.subgraphs = subgraphs;
        this.links = new LinkList(this, links);
        this.nodeAttrs = new SimpleMutableAttributed<>(this, nodeAttrs);
        this.linkAttrs = new SimpleMutableAttributed<>(this, linkAttrs);
        this.graphAttrs = new SimpleMutableAttributed<>(this, graphAttrs);
    }

    public MutableGraph copy() {
        return new MutableGraph(strict, directed, cluster, name,
                new LinkedHashSet<>(nodes), new LinkedHashSet<>(subgraphs), links,
                nodeAttrs, linkAttrs, graphAttrs);
    }

    public MutableGraph use(ThrowingBiConsumer actions) {
        return CreationContext.use(this, ctx -> {
            actions.accept(this, ctx);
            return this;
        });
    }

    public MutableGraph setStrict(boolean strict) {
        this.strict = strict;
        return this;
    }

    public MutableGraph setDirected(boolean directed) {
        this.directed = directed;
        return this;
    }

    public MutableGraph setCluster(boolean cluster) {
        this.cluster = cluster;
        return this;
    }

    public MutableGraph setName(String name) {
        this.name = name;
        return this;
    }

    public MutableGraph add(LinkSource... sources) {
        return add(asList(sources));
    }

    public MutableGraph add(List sources) {
        for (final LinkSource source : sources) {
            add(source);
        }
        return this;
    }

    public MutableGraph add(LinkSource source) {
        source.addTo(this);
        return this;
    }

    public MutableGraph addLink(LinkTarget... targets) {
        for (final LinkTarget target : targets) {
            addLink(target);
        }
        return this;
    }

    public MutableGraph addLink(LinkTarget target) {
        links.add(linkTo(target));
        return this;
    }

    @Override
    public Link linkTo(LinkTarget target) {
        final Link link = target.linkTo();
        return Link.between(this, link.to).with(link.attributes);
    }

    @Override
    public Link linkTo() {
        return Link.to(this);
    }

    @Override
    public void addTo(MutableGraph graph) {
        graph.subgraphs.add(this);
    }

    @Override
    public LinkTarget asLinkTarget() {
        return this;
    }

    @Override
    public LinkSource asLinkSource() {
        return this;
    }

    public Collection rootNodes() {
        return nodes;
    }

    public Collection nodes() {
        final HashSet ns = new HashSet<>();
        for (final MutableNode node : nodes) {
            collectNodes(node, ns);
        }
        return ns;
    }

    private void collectNodes(MutableNode node, Set visited) {
        if (!visited.contains(node)) {
            visited.add(node);
            for (final Link link : node.links()) {
                if (link.to instanceof ImmutablePortNode) {
                    collectNodes(((ImmutablePortNode) link.to).node(), visited);
                }
            }
        }
    }

    public Collection graphs() {
        return subgraphs;
    }

    public List links() {
        return links;
    }

    public boolean isStrict() {
        return strict;
    }

    public boolean isDirected() {
        return directed;
    }

    public boolean isCluster() {
        return cluster;
    }

    public String name() {
        return name;
    }

    public MutableAttributed nodeAttrs() {
        return nodeAttrs;
    }

    public MutableAttributed linkAttrs() {
        return linkAttrs;
    }

    public MutableAttributed graphAttrs() {
        return graphAttrs;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final MutableGraph that = (MutableGraph) o;
        return RECURSION.recurse(this, true, () -> strict == that.strict
                && directed == that.directed
                && cluster == that.cluster
                && Objects.equals(name, that.name)
                && Objects.equals(nodes, that.nodes)
                && Objects.equals(subgraphs, that.subgraphs)
                && Objects.equals(links, that.links)
                && Objects.equals(nodeAttrs, that.nodeAttrs)
                && Objects.equals(linkAttrs, that.linkAttrs)
                && Objects.equals(graphAttrs, that.graphAttrs));
    }

    @Override
    public int hashCode() {
        return RECURSION.recurse(this, 0, () -> Objects.hash(
                strict, directed, cluster, name, nodes, subgraphs, links, nodeAttrs, linkAttrs, graphAttrs));
    }

    @Override
    public String toString() {
        return new Serializer(this).serialize();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy