/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package javax.xml.soap;

import javax.xml.namespace.QName;
import java.util.Iterator;

/**
 * An object representing the contents in a <code>SOAPBody</code> object, the contents in a
 * <code>SOAPHeader</code> object, the content that can follow the <code>SOAPBody</code> object in a
 * <code>SOAPEnvelope</code> object, or what can follow the detail element in a
 * <code>SOAPFault</code> object. It is the base class for all of the classes that represent the
 * SOAP objects as defined in the SOAP specification.
 */
public interface SOAPElement extends javax.xml.soap.Node, org.w3c.dom.Element {

    /**
     * Creates a new <code>SOAPElement</code> object initialized with the given <code>Name</code>
     * object and adds the new element to this <code>SOAPElement</code> object.
     *
     * @param name a <code>Name</code> object with the XML name for the new element
     * @return the new <code>SOAPElement</code> object that was created
     * @throws SOAPException if there is an error in creating the <code>SOAPElement</code> object
     */
    public abstract SOAPElement addChildElement(Name name) throws SOAPException;

    /**
     * Creates a new <code>SOAPElement</code> object initialized with the given <code>String</code>
     * object and adds the new element to this <code>SOAPElement</code> object.
     *
     * @param localName a <code>String</code> giving the local name for the element
     * @return the new <code>SOAPElement</code> object that was created
     * @throws SOAPException if there is an error in creating the <code>SOAPElement</code> object
     */
    public abstract SOAPElement addChildElement(String localName)
            throws SOAPException;

    /**
     * Creates a new <code>SOAPElement</code> object initialized with the specified local name and
     * prefix and adds the new element to this <code>SOAPElement</code> object.
     *
     * @param localName a <code>String</code> giving the local name for the new element
     * @param prefix    a <code>String</code> giving the namespace prefix for the new element
     * @return the new <code>SOAPElement</code> object that was created
     * @throws SOAPException if there is an error in creating the <code>SOAPElement</code> object
     */
    public abstract SOAPElement addChildElement(String localName,
                                                String prefix)
            throws SOAPException;

    /**
     * Creates a new <code>SOAPElement</code> object initialized with the specified local name,
     * prefix, and URI and adds the new element to this <code>SOAPElement</code> object.
     *
     * @param localName a <code>String</code> giving the local name for the new element
     * @param prefix    a <code>String</code> giving the namespace prefix for the new element
     * @param uri       a <code>String</code> giving the URI of the namespace to which the new
     *                  element belongs
     * @return the new <code>SOAPElement</code> object that was created
     * @throws SOAPException if there is an error in creating the <code>SOAPElement</code> object
     */
    public abstract SOAPElement addChildElement(String localName,
                                                String prefix,
                                                String uri) throws SOAPException;

    /**
     * Add a <code>SOAPElement</code> as a child of this <code>SOAPElement</code> instance. The
     * <code>SOAPElement</code> is expected to be created by a <code>SOAPElementFactory</code>.
     * Callers should not rely on the element instance being added as is into the XML tree.
     * Implementations could end up copying the content of the <code>SOAPElement</code> passed into
     * an instance of a different <code>SOAPElement</code> implementation. For instance if
     * <code>addChildElement()</code> is called on a <code>SOAPHeader</code>, <code>element</code>
     * will be copied into an instance of a <code>SOAPHeaderElement</code>.
     * <p/>
     * <P>The fragment rooted in <code>element</code> is either added as a whole or not at all, if
     * there was an error.
     * <p/>
     * <P>The fragment rooted in <code>element</code> cannot contain elements named "Envelope",
     * "Header" or "Body" and in the SOAP namespace. Any namespace prefixes present in the fragment
     * should be fully resolved using appropriate namespace declarations within the fragment
     * itself.
     *
     * @param element the <code>SOAPElement</code> to be added as a new child
     * @return an instance representing the new SOAP element that was actually added to the tree.
     * @throws SOAPException if there was an error in adding this element as a child
     */
    public abstract SOAPElement addChildElement(SOAPElement element)
            throws SOAPException;

    /**
     * Creates a new <code>Text</code> object initialized with the given <code>String</code> and
     * adds it to this <code>SOAPElement</code> object.
     *
     * @param text a <code>String</code> object with the textual content to be added
     * @return the <code>SOAPElement</code> object into which the new <code>Text</code> object was
     *         inserted
     * @throws SOAPException if there is an error in creating the new <code>Text</code> object
     */
    public abstract SOAPElement addTextNode(String text) throws SOAPException;

    /**
     * Adds an attribute with the specified name and value to this <code>SOAPElement</code> object.
     * <p/>
     *
     * @param name  a <code>Name</code> object with the name of the attribute
     * @param value a <code>String</code> giving the value of the attribute
     * @return the <code>SOAPElement</code> object into which the attribute was inserted
     * @throws SOAPException if there is an error in creating the Attribute
     */
    public abstract SOAPElement addAttribute(Name name, String value)
            throws SOAPException;

    /**
     * Adds a namespace declaration with the specified prefix and URI to this
     * <code>SOAPElement</code> object.
     * <p/>
     *
     * @param prefix a <code>String</code> giving the prefix of the namespace
     * @param uri    a <CODE>String</CODE> giving the prefix of the namespace
     * @return the <code>SOAPElement</code> object into which this namespace declaration was
     *         inserted.
     * @throws SOAPException if there is an error in creating the namespace
     */
    public abstract SOAPElement addNamespaceDeclaration(String prefix,
                                                        String uri) throws SOAPException;

