
/*
 * 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.
 */

#include <axis2_handler.h>
#include <axis2_handler_desc.h>

struct axis2_handler
{

    /** handler description. This is a reference, hence a shallow copy. */
    axis2_handler_desc_t *handler_desc;

    /**
     * Invoke is called to do the actual work assigned to the handler.
     * The phase that owns the handler is responsible for calling invoke
     * on top of the handler. Those structs that implement the interface 
     * of the handler should implement the logic for invoke and assign the
     * respective function pointer to invoke operation.
     * @param handler pointer to handler
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
     axis2_status_t(
    AXIS2_CALL * invoke) (
    axis2_handler_t * handler,
    const axutil_env_t * env,
    struct axis2_msg_ctx * msg_ctx);
};

AXIS2_EXTERN axis2_handler_t *AXIS2_CALL
axis2_handler_create(
    const axutil_env_t * env)
{
    axis2_handler_t *handler = NULL;

    handler = AXIS2_MALLOC(env->allocator, sizeof(axis2_handler_t));
    if (!handler)
    {
        AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY);
        AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
        return NULL;
    }

    handler->handler_desc = NULL;

    return handler;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_handler_free(
    axis2_handler_t * handler,
    const axutil_env_t * env)
{
    AXIS2_FREE(env->allocator, handler);
    return;
}

AXIS2_EXTERN const axutil_string_t *AXIS2_CALL
axis2_handler_get_name(
    const axis2_handler_t * handler,
    const axutil_env_t * env)
{
    if (!(handler->handler_desc))
        return NULL;

    return axis2_handler_desc_get_name(handler->handler_desc, env);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_handler_invoke(
    axis2_handler_t * handler,
    const axutil_env_t * env,
    struct axis2_msg_ctx * msg_ctx)
{
    return handler->invoke(handler, env, msg_ctx);
}

AXIS2_EXTERN axutil_param_t *AXIS2_CALL
axis2_handler_get_param(
    const axis2_handler_t * handler,
    const axutil_env_t * env,
    const axis2_char_t * name)
{
    if (!(handler->handler_desc))
        return NULL;

    return axis2_handler_desc_get_param(handler->handler_desc, env, name);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_handler_init(
    axis2_handler_t * handler,
    const axutil_env_t * env,
    axis2_handler_desc_t * handler_desc)
{
    handler->handler_desc = handler_desc;
    axis2_handler_desc_set_handler(handler_desc, env, handler);

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_handler_desc_t *AXIS2_CALL
axis2_handler_get_handler_desc(
    const axis2_handler_t * handler,
    const axutil_env_t * env)
{
    return handler->handler_desc;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_handler_set_invoke(
    axis2_handler_t * handler,
    const axutil_env_t * env,
    AXIS2_HANDLER_INVOKE func)
{
    handler->invoke = func;
    return AXIS2_SUCCESS;
}

