//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.1.5-b01-fcs 
// 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: 2008.07.15 at 04:13:34 PM PDT 
//


package org.apache.geronimo.components.jaspi.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.security.auth.message.config.ClientAuthContext;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.module.ClientAuthModule;
import javax.security.auth.Subject;


/**
 * <p>Java class for clientAuthContextType complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="clientAuthContextType">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="messageLayer" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="appContext" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="authenticationContextID" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         &lt;element name="clientAuthModule" type="{http://geronimo.apache.org/xml/ns/geronimo-jaspi}authModuleType" maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "clientAuthContextType", propOrder = {
    "messageLayer",
    "appContext",
    "authenticationContextID",
    "clientAuthModule"
})
public class ClientAuthContextType
    implements ClientAuthContext, Serializable
{

    private final static long serialVersionUID = 12343L;
    protected String messageLayer;
    protected String appContext;
    @XmlElement(required = true)
    protected String authenticationContextID;
    protected List<AuthModuleType<ClientAuthModule>> clientAuthModule;

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

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

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

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

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

    public String getAuthenticationContextID(MessageInfo messageInfo) {
        return authenticationContextID;
    }

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

    /**
     * Gets the value of the clientAuthModule 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 clientAuthModule property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getClientAuthModule().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link AuthModuleType }
     * 
     *
     * @return list of client auth module wrappers
     */
    public List<AuthModuleType<ClientAuthModule>> getClientAuthModule() {
        if (clientAuthModule == null) {
            clientAuthModule = new ArrayList<AuthModuleType<ClientAuthModule>>();
        }
        return this.clientAuthModule;
    }

    public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException {
        for (AuthModuleType<ClientAuthModule> authModuleType: getClientAuthModule()) {
            ClientAuthModule clientAuthModule = authModuleType.getAuthModule();
            clientAuthModule.cleanSubject(messageInfo, subject);
        }
    }

    public AuthStatus secureRequest(MessageInfo messageInfo, Subject clientSubject) throws AuthException {
        for (AuthModuleType<ClientAuthModule> authModuleType: getClientAuthModule()) {
            ClientAuthModule clientAuthModule = authModuleType.getAuthModule();
            AuthStatus result = clientAuthModule.secureRequest(messageInfo, clientSubject);

            //jaspi spec p 74
            if (result == AuthStatus.SUCCESS) {
                continue;
            }
            if (result == AuthStatus.SEND_CONTINUE || result == AuthStatus.FAILURE) {
                return result;
            }
            throw new AuthException("Invalid AuthStatus " + result + " from client auth module: " + clientAuthModule);
        }
        return AuthStatus.SUCCESS;
    }

    public AuthStatus validateResponse(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {
        for (AuthModuleType<ClientAuthModule> authModuleType: getClientAuthModule()) {
            ClientAuthModule clientAuthModule = authModuleType.getAuthModule();
            AuthStatus result = clientAuthModule.validateResponse(messageInfo, clientSubject, serviceSubject);

            //jaspi spec p 74
            if (result == AuthStatus.SUCCESS) {
                continue;
            }
            if (result == AuthStatus.SEND_CONTINUE || result == AuthStatus.FAILURE) {
                return result;
            }
            throw new AuthException("Invalid AuthStatus " + result + " from client auth module: " + clientAuthModule);
        }
        return AuthStatus.SUCCESS;
    }
}