    /**
     * Returns the value of the attribute with the specified name.
     *
     * @param name a <CODE>Name</CODE> object with the name of the attribute
     * @return a <CODE>String</CODE> giving the value of the specified attribute
     */
    public abstract String getAttributeValue(Name name);

    /**
     * Returns an iterator over all of the attribute names in this <CODE>SOAPElement</CODE> object.
     * The iterator can be used to get the attribute names, which can then be passed to the method
     * <CODE>getAttributeValue</CODE> to retrieve the value of each attribute.
     *
     * @return an iterator over the names of the attributes
     */
    public abstract Iterator getAllAttributes();

    /**
     * Returns the URI of the namespace that has the given prefix.
     *
     * @param prefix a <CODE>String</CODE> giving the prefix of the namespace for which to search
     * @return a <CODE>String</CODE> with the uri of the namespace that has the given prefix
     */
    public abstract String getNamespaceURI(String prefix);

    /**
     * Returns an iterator of namespace prefixes. The iterator can be used to get the namespace
     * prefixes, which can then be passed to the method <CODE>getNamespaceURI</CODE> to retrieve the
     * URI of each namespace.
     *
     * @return an iterator over the namespace prefixes in this <CODE>SOAPElement</CODE> object
     */
    public abstract Iterator getNamespacePrefixes();

    /**
     * Returns the name of this <CODE>SOAPElement</CODE> object.
     *
     * @return a <CODE>Name</CODE> object with the name of this <CODE>SOAPElement</CODE> object
     */
    public abstract Name getElementName();

    /**
     * Removes the attribute with the specified name.
     *
     * @param name the <CODE>Name</CODE> object with the name of the attribute to be removed
     * @return <CODE>true</CODE> if the attribute was removed successfully; <CODE>false</CODE> if it
     *         was not
     */
    public abstract boolean removeAttribute(Name name);

    /**
     * Removes the namespace declaration corresponding to the given prefix.
     *
     * @param prefix a <CODE>String</CODE> giving the prefix for which to search
     * @return <CODE>true</CODE> if the namespace declaration was removed successfully;
     *         <CODE>false</CODE> if it was not
     */
    public abstract boolean removeNamespaceDeclaration(String prefix);

    /**
     * Returns an iterator over all the immediate content of this element. This includes
     * <CODE>Text</CODE> objects as well as <CODE>SOAPElement</CODE> objects.
     *
     * @return an iterator with the content of this <CODE> SOAPElement</CODE> object
     */
    public abstract Iterator getChildElements();

    /**
     * Returns an iterator over all the child elements with the specified name.
     *
     * @param name a <CODE>Name</CODE> object with the name of the child elements to be returned
     * @return an <CODE>Iterator</CODE> object over all the elements in this
     *         <CODE>SOAPElement</CODE> object with the specified name
     */
    public abstract Iterator getChildElements(Name name);

    /**
     * Sets the encoding style for this <CODE>SOAPElement</CODE> object to one specified.
     *
     * @param encodingStyle a <CODE>String</CODE> giving the encoding style
     * @throws IllegalArgumentException
     *          if there was a problem in the encoding style being set.
     * @see #getEncodingStyle() getEncodingStyle()
     */
    public abstract void setEncodingStyle(String encodingStyle)
            throws SOAPException;

    /**
     * Returns the encoding style for this <CODE> SOAPElement</CODE> object.
     *
     * @return a <CODE>String</CODE> giving the encoding style
     * @see #setEncodingStyle(String) setEncodingStyle(java.lang.String)
     */
    public abstract String getEncodingStyle();

    /**
     * Detaches all children of this <code>SOAPElement</code>.
     * <p/>
     * This method is useful for rolling back the construction of partially completed
     * <code>SOAPHeaders</code> and <code>SOAPBodys</code> in reparation for sending a fault when an
     * error condition is detected. It is also useful for recycling portions of a document within a
     * SOAP message.
     */
    public abstract void removeContents();

    /**
     * Returns an <code>Iterator</code> over the namespace prefix <code>String</code>s visible to
     * this element. The prefixes returned by this iterator can be passed to the method
     * <code>getNamespaceURI()</code> to retrieve the URI of each namespace.
     *
     * @return an iterator over the namespace prefixes are within scope of this
     *         <code>SOAPElement</code> object
     */
    public abstract Iterator getVisibleNamespacePrefixes();

    public abstract SOAPElement addAttribute(javax.xml.namespace.QName qname,
                                             java.lang.String value)
            throws SOAPException;

    public abstract SOAPElement addChildElement(javax.xml.namespace.QName qname)
            throws SOAPException;

    public abstract javax.xml.namespace.QName createQName(String localName, String prefix)
            throws SOAPException;

    public abstract java.util.Iterator getAllAttributesAsQNames();

    public abstract java.lang.String getAttributeValue(javax.xml.namespace.QName qname);

    public abstract java.util.Iterator getChildElements(QName name);

    public abstract javax.xml.namespace.QName getElementQName();

    boolean removeAttribute(javax.xml.namespace.QName qname);

    public abstract SOAPElement setElementQName(javax.xml.namespace.QName newName)
            throws SOAPException;
}
