//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-2 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2013.08.27 at 09:45:12 AM CEST 
//


package org.apache.batchee.jaxb;

import org.apache.batchee.container.jsl.ExecutionElement;
import org.apache.batchee.container.jsl.TransitionElement;

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.XmlElements;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.ArrayList;
import java.util.List;


/**
 * Java class for Flow complex type.
 * <p>
 * The following schema fragment specifies the expected content contained within this class.
 *
 * <pre>
 * &lt;complexType name="Flow"&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;choice maxOccurs="unbounded" minOccurs="0"&gt;
 *           &lt;element name="decision" type="{http://xmlns.jcp.org/xml/ns/javaee}Decision"/&gt;
 *           &lt;element name="flow" type="{http://xmlns.jcp.org/xml/ns/javaee}Flow"/&gt;
 *           &lt;element name="split" type="{http://xmlns.jcp.org/xml/ns/javaee}Split"/&gt;
 *           &lt;element name="step" type="{http://xmlns.jcp.org/xml/ns/javaee}Step"/&gt;
 *         &lt;/choice&gt;
 *         &lt;group ref="{http://xmlns.jcp.org/xml/ns/javaee}TransitionElements" maxOccurs="unbounded" minOccurs="0"/&gt;
 *       &lt;/sequence&gt;
 *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" /&gt;
 *       &lt;attribute name="next" type="{http://www.w3.org/2001/XMLSchema}string" /&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Flow", propOrder = {
    "executionElements",
    "transitionElements"
})
public class Flow implements ExecutionElement {

    @XmlElements({
        @XmlElement(name = "split", type = Split.class),
        @XmlElement(name = "flow", type = Flow.class),
        @XmlElement(name = "step", type = Step.class),
        @XmlElement(name = "decision", type = Decision.class)
    })
    protected List<ExecutionElement> executionElements;
    @XmlElements({
        @XmlElement(name = "stop", type = Stop.class),
        @XmlElement(name = "fail", type = Fail.class),
        @XmlElement(name = "next", type = Next.class),
        @XmlElement(name = "end", type = End.class)
    })
    protected List<TransitionElement> transitionElements;
    @XmlAttribute(name = "id", required = true)
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    protected String id;
    @XmlAttribute(name = "next")
    protected String nextFromAttribute;

    /**
     * Gets the value of the executionElements property.
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a {@code set} method for the executionElements property.
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getExecutionElements().add(newItem);
     * </pre>
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Split }
     * {@link Flow }
     * {@link Step }
     * {@link Decision }
     */
    public List<ExecutionElement> getExecutionElements() {
        if (executionElements == null) {
            executionElements = new ArrayList<ExecutionElement>();
        }
        return this.executionElements;
    }

    /**
     * Gets the value of the transitionElements property.
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a {@code set} method for the transitionElements property.
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getTransitionElements().add(newItem);
     * </pre>
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Stop }
     * {@link Fail }
     * {@link Next }
     * {@link End }
     */
    public List<TransitionElement> getTransitionElements() {
        if (transitionElements == null) {
            transitionElements = new ArrayList<TransitionElement>();
        }
        return this.transitionElements;
    }

    /**
     * Gets the value of the id property.
     *
     * @return possible object is
     * {@link String }
     */
    public String getId() {
        return id;
    }

    /**
     * Sets the value of the id property.
     *
     * @param value allowed object is
     *              {@link String }
     */
    public void setId(String value) {
        this.id = value;
    }

    /**
     * Gets the value of the nextFromAttribute property.
     *
     * @return possible object is
     * {@link String }
     */
    public String getNextFromAttribute() {
        return nextFromAttribute;
    }

    /**
     * Sets the value of the nextFromAttribute property.
     *
     * @param value allowed object is
     *              {@link String }
     */
    public void setNextFromAttribute(String value) {
        this.nextFromAttribute = value;
    }

}
