/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed 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.rampart.handler;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.HandlerDescription;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.engine.Handler;
import org.apache.rampart.util.Axis2Util;
import org.apache.ws.security.handler.WSHandler;

/**
 * Class WSDoAllHandler
 */
public abstract class WSDoAllHandler extends WSHandler implements Handler {

    /**
     * Field EMPTY_HANDLER_METADATA
     */
    private static HandlerDescription EMPTY_HANDLER_METADATA =
            new HandlerDescription("default Handler");

    private final static String WSS_PASSWORD = "password";

    private final static String WSS_USERNAME = "username";

    /**
     * Field handlerDesc
     */
    protected HandlerDescription handlerDesc;

    /**
     * In Axis2, the user cannot set inflow and outflow parameters.
     * Therefore, we need to map the Axis2 specific inflow and outflow
     * parameters to WSS4J params,
     * <p/>
     * Knowledge of inhandler and out handler is used to get the mapped value.
     */
    protected boolean inHandler;

    /**
     * Constructor AbstractHandler.
     */
    public WSDoAllHandler() {
        handlerDesc = EMPTY_HANDLER_METADATA;
    }

    public abstract void processMessage(MessageContext msgContext) throws AxisFault;

    /* (non-Javadoc)
    * @see org.apache.axis2.engine.Handler#invoke(org.apache.axis2.context.MessageContext)
    */
    public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
        //If the security module is not engaged for this service
        //do not do any processing
        if (msgContext.isEngaged(WSSHandlerConstants.SECURITY_MODULE_NAME)) {
            this.processMessage(msgContext);
        }
        return InvocationResponse.CONTINUE;        
    }

    public void flowComplete(MessageContext msgContext)
    {
    }
    
    /**
     * Method getName.
     *
     * @return Returns name.
     */
    public String getName() {
        return handlerDesc.getName();
    }

    /**
     * Method cleanup.
     */
    public void cleanup() {
    }

    /**
     * Method getParameter.
     *
     * @param name
     * @return Returns parameter.
     */
    public Parameter getParameter(String name) {
        return handlerDesc.getParameter(name);
    }

    /**
     * Method init.
     *
     * @param handlerdesc
     */
    public void init(HandlerDescription handlerdesc) {
        this.handlerDesc = handlerdesc;
    }

    /**
     * Gets the handler description.
     *
     * @return Returns handler description.
     */
    public HandlerDescription getHandlerDesc() {
        return handlerDesc;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    public String toString() {
        String name = this.getName();
        return (name != null) ? name : "";
    }


    public Object getProperty(Object msgContext, String axisKey) {

        int repetition = getCurrentRepetition(msgContext);

        String key = Axis2Util.getKey(axisKey, inHandler, repetition);
        Object property = ((MessageContext) msgContext).getProperty(key);
        if (property == null) {
            //Try the description hierarchy
            Parameter parameter = ((MessageContext) msgContext).getParameter(key);
            if (parameter != null) {
                property = parameter.getValue();
            }
        }
        return property;
    }

    /**
     * Returns the repetition number from the message context
     *
     * @param msgContext
     * @return Returns int.
     */
    protected int getCurrentRepetition(Object msgContext) {
        //get the repetition from the message context
        int repetition = 0;
        if (!inHandler) {//We only need to repeat the out handler
            Integer count = (Integer) ((MessageContext) msgContext).getProperty(WSSHandlerConstants.CURRENT_REPETITON);
            if (count != null) { //When we are repeating the handler
                repetition = count.intValue();
            }
        }
        return repetition;
    }

    public String getPassword(Object msgContext) {
        return (String) ((MessageContext) msgContext).getProperty(WSS_PASSWORD);
    }

    public void setPassword(Object msgContext, String password) {
        ((MessageContext) msgContext).setProperty(WSS_PASSWORD, password);
    }

    public String getUsername(Object msgContext) {
        return (String) ((MessageContext) msgContext).getProperty(WSS_USERNAME);
    }

    public void setUsername(Object msgContext, String username) {
        ((MessageContext) msgContext).setProperty(WSS_USERNAME, username);
    }

    /**
     * Gets option. Extracts the configuration values from the service.xml
     * and/or axis2.xml. Values set in the service.xml takes priority over
     * values of the axis2.xml
     */
    public Object getOption(String axisKey) {
        Parameter parameter = this.handlerDesc.getParameter(axisKey);
        return (parameter == null) ? null : parameter.getValue();
    }

    public void setProperty(Object msgContext, String key, Object value) {
        ((MessageContext) msgContext).setProperty(key, value);
    }

    /**
     * Overrides the class loader used to load the PW callback class.
     *
     * @param msgCtx MessageContext
     * @return Returns class loader.
     */
    public java.lang.ClassLoader getClassLoader(Object msgCtx) {
        try {
            return ((MessageContext) msgCtx).getAxisService().getClassLoader();
        } catch (Throwable t) {
            return super.getClassLoader(msgCtx);
        }
    }
}
