/*
 * 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 org.apache.axis2.saaj;

import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axiom.soap.SOAPVersion;

import jakarta.xml.soap.SOAPElement;
import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPHeader;
import jakarta.xml.soap.SOAPHeaderElement;

public class SOAPHeaderElementImpl extends SOAPElementImpl<SOAPHeaderBlock> implements SOAPHeaderElement {

    /** @param element  */
    public SOAPHeaderElementImpl(SOAPHeaderBlock element) {
        super(element);
    }

    /**
     * Sets the actor associated with this <CODE> SOAPHeaderElement</CODE> object to the specified
     * actor. The default value of an actor is: <CODE> SOAPConstants.URI_SOAP_ACTOR_NEXT</CODE>
     *
     * @param actorURI a <CODE>String</CODE> giving the URI of the actor to set
     * @throws IllegalArgumentException
     *          if there is a problem in setting the actor.
     * @see #getActor() getActor()
     */
    public void setActor(String actorURI) {
        this.omTarget.setRole(actorURI);
    }

    /**
     * Returns the uri of the actor associated with this <CODE> SOAPHeaderElement</CODE> object.
     *
     * @return a <CODE>String</CODE> giving the URI of the actor
     * @see #setActor(String) setActor(java.lang.String)
     */
    public String getActor() {
        return this.omTarget.getRole();
    }

    /**
     * Sets the mustUnderstand attribute for this <CODE> SOAPHeaderElement</CODE> object to be on or
     * off.
     * <p/>
     * <P>If the mustUnderstand attribute is on, the actor who receives the
     * <CODE>SOAPHeaderElement</CODE> must process it correctly. This ensures, for example, that if
     * the <CODE> SOAPHeaderElement</CODE> object modifies the message, that the message is being
     * modified correctly.</P>
     *
     * @param mustUnderstand <CODE>true</CODE> to set the mustUnderstand attribute on;
     *                       <CODE>false</CODE> to turn if off
     * @throws IllegalArgumentException
     *          if there is a problem in setting the actor.
     * @see #getMustUnderstand() getMustUnderstand()
     */
    public void setMustUnderstand(boolean mustUnderstand) {
        this.omTarget.setMustUnderstand(mustUnderstand);
    }

    /**
     * Returns whether the mustUnderstand attribute for this <CODE>SOAPHeaderElement</CODE> object
     * is turned on.
     *
     * @return <CODE>true</CODE> if the mustUnderstand attribute of this
     *         <CODE>SOAPHeaderElement</CODE> object is turned on; <CODE>false</CODE> otherwise
     */
    public boolean getMustUnderstand() {
        return this.omTarget.getMustUnderstand();
    }

    /**
     * Sets the Role associated with this SOAPHeaderElement object to the specified Role.
     *
     * @param uri - the URI of the Role
     * @throws SOAPException - if there is an error in setting the role java.lang.UnsupportedOperationException
     *                       - if this message does not support the SOAP 1.2 concept of Fault Role.
     */
    public void setRole(String uri) throws SOAPException {
        if (((SOAPFactory)this.omTarget.getOMFactory()).getSOAPVersion() == SOAPVersion.SOAP11) {
            throw new UnsupportedOperationException();
        } else {
            this.omTarget.setRole(uri);
        }
    }

    public String getRole() {
        if (((SOAPFactory)this.omTarget.getOMFactory()).getSOAPVersion() == SOAPVersion.SOAP11) {
            throw new UnsupportedOperationException();
        } else {
            return this.omTarget.getRole();
        }
    }

    /**
     * Sets the relay attribute for this SOAPHeaderElement to be either true or false. The SOAP
     * relay attribute is set to true to indicate that the SOAP header block must be relayed by any
     * node that is targeted by the header block but not actually process it. This attribute is
     * ignored on header blocks whose mustUnderstand attribute is set to true or that are targeted
     * at the ultimate reciever (which is the default). The default value of this attribute is
     * false.
     *
     * @param relay - the new value of the relay attribute
     * @throws SOAPException - if there is a problem in setting the relay attribute.
     *                       java.lang.UnsupportedOperationException - if this message does not
     *                       support the SOAP 1.2 concept of Relay attribute.
     */
    public void setRelay(boolean flag) throws SOAPException {
        if (((SOAPFactory)this.omTarget.getOMFactory()).getSOAPVersion() == SOAPVersion.SOAP11) {
            throw new UnsupportedOperationException();
        } else {
            this.omTarget.setRelay(flag);
        }
    }

    public boolean getRelay() {
        if (((SOAPFactory)this.omTarget.getOMFactory()).getSOAPVersion() == SOAPVersion.SOAP11) {
            throw new UnsupportedOperationException();
        } else {
            return this.omTarget.getRelay();
        }
    }

    public void setParentElement(SOAPElement parent) throws SOAPException {
        if (!(parent instanceof SOAPHeader)) {
            throw new IllegalArgumentException("Parent is not a SOAPHeader");
        }
        super.setParentElement(parent);
    }
}
