NodeModel.java

package org.thewonderlemming.c4plantuml.graphml.model;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.thewonderlemming.c4plantuml.graphml.Build;
import org.thewonderlemming.c4plantuml.graphml.model.builder.WithId;

/**
 * The <node> part of the representation of a GraphML stream.
 * <p>
 * It is based on JAXB.
 *
 * @author thewonderlemming
 *
 */
@XmlRootElement(name = NodeModel.TAG_NAME)
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeModel {

    /**
     * The current model XML tag name.
     */
    public static final String TAG_NAME = "node";

    @XmlAttribute(name = "id", required = true)
    private String id;

    @XmlElement(name = DataModel.TAG_NAME, required = true)
    private MappedListDecorator<DataModel, String> seq1Data;

    @XmlElement(name = GraphModel.TAG_NAME)
    private GraphModel seq2Graph;


    /**
     * A builder to the current {@link NodeModel} class.
     *
     * @return a new {@link NodeModel} instance.
     */
    public static WithId<String, WithData<Build<NodeModel>>> builder() {

        return id -> data -> () -> {

            final NodeModel node = new NodeModel();
            node.setId(id);
            node.setData(data);

            return node;
        };
    }

    /**
     * Default constructor.
     */
    private NodeModel() {
        // Does nothing but hiding the current constructor.
    }

    /**
     * Adds the given {@link DataModel} to the list if its {@link DataModel#getKey()} is not already there or replaces
     * it else.
     *
     * @param data the given {@link DataModel} to add/replace.
     */
    public void addOrReplaceData(final DataModel data) {
        this.seq1Data.addOrReplaceData(data);
    }

    /**
     * Returns the current &lt;node&gt; data tags.
     *
     * @return the node data tags.
     */
    public List<DataModel> getData() {
        return seq1Data;
    }

    /**
     * Returns the current &lt;node&gt; inner graph.
     *
     * @return the node inner graph.
     */
    public GraphModel getGraph() {
        return seq2Graph;
    }

    /**
     * Returns the current &lt;node&gt; ID.
     *
     * @return the node ID.
     */
    public String getId() {
        return id;
    }

    /**
     * Sets a &lt;data&gt; tag of type {@link C4Keys#DESCRIPTION} and with the given value.
     *
     * @param description the data value to set.
     */
    public void setDescription(final String description) {
        this.seq1Data
            .add(DataModel
                .builder()
                    .withKey(C4Keys.DESCRIPTION)
                    .withValue(description)
                    .build());
    }

    /**
     * Sets a &lt;data&gt; tag of type {@link C4Keys#ENTITY_TYPE} and with the given value.
     *
     * @param entityType the data value to set.
     */
    public void setEntityType(final EntityType entityType) {
        this.seq1Data
            .add(DataModel
                .builder()
                    .withKey(C4Keys.ENTITY_TYPE)
                    .withValue(entityType.getTypeAsString())
                    .build());
    }

    /**
     * Sets a child &lt;graph&gt; into the current &lt;node&gt;.
     *
     * @param graph the graph to set.
     */
    public void setGraph(final GraphModel graph) {
        this.seq2Graph = graph;
    }

    /**
     * Sets the current &lt;node&gt; {@code id} attribute.
     *
     * @param id the id to set.
     */
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Sets a &lt;data&gt; tag of type {@link C4Keys#NAME} and with the given value.
     *
     * @param name the data value to set.
     */
    public void setName(final String name) {
        this.seq1Data
            .add(DataModel
                .builder()
                    .withKey(C4Keys.NAME)
                    .withValue(name)
                    .build());
    }

    /**
     * Sets a &lt;data&gt; tag of type {@link C4Keys#TECHNOLOGICAL_STACK} and with the given value.
     *
     * @param technologicalStack the data value to set.
     */
    public void setTechnologicalStack(final String technologicalStack) {
        this.seq1Data
            .add(DataModel
                .builder()
                    .withKey(C4Keys.TECHNOLOGICAL_STACK)
                    .withValue(technologicalStack)
                    .build());
    }

    private void setData(final List<DataModel> data) {
        this.seq1Data = new MappedListDecorator<>(DataModel.class, data, DataModel::getKey);
    }
}