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

poussecafe.doc.AggregateGraphFactory Maven / Gradle / Ivy

The newest version!
package poussecafe.doc;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import poussecafe.doc.doclet.Logger;
import poussecafe.doc.graph.Node;
import poussecafe.doc.graph.NodeStyle;
import poussecafe.doc.graph.UndirectedEdge;
import poussecafe.doc.graph.UndirectedGraph;
import poussecafe.doc.model.Aggregate;
import poussecafe.doc.model.Domain;
import poussecafe.doc.model.Module;
import poussecafe.doc.model.Relation;
import poussecafe.doc.model.relationdoc.Component;
import poussecafe.doc.model.relationdoc.ComponentType;
import poussecafe.source.analysis.ClassName;

import static java.util.stream.Collectors.toList;

public class AggregateGraphFactory {

    private Set exploredFromClassNames = new HashSet<>();

    public UndirectedGraph buildGraph() {
        String aggregateNodeName = addAggregate();
        AggregateGraphPath path = new AggregateGraphPath().with(aggregateNodeName);
        addAllRelations(path, aggregateDoc.documentation().className().orElseThrow());
        return graph;
    }

    private String addAggregate() {
        Logger.debug("Aggregate " + aggregateDoc.documentation().id());
        String nodeName = aggregateDoc.documentation().name();
        Node node = Node.box(nodeName);
        node.setStyle(Optional.of(NodeStyle.BOLD));
        graph.getNodesAndEdges().addNode(node);
        return nodeName;
    }

    private Aggregate aggregateDoc;

    private UndirectedGraph graph = new UndirectedGraph();

    private void addAllRelations(AggregateGraphPath path, ClassName fromClassName) {
        if(!exploredFromClassNames.contains(fromClassName)) {
            exploredFromClassNames.add(fromClassName);

            for(Relation relation : findWithFromClassName(fromClassName)) {
                Component toComponent = relation.to();

                Logger.debug("Relation " + fromClassName + " -> " + toComponent.className());
                if(toComponent.type() != ComponentType.AGGREGATE) {
                    String newNodeName = toComponent.name();
                    AggregateGraphPath newPath = path.with(newNodeName);
                    addNonAggregateRelation(path, toComponent, newNodeName);
                    addAllRelations(newPath, relation.to().className());
                } else {
                    addAggregateRelation(path, toComponent);
                }
            }
        }
    }

    private List findWithFromClassName(ClassName fromClassName) {
        return domain.relations().stream()
                .filter(item -> item.from().className().equals(fromClassName))
                .collect(toList());
    }

    private Domain domain;

    private void addAggregateRelation(AggregateGraphPath path, Component toComponent) {
        var aggregateClassName = aggregateDoc.documentation().className().orElseThrow();
        if(toComponent.className().equals(aggregateClassName)) {
            return;
        }

        var toAggregateDoc = module.aggregate(toComponent.name());
        if(toAggregateDoc.isPresent()) {
            String toName = toComponent.name();
            addNode(toComponent, toName);
            UndirectedEdge edge = UndirectedEdge.dashedEdge(path.lastName(), toName);
            graph.getNodesAndEdges().addEdge(edge);
        }
    }

    private Module module;

    private String addNonAggregateRelation(AggregateGraphPath path, Component toComponent, String toName) {
        addNode(toComponent, toName);
        UndirectedEdge edge = UndirectedEdge.solidEdge(path.lastName(), toName);
        graph.getNodesAndEdges().addEdge(edge);
        return toName;
    }

    private void addNode(Component component, String candidateName) {
        if(graph.getNodesAndEdges().getNode(candidateName) == null) {
            Node node = node(component, candidateName);
            graph.getNodesAndEdges().addNode(node);
        }
    }

    private Node node(Component component,
            String name) {
        if(component.type() == ComponentType.ENTITY) {
            return Node.box(name);
        } else if(component.type() == ComponentType.VALUE_OBJECT) {
            return Node.ellipse(name);
        } else if(component.type() == ComponentType.AGGREGATE) {
            Node node = Node.box(name);
            node.setStyle(Optional.of(NodeStyle.BOLD));
            return node;
        } else {
            throw new IllegalArgumentException("Unsupported component type " + component.type());
        }
    }

    public static class Builder {

        private AggregateGraphFactory factory = new AggregateGraphFactory();

        public Builder aggregateDoc(Aggregate aggregateDoc) {
            factory.aggregateDoc = aggregateDoc;
            return this;
        }

        public Builder domain(Domain domain) {
            factory.domain = domain;
            return this;
        }

        public AggregateGraphFactory build() {
            Objects.requireNonNull(factory.aggregateDoc);
            Objects.requireNonNull(factory.domain);

            factory.module = factory.domain.module(factory.aggregateDoc.documentation().moduleName()).orElseThrow();

            return factory;
        }
    }

    private AggregateGraphFactory() {

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy