/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
// dmccann - June 29/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.jaxb.xmlmodel;

import java.util.ArrayList;
import java.util.List;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 *
 * <p>The following schema fragment specifies the expected content contained within this class.
 *
 * <pre>
 * &lt;complexType&gt;
 *   &lt;complexContent&gt;
 *     &lt;extension base="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}java-attribute"&gt;
 *       &lt;sequence&gt;
 *         &lt;element ref="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-access-methods" minOccurs="0"/&gt;
 *         &lt;element ref="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-element" maxOccurs="unbounded" minOccurs="0"/&gt;
 *         &lt;element ref="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-element-wrapper" minOccurs="0"/&gt;
 *         &lt;element ref="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-java-type-adapter" minOccurs="0"/&gt;
 *         &lt;element ref="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-properties" minOccurs="0"/&gt;
 *         &lt;element ref="{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-join-nodes" maxOccurs="unbounded" minOccurs="0"/&gt;
 *       &lt;/sequence&gt;
 *       &lt;attribute name="xml-idref" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
 *       &lt;attribute name="xml-list" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
 *       &lt;attribute name="read-only" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
 *       &lt;attribute name="write-only" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
 *       &lt;attribute name="container-type" type="{http://www.w3.org/2001/XMLSchema}string" default="##default" /&gt;
 *     &lt;/extension&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "xmlAccessMethods",
    "xmlElement",
    "xmlElementWrapper",
    "xmlJavaTypeAdapter",
    "xmlProperties",
    "xmlJoinNodes"
})
public class XmlElements
    extends JavaAttribute
{

    @jakarta.xml.bind.annotation.XmlElement(name = "xml-access-methods")
    protected XmlAccessMethods xmlAccessMethods;
    @jakarta.xml.bind.annotation.XmlElement(name = "xml-element")
    protected List<org.eclipse.persistence.jaxb.xmlmodel.XmlElement> xmlElement;
    @jakarta.xml.bind.annotation.XmlElement(name = "xml-element-wrapper")
    protected XmlElementWrapper xmlElementWrapper;
    @jakarta.xml.bind.annotation.XmlElement(name = "xml-java-type-adapter")
    protected XmlJavaTypeAdapter xmlJavaTypeAdapter;
    @jakarta.xml.bind.annotation.XmlElement(name = "xml-properties")
    protected XmlProperties xmlProperties;
    @jakarta.xml.bind.annotation.XmlElement(name = "xml-join-nodes")
    protected List<XmlJoinNodes> xmlJoinNodes;
    @XmlAttribute(name = "xml-idref")
    protected Boolean xmlIdref;
    @XmlAttribute(name = "xml-list")
    protected Boolean xmlList;
    @XmlAttribute(name = "read-only")
    protected Boolean readOnly;
    @XmlAttribute(name = "write-only")
    protected Boolean writeOnly;
    @XmlAttribute(name = "container-type")
    protected String containerType;

    /**
     * Gets the value of the xmlAccessMethods property.
     *
     * @return
     *     possible object is
     *     {@link XmlAccessMethods }
     *
     */
    public XmlAccessMethods getXmlAccessMethods() {
        return xmlAccessMethods;
    }

    /**
     * Sets the value of the xmlAccessMethods property.
     *
     * @param value
     *     allowed object is
     *     {@link XmlAccessMethods }
     *
     */
    public void setXmlAccessMethods(XmlAccessMethods value) {
        this.xmlAccessMethods = value;
    }

    /**
     * Gets the value of the xmlElement 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</CODE> method for the xmlElement property.
     *
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getXmlElement().add(newItem);
     * </pre>
     *
     *
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link org.eclipse.persistence.jaxb.xmlmodel.XmlElement }
     *
     *
     */
    public List<org.eclipse.persistence.jaxb.xmlmodel.XmlElement> getXmlElement() {
        if (xmlElement == null) {
            xmlElement = new ArrayList<org.eclipse.persistence.jaxb.xmlmodel.XmlElement>();
        }
        return this.xmlElement;
    }

    /**
     * Gets the value of the xmlElementWrapper property.
     *
     * @return
     *     possible object is
     *     {@link XmlElementWrapper }
     *
     */
    public XmlElementWrapper getXmlElementWrapper() {
        return xmlElementWrapper;
    }

    /**
     * Sets the value of the xmlElementWrapper property.
     *
     * @param value
     *     allowed object is
     *     {@link XmlElementWrapper }
     *
     */
    public void setXmlElementWrapper(XmlElementWrapper value) {
        this.xmlElementWrapper = value;
    }

    /**
     * Gets the value of the xmlJavaTypeAdapter property.
     *
     * @return
     *     possible object is
     *     {@link XmlJavaTypeAdapter }
     *
     */
    public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
        return xmlJavaTypeAdapter;
    }

    /**
     * Sets the value of the xmlJavaTypeAdapter property.
     *
     * @param value
     *     allowed object is
     *     {@link XmlJavaTypeAdapter }
     *
     */
    public void setXmlJavaTypeAdapter(XmlJavaTypeAdapter value) {
        this.xmlJavaTypeAdapter = value;
    }

    /**
     * Gets the value of the xmlProperties property.
     *
     * @return
     *     possible object is
     *     {@link XmlProperties }
     *
     */
    public XmlProperties getXmlProperties() {
        return xmlProperties;
    }

    /**
     * Sets the value of the xmlProperties property.
     *
     * @param value
     *     allowed object is
     *     {@link XmlProperties }
     *
     */
    public void setXmlProperties(XmlProperties value) {
        this.xmlProperties = value;
    }

    /**
     * Gets the value of the xmlJoinNodes 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</CODE> method for the xmlJoinNodes property.
     *
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getXmlJoinNodes().add(newItem);
     * </pre>
     *
     *
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link XmlJoinNodes }
     *
     *
     */
    public List<XmlJoinNodes> getXmlJoinNodes() {
        if (xmlJoinNodes == null) {
            xmlJoinNodes = new ArrayList<XmlJoinNodes>();
        }
        return this.xmlJoinNodes;
    }

    /**
     * Indicates if xmlJoinNodes has been set, i.e. has non-zero size.
     *
     * @return true if xmlJoinNodes has been set, i.e. there are one or
     * more entries, false otherwise
     */
    public boolean hasXmlJoinNodes() {
        return getXmlJoinNodes().size() > 0;
    }

    /**
     * Gets the value of the xmlIdref property.
     *
     * @return
     *     possible object is
     *     {@link Boolean }
     *
     */
    public boolean isXmlIdref() {
        if (xmlIdref == null) {
            return false;
        } else {
            return xmlIdref;
        }
    }

    /**
     * Sets the value of the xmlIdref property.
     *
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *
     */
    public void setXmlIdref(Boolean value) {
        this.xmlIdref = value;
    }

    /**
     * Gets the value of the xmlList property.
     *
     * @return
     *     possible object is
     *     {@link Boolean }
     *
     */
    public boolean isXmlList() {
        if (xmlList == null) {
            return false;
        } else {
            return xmlList;
        }
    }

    /**
     * Sets the value of the xmlList property.
     *
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *
     */
    public void setXmlList(Boolean value) {
        this.xmlList = value;
    }

    /**
     * Gets the value of the readOnly property.
     *
     * @return
     *     possible object is
     *     {@link Boolean }
     *
     */
    public boolean isReadOnly() {
        if (readOnly == null) {
            return false;
        } else {
            return readOnly;
        }
    }

    /**
     * Sets the value of the readOnly property.
     *
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *
     */
    public void setReadOnly(Boolean value) {
        this.readOnly = value;
    }

    /**
     * Indicates if readOnly has been set, i.e. is non-null.
     *
     * @return true if readOnly has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetReadOnly() {
        return this.readOnly != null;
    }

    /**
     * Gets the value of the writeOnly property.
     *
     * @return
     *     possible object is
     *     {@link Boolean }
     *
     */
    public boolean isWriteOnly() {
        if (writeOnly == null) {
            return false;
        } else {
            return writeOnly;
        }
    }

    /**
     * Sets the value of the writeOnly property.
     *
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *
     */
    public void setWriteOnly(Boolean value) {
        this.writeOnly = value;
    }

    /**
     * Indicates if writeOnly has been set, i.e. is non-null.
     *
     * @return true if writeOnly has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetWriteOnly() {
        return this.writeOnly != null;
    }

    /**
     * Gets the value of the containerType property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getContainerType() {
        if (containerType == null) {
            return "##default";
        } else {
            return containerType;
        }
    }

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

}
