
/*
 * 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 "_axiom_soap_fault_node.h"
#include <axiom_node.h>
#include <axiom_element.h>
#include "_axiom_soap_fault.h"

struct axiom_soap_fault_node
{
    axiom_node_t *om_ele_node;
};

AXIS2_EXTERN axiom_soap_fault_node_t *AXIS2_CALL
axiom_soap_fault_node_create(
    const axutil_env_t * env)
{
    axiom_soap_fault_node_t *fault_node = NULL;

    fault_node = (axiom_soap_fault_node_t *) AXIS2_MALLOC(env->allocator,
                                                          sizeof
                                                          (axiom_soap_fault_node_t));

    if (!fault_node)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                          "No memory. Cannot create a SOAP fault node");
        return NULL;
    }
    fault_node->om_ele_node = NULL;

    return fault_node;
}

AXIS2_EXTERN axiom_soap_fault_node_t *AXIS2_CALL
axiom_soap_fault_node_create_with_parent(
    const axutil_env_t * env,
    axiom_soap_fault_t * fault)
{
    axiom_soap_fault_node_t *fault_node = NULL;
    axiom_element_t *this_ele = NULL;
    axiom_node_t *this_node = NULL;

    axiom_node_t *parent_node = NULL;
    axiom_element_t *parent_ele = NULL;

    axiom_namespace_t *parent_ns = NULL;

    AXIS2_PARAM_CHECK(env->error, fault, NULL);

    fault_node = axiom_soap_fault_node_create(env);
    if (!fault_node)
    {
        return NULL;
    }
    parent_node = axiom_soap_fault_get_base_node(fault, env);
    if (!parent_node)
    {
        axiom_soap_fault_node_free(fault_node, env);
        return NULL;
    }

    parent_ele =
        (axiom_element_t *) axiom_node_get_data_element(parent_node, env);
    if (!parent_ele)
    {
        axiom_soap_fault_node_free(fault_node, env);
        return NULL;
    }

    parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node);

    this_ele = axiom_element_create(env,
                                    parent_node,
                                    AXIOM_SOAP12_SOAP_FAULT_NODE_LOCAL_NAME,
                                    parent_ns, &this_node);

    if (!this_ele)
    {
        axiom_soap_fault_node_free(fault_node, env);
        return NULL;
    }

    fault_node->om_ele_node = this_node;

    axiom_soap_fault_set_node(fault, env, fault_node);

    return fault_node;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_soap_fault_node_free(
    axiom_soap_fault_node_t * fault_node,
    const axutil_env_t * env)
{
    AXIS2_FREE(env->allocator, fault_node);
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_fault_node_set_value(
    axiom_soap_fault_node_t * fault_node,
    const axutil_env_t * env,
    axis2_char_t * uri)
{
    axiom_element_t *om_ele = NULL;

    AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE);

    if (fault_node->om_ele_node)
    {
        om_ele =
            (axiom_element_t *) axiom_node_get_data_element(fault_node->
                                                            om_ele_node, env);

        if (om_ele)
        {
            return axiom_element_set_text(om_ele, env, uri,
                                          fault_node->om_ele_node);
        }
    }

    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_soap_fault_node_get_value(
    axiom_soap_fault_node_t * fault_node,
    const axutil_env_t * env)
{
    axiom_element_t *om_ele = NULL;

    if (fault_node->om_ele_node)
    {
        om_ele =
            (axiom_element_t *) axiom_node_get_data_element(fault_node->
                                                            om_ele_node, env);
        if (om_ele)
        {
            return axiom_element_get_text(om_ele, env, fault_node->om_ele_node);
        }

    }
    return NULL;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_fault_node_set_base_node(
    axiom_soap_fault_node_t * fault_node,
    const axutil_env_t * env,
    axiom_node_t * node)
{
    AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE);
    if (axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)
    {
        AXIS2_HANDLE_ERROR(env,
                        AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    fault_node->om_ele_node = node;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_soap_fault_node_get_base_node(
    axiom_soap_fault_node_t * fault_node,
    const axutil_env_t * env)
{
    return fault_node->om_ele_node;
}
