# KeyModel.java

    package org.thewonderlemming.c4plantuml.graphml.model;

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

    import org.thewonderlemming.c4plantuml.graphml.Build;
    import org.thewonderlemming.c4plantuml.graphml.model.builder.KeyFor;
    import org.thewonderlemming.c4plantuml.graphml.model.builder.WithAttrName;
    import org.thewonderlemming.c4plantuml.graphml.model.builder.WithAttrType;
    import org.thewonderlemming.c4plantuml.graphml.model.builder.WithFor;
    import org.thewonderlemming.c4plantuml.graphml.model.builder.WithId;

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

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

        @XmlAttribute(name = "attr.name", required = true)
        private String attrName;

        @XmlAttribute(name = "attr.type", required = true)
        private String attrType;

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

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

        /**
         * A builder to the current {@link KeyModel} class.
         *
         * @return a new {@link KeyModel} instance.
         */
        public static WithId<String, WithFor<KeyFor, WithAttrName<String, WithAttrType<String, Build<KeyModel>>>>> builder() {

            return id -> forProperty -> attrName -> attrType -> () -> {

                final KeyModel key = new KeyModel();
                key.setId(id);
                key.setForProperty(forProperty.getValue());
                key.setAttrName(attrName);
                key.setAttrType(attrType);

                return key;
            };
        }

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

        /**
         * Sets the {@code attrName} of the current instance.
         *
         * @param id the {@code attrName} to add to the current instance.
         */
        private void setAttrName(final String attrName) {
            this.attrName = attrName;
        }

        /**
         * Sets the {@code attrType} of the current instance.
         *
         * @param id the {@code attrType} to add to the current instance.
         */
        private void setAttrType(final String attrType) {
            this.attrType = attrType;
        }

        /**
         * Sets the {@code forProperty} of the current instance.
         *
         * @param id the {@code forProperty} to add to the current instance.
         */
        private void setForProperty(final String forProperty) {
            this.forProperty = forProperty;
        }

        /**
         * Sets the {@code id} of the current instance.
         *
         * @param id the {@code id} to add to the current instance.
         */
        private void setId(final String id) {
            this.id = id;
        }
    }