blob: 0f95cbb29c2b5a6abdeb2d326bbe4a26632197f0 [file] [log] [blame]
/*
* 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_element_internal.h"
#include "axiom_node_internal.h"
#include <axiom_attribute.h>
#include <axiom_namespace.h>
#include <axiom_xml_writer.h>
#include <axiom_stax_builder.h>
#include <string.h>
#include <stdio.h>
struct axiom_element
{
/** Element's namespace */
axiom_namespace_t *ns;
/** Element's local name */
axutil_string_t *localname;
/** List of attributes */
axutil_hash_t *attributes;
/** List of other namespaces */
axutil_hash_t *namespaces;
/* denotes whether current element is an empty element. i.e. <element/>
* Used only when writing the output */
axis2_bool_t is_empty;
/* Following members are kept as a result of some operations. Reason for keeping them is,
* (1) we can free them without memory leak
* (2) Improve the performance, so that we don't need to re-do the calculation again
*/
axutil_qname_t *qname; /* result of axiom_element_get_qname */
axiom_child_element_iterator_t *child_ele_iter; /* result of axiom_element_get_child_elements*/
axiom_children_iterator_t *children_iter; /* result of axiom_element_get_children */
axiom_children_qname_iterator_t *children_qname_iter; /*axiom_element_get_children_with_qname */
axis2_char_t *text_value; /* result of axiom_element_get_text */
};
/**
* Creates an AXIOM element with given local name
*
* @param env Environment. MUST NOT be NULL.
* @param parent parent of the element node to be created. can be NULL.
* @param localname local name of the element. cannot be NULL.
* @param ns namespace of the element. can be NULL.
* If the value of the namespace has not already been declared
* then the namespace structure ns will be cloned and declared and will be
* freed when the tree is freed.
* Caller has to delete the original ns object passed to the method.
* @param node This is an out parameter. cannot be NULL.
* Returns the node corresponding to the comment created.
* Node type will be set to AXIOM_ELEMENT
*
* @return a pointer to the newly created element struct
*/
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_create(
const axutil_env_t * env,
axiom_node_t * parent,
const axis2_char_t * localname,
axiom_namespace_t * ns,
axiom_node_t ** node)
{
axiom_element_t *element;
AXIS2_ASSERT(localname != NULL);
AXIS2_ASSERT(node != NULL);
AXIS2_ASSERT(env != NULL);
(*node) = axiom_node_create(env);
if (!(*node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create axiom node needed by element");
return NULL;
}
element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t));
if (!element)
{
axiom_node_free_tree(*node, env);
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create axiom element");
return NULL;
}
memset(element, 0, sizeof(axiom_element_t));
element->localname = axutil_string_create(env, localname);
if (!element->localname)
{
AXIS2_FREE(env->allocator, element);/* Still we haven't set the data element. so, we have */
axiom_node_free_tree(*node, env); /* to free node and element separately */
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create string to store local name");
return NULL;
}
if (parent)
axiom_node_add_child(parent, env, (*node));
axiom_node_set_node_type((*node), env, AXIOM_ELEMENT);
axiom_node_set_data_element((*node), env, element);
if (ns)
{
if (axiom_element_set_namespace(element, env, ns, *node) != AXIS2_SUCCESS)
{
axiom_node_free_tree(*node, env); /* this will internally free axiom element */
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set namespace of element");
return NULL;
}
}
return element;
}
/**
* Creates an AXIOM element with given qname
*
* @param env Environment. MUST NOT be NULL.
* @param parent parent of the element node to be created. can be NULL.
* @param qname qname of the elment.cannot be NULL.
* @param node This is an out parameter. cannot be NULL.
* Returns the node corresponding to the comment created.
* Node type will be set to AXIOM_ELEMENT
*
* @return a pointer to the newly created element struct
*/
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_create_with_qname(
const axutil_env_t * env,
axiom_node_t * parent,
const axutil_qname_t * qname,
axiom_node_t ** node)
{
axiom_element_t *element;
axis2_char_t *localpart;
axis2_char_t *temp_nsuri;
axis2_char_t *temp_prefix;
AXIS2_ASSERT(qname != NULL);
AXIS2_ASSERT(node != NULL);
AXIS2_ASSERT(env != NULL);
localpart = axutil_qname_get_localpart(qname, env);
AXIS2_ASSERT(localpart != NULL);
element = axiom_element_create(env, parent, localpart, NULL, node);
if (!element)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create element with qname");
return NULL;
}
AXIS2_ASSERT(*node != NULL);
temp_nsuri = axutil_qname_get_uri(qname, env);
temp_prefix = axutil_qname_get_prefix(qname, env);
/** if no namespace uri is available in given qname no need to bother about it */
if ((!temp_nsuri) || (axutil_strcmp(temp_nsuri, "") == 0))
return element;
/** if could not find a namespace so declare namespace */
element->ns = axiom_element_find_namespace(element, env, (*node), temp_nsuri, temp_prefix);
if (!element->ns)
{
axiom_namespace_t *ns = axiom_namespace_create(env, temp_nsuri, temp_prefix);
if (!ns)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespace needed by element");
axiom_node_free_tree(*node, env);
*node = NULL;
return NULL;
}
if (axiom_element_declare_namespace(element, env, *node, ns) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare namespace needed by element");
axiom_node_free_tree(*node, env);
*node = NULL;
axiom_namespace_free(ns, env);
return NULL;
}
element->ns = ns;
}
else
{
/* namespace is declared somewhere, but since we are going to keep it, we should
* increment the reference
*/
axiom_namespace_increment_ref(element->ns, env);
}
return element;
}
/**
* Frees given element
*
* @param element AXIOM element to be freed.
* @param env Environment. MUST NOT be NULL.
*
* @return status of the operation. AXIS2_SUCCESS on success ,AXIS2_FAILURE on error.
*/
AXIS2_EXTERN void AXIS2_CALL
axiom_element_free(
axiom_element_t * om_element,
const axutil_env_t * env)
{
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_element->localname != NULL);
axutil_string_free(om_element->localname, env);
if (om_element->ns)
axiom_namespace_free(om_element->ns, env);
if (om_element->attributes)
{
axutil_hash_index_t *hi;
void *val;
for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
{
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
axiom_attribute_free((axiom_attribute_t *)val, env);
}
axutil_hash_free(om_element->attributes, env);
}
if (om_element->namespaces)
{
axutil_hash_index_t *hi;
void *val;
for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi))
{
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
axiom_namespace_free((axiom_namespace_t *)val, env);
}
axutil_hash_free(om_element->namespaces, env);
}
if (om_element->qname)
axutil_qname_free(om_element->qname, env);
if (om_element->children_iter)
axiom_children_iterator_free(om_element->children_iter, env);
if (om_element->child_ele_iter)
axiom_child_element_iterator_free(om_element->child_ele_iter, env);
if (om_element->children_qname_iter)
axiom_children_qname_iterator_free(om_element->children_qname_iter, env);
if (om_element->text_value)
{
AXIS2_FREE(env->allocator, om_element->text_value);
}
AXIS2_FREE(env->allocator, om_element);
}
/**
* finds a namespace in current element's scope, by uri or prefix or both. Will not check in the
* parents, so even it is defined in parent nodes, this method will return NULL if it is not defined
* in element's scope
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param uri namespace uri, may be null
* @param prefix prefix
*
* @return axiom_namespace_t if found, else return NULL
*/
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_declared_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
const axis2_char_t * uri,
const axis2_char_t * prefix)
{
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
if (om_element->namespaces)
{
if (uri && (!prefix || axutil_strcmp(prefix, "") == 0))
{
/** prefix is null , so iterate the namespaces hash to find the namespace */
axutil_hash_index_t *hashindex;
for(hashindex = axutil_hash_first(om_element->namespaces, env); hashindex;
hashindex = axutil_hash_next(env, hashindex))
{
void *ns = NULL;
axutil_hash_this(hashindex, NULL, NULL, &ns);
if (ns)
{
axiom_namespace_t *temp_ns = (axiom_namespace_t *)ns;
axis2_char_t *temp_nsuri = axiom_namespace_get_uri(temp_ns, env);
if (axutil_strcmp(temp_nsuri, uri) == 0)
{
/** namespace uri matches, so free hash index and return ns*/
AXIS2_FREE(env->allocator, hashindex);
return temp_ns;
}
}
}
}
else if (prefix)
{
/** prefix is not null get namespace directly if exist */
axiom_namespace_t *ns = (axiom_namespace_t *)axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING);
if (ns)
{
/* if uri provided, return found ns only if uri matches */
if ((uri) && (axutil_strcmp(axiom_namespace_get_uri(ns, env), uri) != 0))
ns = NULL;
return ns;
}
}
}
return NULL;
}
/**
* Find a namespace in the scope of the document.
* Start to find from the given node and go up the hierarchy.
*
* @param om_element pointer to om_element_struct contained in node ,
* @param env Environment. MUST NOT be NULL.
* @param node node containing an instance of an AXIOM element,cannot be NULL.
* @param uri namespace uri..
* @param prefix namespace prefix. can be NULL.
*
* @return pointer to the namespace, if found, else NULL. On error, returns
* NULL and sets error code in environment,s error
*/
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node,
const axis2_char_t * uri,
const axis2_char_t * prefix)
{
axiom_node_t *parent;
axiom_namespace_t *ns;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(element_node != NULL);
/* check whether we can find the namespace in current element scope */
ns = axiom_element_find_declared_namespace(om_element, env, uri, prefix);
if (ns)
return ns;
/* could not find the namespace in current element scope look in the parent */
parent = axiom_node_get_parent(element_node, env);
if ((parent) && (axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT))
{
axiom_element_t *om_element;
om_element = (axiom_element_t *)axiom_node_get_data_element(parent, env);
if (om_element)
{
/** parent exist, parent is om element so find in parent*/
return axiom_element_find_namespace(om_element, env, parent, uri, prefix);
}
}
return NULL;
}
/**
* Finds a namespace using qname. Start to find from the given node and go up the hierarchy.
*
* @param om_element om_element contained in node
* @param env Environment. MUST NOT be NULL.
* @param node node containing an instance of an AXIOM element, cannot be NULL.
* @param qname qname of the namespace to be found. cannot be NULL.
*
* @return pointer to the namespace, if found, else NULL. On error, returns
* NULL and sets the error code in environment's error struct.
*/
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_namespace_with_qname(
axiom_element_t * element,
const axutil_env_t * env,
axiom_node_t * node,
axutil_qname_t * qname)
{
AXIS2_ASSERT(qname != NULL);
AXIS2_ASSERT(axutil_qname_get_uri(qname, env) != NULL);
return axiom_element_find_namespace(element, env, node,
axutil_qname_get_uri(qname, env),
axutil_qname_get_prefix(qname, env));
}
/**
* Declare a namespace in current element (in the scope of this element ).
* It checks to see if it is already declared at this level or in its ancestors
*
* @param om_element contained in the om node struct
* @param env Environment. MUST NOT be NULL.
* @param node node containing an instance of an AXIOM element.
* @param ns pointer to the namespace struct to be declared. Should not be null
*
* @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE.
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_declare_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * node,
axiom_namespace_t * ns)
{
axiom_namespace_t *declared_ns;
axis2_char_t *prefix;
axis2_char_t *uri;
AXIS2_ASSERT(node != NULL);
AXIS2_ASSERT(ns != NULL);
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
uri = axiom_namespace_get_uri(ns, env);
prefix = axiom_namespace_get_prefix(ns, env);
/* If namespace already declared, return */
declared_ns = axiom_element_find_namespace(om_element, env, node, uri, prefix);
if (declared_ns)
return AXIS2_SUCCESS;
if (!om_element->namespaces)
{
om_element->namespaces = axutil_hash_make(env);
if (!om_element->namespaces)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespaces hash map");
return AXIS2_FAILURE;
}
}
if (prefix)
axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns);
else
{
/* create a key with empty string */
axis2_char_t *key;
key = AXIS2_MALLOC(env->allocator, sizeof(char) * 1);
if (!key)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create key to store namespace");
}
key[0] = '\0';
axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns);
}
axiom_namespace_increment_ref(ns, env);
return AXIS2_SUCCESS;
}
/**
* retrieves the default namespace of this element
*
* @param om_element pointer to om element
* @param env axutil_environment MUST Not be NULL
* @param element_node corresponding om element node of this om element
*
* @returns pointer to default namespace if available , NULL otherwise
*/
axiom_namespace_t *AXIS2_CALL
axiom_element_get_default_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node)
{
axiom_node_t *parent_node;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(element_node != NULL);
if (om_element->namespaces)
{
axiom_namespace_t *default_ns;
default_ns = axutil_hash_get(om_element->namespaces, "", AXIS2_HASH_KEY_STRING);
if (default_ns)
return default_ns;
}
parent_node = axiom_node_get_parent(element_node, env);
if ((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT))
{
axiom_element_t *parent_ele;
parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
return axiom_element_get_default_namespace(parent_ele, env, parent_node);
}
return NULL;
}
/**
* get the namespace of om_element
*
* @param om_element om_element struct
* @param env environment, MUST NOT be NULL.
*
* @returns pointer to axiom_namespace_t struct
* NULL if there is no namespace associated with the element,
* NULL on error with error code set to environment's error
*/
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_get_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * ele_node)
{
axiom_namespace_t *ns;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(ele_node != NULL);
if (om_element->ns)
ns = om_element->ns;
else
ns = axiom_element_get_default_namespace(om_element, env, ele_node);
return ns;
}
/**
* set the namespace of the element
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param ns pointer to namespace. Must not be NULL
* If the value of the namespace has not already been declared
* then the namespace structure ns will be declared and will be
* freed when the tree is freed.
* @returns status code of the op, with error code
* set to environment's error
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_namespace_t * ns,
axiom_node_t * node)
{
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(ns != NULL);
AXIS2_ASSERT(node != NULL);
if (axiom_element_declare_namespace(om_element, env, node, ns) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare namespace given");
return AXIS2_FAILURE;
}
om_element->ns = ns;
axiom_namespace_increment_ref(ns, env);
return AXIS2_SUCCESS;
}
/**
* get the namespace list of the element
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
*
* @returns axutil_hash pointer to namespaces hash
* this hash table is read only
*/
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_element_get_namespaces(
axiom_element_t * om_element,
const axutil_env_t * env)
{
return om_element->namespaces;
}
/**
* Adds an attribute to current element. The current element takes responsibility of the
* assigned attribute
* @param om_element element to which the attribute is to be added.cannot be NULL.
* @param env Environment. MUST NOT be NULL.
* @param attribute attribute to be added.
* @param node axiom_node_t node that om_element is contained in
* @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE.
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_add_attribute(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_attribute_t * attribute,
axiom_node_t * element_node)
{
axutil_qname_t *qname;
axiom_namespace_t *om_namespace;
AXIS2_ASSERT(attribute != NULL);
AXIS2_ASSERT(element_node != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_element != NULL);
om_namespace = axiom_attribute_get_namespace(attribute, env);
if (om_namespace)
{
/* Declare the namespace in element */
if (axiom_element_declare_namespace(om_element, env, element_node, om_namespace) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare attribute namespace");
return AXIS2_FAILURE;
}
}
if (!om_element->attributes)
{
om_element->attributes = axutil_hash_make(env);
if (!om_element->attributes)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create hash map to store attributes");
return AXIS2_FAILURE;
}
}
qname = axiom_attribute_get_qname(attribute, env);
if (qname)
{
axis2_char_t *name = axutil_qname_to_string(qname, env);
axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, attribute);
axiom_attribute_increment_ref(attribute, env);
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create qname to store attribute");
return AXIS2_FAILURE;
}
return AXIS2_SUCCESS;
}
/**
* Gets (finds) the attribute with the given qname
*
* @param element element whose attribute is to be found.
* @param env Environment. MUST NOT be NULL.
* @param qname qname of the attribute to be found. should not be NULL.
*
* @return a pointer to the attribute with given qname if found, else NULL.
* On error, returns NULL and sets the error code in environment's error struct.
*/
AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL
axiom_element_get_attribute(
axiom_element_t * om_element,
const axutil_env_t * env,
axutil_qname_t * qname)
{
axis2_char_t *name;
void *attr;
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(qname != NULL);
AXIS2_ASSERT(om_element != NULL);
/* if there are no attributes, then return NULL */
if (!om_element->attributes)
return NULL;
name = axutil_qname_to_string(qname, env);
if (!name)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to get string representation of qname");
return NULL;
}
attr = axutil_hash_get(om_element->attributes, name, AXIS2_HASH_KEY_STRING);
return (axiom_attribute_t *)attr;
}
/**
* get the attribute list of the element
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
*
* @returns axutil_hash pointer to attributes hash
* This hash table is read only
*/
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_element_get_all_attributes(
axiom_element_t * om_element,
const axutil_env_t * env)
{
return om_element->attributes;
}
/**
* Gets (finds) the attribute value with the given qname
*
* @param element element whose attribute is to be found.
* @param env Environment. MUST NOT be NULL.
* @param qname qname of the attribute to be found. should not be NULL.
*
* @return the attribute value with given qname if found, else NULL.
* On error, returns NULL and sets the error code in environment's error struct.
*/
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_attribute_value(
axiom_element_t * om_element,
const axutil_env_t * env,
axutil_qname_t * qname)
{
axiom_attribute_t *attr = axiom_element_get_attribute(om_element, env, qname);
if (!attr)
return NULL;
return axiom_attribute_get_value(attr, env);
}
/**
* Extract attributes , returns a clones hash table of attributes,
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
*/
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_element_extract_attributes(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * ele_node)
{
axutil_hash_index_t *hi;
axutil_hash_t *ht_cloned;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(ele_node != NULL);
if (!om_element->attributes)
return NULL;
ht_cloned = axutil_hash_make(env);
if (!ht_cloned)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create hashmap to extract attributes");
return NULL;
}
for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
{
void *val;
axiom_attribute_t *cloned_attr;
axis2_char_t *key = NULL;
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
cloned_attr = axiom_attribute_clone((axiom_attribute_t*)val, env);
if (cloned_attr)
{
axutil_qname_t *qn = axiom_attribute_get_qname(cloned_attr, env);
if (qn)
key = axutil_qname_to_string(qn, env);
}
if (key)
axutil_hash_set(ht_cloned, key, AXIS2_HASH_KEY_STRING, cloned_attr);
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to clone attribute");
return NULL;
}
}
return ht_cloned;
}
/**
* Returns the attribute value as a string for the given element
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param attr_name the attribute name
* @return the attribute value as a string
*/
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_attribute_value_by_name(
axiom_element_t * om_element,
const axutil_env_t * env,
axis2_char_t * attr_name)
{
axutil_hash_index_t *hi;
AXIS2_ASSERT(attr_name != NULL);
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
if (!om_element->attributes)
return NULL;
for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
{
void *attr;
axis2_char_t *this_attr_name;
axiom_namespace_t *attr_ns;
axis2_char_t *prefix;
axutil_hash_this(hi, NULL, NULL, &attr);
AXIS2_ASSERT(attr != NULL);
this_attr_name = axiom_attribute_get_localname((axiom_attribute_t*)attr, env);
attr_ns = axiom_attribute_get_namespace((axiom_attribute_t*)attr, env);
if (attr_ns && (prefix = axiom_namespace_get_prefix(attr_ns, env)) &&
(axutil_strcmp(prefix, "") != 0))
{
/* namespace is defined and prefix is not empty. So, prefix:localname should match
* with given name
*/
axis2_char_t *attr_qn_str = axutil_strcat(env, prefix, ":", this_attr_name, NULL);
if (axutil_strcmp(attr_qn_str, attr_name) != 0)
{
/* not the attribute we are looking for */
AXIS2_FREE(env->allocator, attr_qn_str);
continue;
}
AXIS2_FREE(env->allocator, attr_qn_str);
}
else
{
/* no namespace or no prefix. so compare only local name */
if (axutil_strcmp(this_attr_name, attr_name) != 0)
{
/* not the attribute we are looking for */
continue;
}
}
/* we found the attribute */
AXIS2_FREE(env->allocator, hi);
return axiom_attribute_get_value((axiom_attribute_t*)attr, env);
}
return NULL;
}
/**
* Select all the text children and concatenate them to a single string. The string
* returned by this method call will be free by axiom when this method is called again.
* So it is recommended to have a copy of the return value if this method is going to
* be called more that once and the return values of the earlier calls are important.
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param element node , the container node of this om element
* @return the concatenated text of all text children text values
* return null if no text children is available or on error
*/
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_text(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node)
{
axiom_node_t *temp_node;
axis2_char_t *dest = NULL;
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(element_node != NULL);
AXIS2_ASSERT(om_element != NULL);
if (om_element->text_value)
{
AXIS2_FREE(env->allocator, om_element->text_value);
om_element->text_value = NULL;
}
temp_node = axiom_node_get_first_child(element_node, env);
while(temp_node)
{
if (axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT)
{
const axis2_char_t *temp_text;
axiom_text_t *text_ele;
text_ele = (axiom_text_t *)axiom_node_get_data_element(temp_node, env);
AXIS2_ASSERT(text_ele != NULL);
temp_text = axiom_text_get_value(text_ele, env);
if (dest && temp_text && axutil_strcmp(temp_text, "") != 0)
{
axis2_char_t *temp_dest = axutil_stracat(env, dest, temp_text);
AXIS2_FREE(env->allocator, dest);
dest = temp_dest;
}
else if (!dest && temp_text && axutil_strcmp(temp_text, "") != 0)
dest = axutil_strdup(env, temp_text);
}
temp_node = axiom_node_get_next_sibling(temp_node, env);
}
om_element->text_value = dest;
return om_element->text_value;
}
/**
* Sets the text of the given element.
* caution - This method will wipe out all the text elements (and hence any mixed content)
* before setting the text
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param text text to set.
* @param element_node node of element.
*
* @return AXIS2_SUCCESS if attribute was found and removed, else AXIS2_FAILURE
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_text(
axiom_element_t * om_element,
const axutil_env_t * env,
const axis2_char_t * text,
axiom_node_t * element_node)
{
axiom_node_t *temp_node, *next_node;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(text != NULL);
AXIS2_ASSERT(element_node != NULL);
next_node = axiom_node_get_first_child(element_node, env);
while(next_node)
{
temp_node = next_node;
next_node = axiom_node_get_next_sibling(temp_node, env);
if (axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT)
axiom_node_free_tree(temp_node, env);
}
if (!axiom_text_create(env, element_node, text, &temp_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set text to element");
return AXIS2_FAILURE;
}
return AXIS2_SUCCESS;
}
/**
* returns the localname of this element
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @returns localname of element, returns NULL on error.
*/
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_get_localname(
axiom_element_t * om_element,
const axutil_env_t * env)
{
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(om_element->localname != NULL);
return (axis2_char_t *)axutil_string_get_buffer(om_element->localname, env);
}
/**
* set the localname of this element
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @localname text value to be set as localname
* @returns status code of operation, AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_localname(
axiom_element_t * om_element,
const axutil_env_t * env,
const axis2_char_t * localname)
{
axutil_string_t *new_name;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(om_element->localname != NULL);
AXIS2_ASSERT(localname != NULL);
AXIS2_ASSERT(env != NULL);
new_name = axutil_string_create(env, localname);
if (!new_name)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set local name of element");
return AXIS2_FAILURE;
}
axutil_string_free(om_element->localname, env);
om_element->localname = new_name;
return AXIS2_SUCCESS;
}
/**
* return qname of this element. The returned qname should not be freed by the caller.
* It will be freed when om_element struct is freed
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param ele_node pointer to this element node
* @returns axutil_qname_t struct , NULL on failure
*/
AXIS2_EXTERN axutil_qname_t *AXIS2_CALL
axiom_element_get_qname(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * ele_node)
{
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(ele_node != NULL);
if (!om_element->qname)
{
axiom_namespace_t *ns = axiom_element_get_namespace(om_element, env, ele_node);
const axis2_char_t *localname = axutil_string_get_buffer(om_element->localname, env);
axis2_char_t *prefix = NULL;
axis2_char_t *uri = NULL;
if (ns)
{
prefix = axiom_namespace_get_prefix(ns, env);
uri = axiom_namespace_get_uri(ns, env);
}
om_element->qname = axutil_qname_create(env, localname, uri, prefix);
}
return om_element->qname;
}
/**
* returns a list of children iterator. Returned iterator is freed when om_element struct
* is freed
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param element_node pointer to this element node
*/
AXIS2_EXTERN axiom_children_iterator_t *AXIS2_CALL
axiom_element_get_children(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node)
{
AXIS2_ASSERT(element_node != NULL);
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
if (!om_element->children_iter)
om_element->children_iter = axiom_children_iterator_create(env, axiom_node_get_first_child(element_node, env));
else
axiom_children_iterator_reset(om_element->children_iter, env);
return om_element->children_iter;
}
/**
* returns a list of children iterator with qname. Returned iterator is freed when om element
* struct is freed
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param element_node pointer to this element node
*
* @returns children qname iterator struct
*/
AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL
axiom_element_get_children_with_qname(
axiom_element_t * om_element,
const axutil_env_t * env,
axutil_qname_t * element_qname,
axiom_node_t * element_node)
{
AXIS2_ASSERT(element_node != NULL);
AXIS2_ASSERT(om_element != NULL);
if (om_element->children_qname_iter)
axiom_children_qname_iterator_free(om_element->children_qname_iter, env);
om_element->children_qname_iter = axiom_children_qname_iterator_create(env,
axiom_node_get_first_child(element_node, env), element_qname);
return om_element->children_qname_iter;
}
/**
* Returns the first om_element corresponding to element_qname
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param element_qname qname of the element
* @param om_node pointer to this element node
* @param element_node
* @param child_node
*
* @returns children qname iterator struct
*/
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_get_first_child_with_qname(
axiom_element_t * om_element,
const axutil_env_t * env,
axutil_qname_t * qname,
axiom_node_t * element_node,
axiom_node_t ** child_node)
{
axiom_children_qname_iterator_t *children_iterator;
children_iterator = axiom_element_get_children_with_qname(om_element, env, qname, element_node);
if (!children_iterator)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not get children qname iterator");
return NULL;
}
if (axiom_children_qname_iterator_has_next(children_iterator, env))
{
axiom_node_t *om_node = axiom_children_qname_iterator_next(children_iterator, env);
AXIS2_ASSERT(om_node != NULL);
AXIS2_ASSERT(axiom_node_get_node_type(om_node, env) == AXIOM_ELEMENT);
if (child_node)
*child_node = om_node;
return (axiom_element_t *)axiom_node_get_data_element(om_node, env);
}
return NULL;
}
/**
* returns the first child om element of this om element node
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
* @return om_element if one is available otherwise return NULL
*/
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_get_first_element(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node,
axiom_node_t ** first_ele_node)
{
axiom_node_t *temp_node;
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(element_node != NULL);
temp_node = axiom_node_get_first_child(element_node, env);
while(temp_node)
{
if (axiom_node_get_node_type(temp_node, env) == AXIOM_ELEMENT)
{
if (first_ele_node)
*first_ele_node = temp_node;
return (axiom_element_t *)axiom_node_get_data_element(temp_node, env);
}
else
temp_node = axiom_node_get_next_sibling(temp_node, env);
}
return NULL;
}
/**
* returns an iterator with child elements of type AXIOM_ELEMENT
* iterator is freed when om_element node is freed
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param element_node
* @returns axiom_child_element_iterator_t , NULL on error
*/
AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL
axiom_element_get_child_elements(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node)
{
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(element_node != NULL);
if (om_element->child_ele_iter)
return om_element->child_ele_iter;
else
{
axiom_node_t *first_node;
axiom_element_t *ele;
ele = axiom_element_get_first_element(om_element, env, element_node, &first_node);
if (ele)
{
AXIS2_ASSERT(first_node != NULL);
om_element->child_ele_iter = axiom_child_element_iterator_create(env, first_node);
return om_element->child_ele_iter;
}
}
return NULL;
}
/**
* Collect all the namespaces with distinct prefixes in the parents of the given element.
* Effectively this is the set of namespaces declared above this element and might be used by it
* or its children. Output of this will be used later by axiom_element_redeclare_parent_namespaces
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
*
* @returns pointer to hash of relevant namespaces
*/
axutil_hash_t * AXIS2_CALL
axiom_element_gather_parent_namespaces(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * om_node)
{
axutil_hash_t *inscope_namespaces;
axiom_node_t *parent_node = om_node;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_node != NULL);
inscope_namespaces = axutil_hash_make(env);
if (!inscope_namespaces)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"Unable to create hashmap needed to gather parent namespace");
return NULL;
}
while ((parent_node = axiom_node_get_parent(parent_node, env))
&& (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT))
{
axiom_element_t *parent_element;
axutil_hash_t *parent_namespaces;
axutil_hash_index_t *hi;
parent_element = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
parent_namespaces = axiom_element_get_namespaces(parent_element, env);
/* If no namespaces are declared. So, continue without processing */
if (!parent_namespaces)
continue;
for (hi = axutil_hash_first(parent_namespaces, env); hi; hi = axutil_hash_next(env, hi))
{
axis2_char_t *key;
void *val;
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
key = axiom_namespace_get_prefix((axiom_namespace_t *)val, env);
if (!key)
key = "";
/* Check if prefix already associated with some namespace in a parent node */
if (!axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING))
{
/* Remember this namespace as needing to be declared, if used */
axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, val);
}
}
}
return inscope_namespaces;
}
/**
* If the provided namespace used by the provided element is one of the namespaces from the
* parent of the detached node, redeclares that namespace at the element level and removes it
* from the hash of parent namespaces
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
* @param ns pointer to namespace to redeclare
* @param inscope_namespaces pointer to hash of parent namespaces
*/
void AXIS2_CALL
axiom_element_use_parent_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * om_node,
axiom_namespace_t *ns,
axutil_hash_t *inscope_namespaces)
{
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_node != NULL);
if (ns && inscope_namespaces)
{
axiom_namespace_t *parent_ns;
axis2_char_t *key = axiom_namespace_get_prefix(ns, env);
if (!key)
key = "";
parent_ns = axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING);
/* Check if namespace is a namespace declared in a parent and not also declared at an
* intermediate level */
if (parent_ns)
{
/* declare the namespace. If it is already declared in intermediate level,
* axiom_elment_declare_namespace will handle it
*/
axiom_element_declare_namespace(om_element, env, om_node, parent_ns);
/* Remove the namespace from the inscope parent namespaces now that it has
been redeclared. */
axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, NULL);
}
}
}
/**
* Examines the subtree beginning at the provided element for each element or attribute,
* if it refers to a namespace declared in a parent of the subtree root element, if not already
* declared, redeclares that namespace at the level of the subtree root and removes
* it from the set of parent inscope_namespaces. inscope_namespaces contains all the parent
* namespaces which should be redeclared at some point.
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
* @param inscope_namespaces pointer to hash of parent namespaces
*/
void AXIS2_CALL
axiom_element_redeclare_parent_namespaces(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * om_node,
axutil_hash_t *inscope_namespaces)
{
axiom_node_t *child_node;
axutil_hash_t * attributes;
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_node != NULL);
/* ensure the element's namespace is declared */
axiom_element_use_parent_namespace(om_element, env, om_node, om_element->ns, inscope_namespaces);
/* for each attribute, ensure the attribute's namespace is declared */
attributes = om_element->attributes;
if (attributes)
{
axutil_hash_index_t *hi;
for(hi = axutil_hash_first(attributes, env); hi; hi = axutil_hash_next(env, hi))
{
void *val;
axiom_namespace_t* ns;
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
ns = axiom_attribute_get_namespace((axiom_attribute_t*)val, env);
axiom_element_use_parent_namespace(om_element, env, om_node,ns, inscope_namespaces);
}
}
/* ensure the namespaces in all the children are declared */
child_node = axiom_node_get_first_child(om_node, env);
while(child_node && (axutil_hash_count(inscope_namespaces) > 0))
{
if (axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT)
{
axiom_element_redeclare_parent_namespaces(axiom_node_get_data_element(child_node, env),
env, child_node, inscope_namespaces);
}
child_node = axiom_node_get_next_sibling(child_node, env);
}
}
/**
* Serializes the start part of the given element
* @param element element to be serialized.
* @param env Environment. MUST NOT be NULL.
* @param om_output AXIOM output handler to be used in serializing
* @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE
*/
axis2_status_t AXIS2_CALL
axiom_element_serialize_start_part(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_output_t * om_output,
axiom_node_t * ele_node)
{
axis2_status_t status = AXIS2_SUCCESS;
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(om_output != NULL);
AXIS2_ASSERT(ele_node != NULL);
if (om_element->is_empty)
{
if (om_element->ns)
{
axis2_char_t *uri = axiom_namespace_get_uri(om_element->ns, env);
axis2_char_t *prefix = axiom_namespace_get_prefix(om_element->ns, env);
AXIS2_ASSERT(uri != NULL);
if (prefix && (axutil_strcmp(prefix, "") != 0))
{
status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4,
axutil_string_get_buffer(om_element-> localname, env), uri, prefix, NULL);
}
else
{
status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4,
axutil_string_get_buffer(om_element-> localname, env), uri, NULL, NULL);
}
}
else
{
status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4,
axutil_string_get_buffer(om_element-> localname, env), NULL, NULL, NULL);
}
}
else
{
if (om_element->ns)
{
axis2_char_t *uri = axiom_namespace_get_uri(om_element->ns, env);
axis2_char_t *prefix = axiom_namespace_get_prefix(om_element->ns, env);
AXIS2_ASSERT(uri != NULL);
if (prefix && (axutil_strcmp(prefix, "") != 0))
{
status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 3,
axutil_string_get_buffer(om_element-> localname, env), uri, prefix);
}
else
{
status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 2,
axutil_string_get_buffer(om_element-> localname, env), uri);
}
}
else
{
status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 1,
axutil_string_get_buffer(om_element-> localname, env));
}
}
if (status != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element serialized failed");
return AXIS2_FAILURE;
}
if (om_element->attributes)
{
axutil_hash_index_t *hi;
void *val;
for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi))
{
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
if (axiom_attribute_serialize((axiom_attribute_t *)val, env, om_output) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element attribute serialize failed");
AXIS2_FREE(env->allocator, hi);
return AXIS2_FAILURE;
}
}
}
if (om_element->namespaces)
{
axutil_hash_index_t *hi;
void *val;
for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi))
{
axutil_hash_this(hi, NULL, NULL, &val);
AXIS2_ASSERT(val != NULL);
if (axiom_namespace_serialize((axiom_namespace_t *)val, env, om_output) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element namespace serialize failed");
AXIS2_FREE(env->allocator, hi);
return AXIS2_FAILURE;
}
}
}
return AXIS2_SUCCESS;
}
/**
* Serializes the end part of the given element. serialize_start_part must
* have been called before calling this method.
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
* @param om_output AXIOM output handler to be used in serializing
*
* @return status of the operation. AXIS2_SUCCESS on success else AXIS2_FAILURE
*/
axis2_status_t AXIS2_CALL
axiom_element_serialize_end_part(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_output_t * om_output)
{
AXIS2_ASSERT(env != NULL);
AXIS2_ASSERT(om_element != NULL);
AXIS2_ASSERT(om_output != NULL);
return axiom_output_write(om_output, env, AXIOM_ELEMENT, 0);
}
/**
* Set whether the element is empty or not
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param is_empty AXIS2_TRUE if empty AXIS2_FALSE if not empty
* @return VOID
*/
void AXIS2_CALL
axiom_element_set_is_empty(
axiom_element_t * om_element,
const axutil_env_t * env,
axis2_bool_t is_empty)
{
om_element->is_empty = is_empty;
}
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_element_get_is_empty(
axiom_element_t * om_element,
const axutil_env_t * env)
{
return om_element->is_empty;
}
/**
* This method will declare the namespace without checking whether it is already declared.
* (This method is only used by codegen. We have to remove this method in future)
*
* @param om_element pointer to om_element
* @param env environment MUST not be NULL
* @param om_node pointer to this element node
*
* @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE.
*
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_declare_namespace_assume_param_ownership(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_namespace_t * ns)
{
axis2_char_t *prefix = NULL;
if (!ns || !om_element)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "namespace or om_element is NULL");
return AXIS2_FAILURE;
}
if (!(om_element->namespaces))
{
om_element->namespaces = axutil_hash_make(env);
if (!(om_element->namespaces))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespaces hash map");
return AXIS2_FAILURE;
}
}
prefix = axiom_namespace_get_prefix(ns, env);
if (prefix)
axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns);
else
{
/* create a key with empty string */
axis2_char_t *key;
key = AXIS2_MALLOC(env->allocator, sizeof(char) * 1);
if (!key)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create key to store namespace");
}
key[0] = '\0';
axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns);
}
axiom_namespace_increment_ref(ns, env);
return AXIS2_SUCCESS;
}
#if 0
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_build(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * om_ele_node)
{
axiom_stax_builder_t *builder = NULL;
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
AXIS2_PARAM_CHECK(env->error, om_ele_node, AXIS2_FAILURE);
if (axiom_node_get_node_type(om_ele_node, env) != AXIOM_ELEMENT)
return AXIS2_FAILURE;
builder = axiom_node_get_builder(om_ele_node, env);
if (!builder)
return AXIS2_FAILURE;
while(!axiom_node_is_complete(om_ele_node, env)
&& !axiom_stax_builder_is_complete(builder, env))
{
void *value = NULL;
value = axiom_stax_builder_next(builder, env);
if (!value)
return AXIS2_FAILURE;
}
return AXIS2_SUCCESS;
}
#endif
/**
* checks for the namespace in the context of this element
* with the given prefix
*/
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_find_namespace_uri(
axiom_element_t * om_element,
const axutil_env_t * env,
const axis2_char_t * prefix,
axiom_node_t * element_node)
{
axiom_node_t *parent_node = NULL;
axiom_namespace_t *ns = NULL;
AXIS2_ENV_CHECK(env, NULL);
AXIS2_PARAM_CHECK(env->error, element_node, NULL);
AXIS2_PARAM_CHECK(env->error, prefix, NULL);
if (om_element->namespaces)
{
ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING);
if (ns)
return ns;
}
parent_node = axiom_node_get_parent(element_node, env);
if ((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT))
{
axiom_element_t *parent_ele = NULL;
parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
if (parent_ele)
return axiom_element_find_namespace_uri(parent_ele, env, prefix, parent_node);
}
return NULL;
}
AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_element_get_localname_str(
axiom_element_t * om_element,
const axutil_env_t * env)
{
return om_element->localname;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_localname_str(
axiom_element_t * om_element,
const axutil_env_t * env,
axutil_string_t * localname)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);
if (om_element->localname)
{
axutil_string_free(om_element->localname, env);
om_element->localname = NULL;
}
om_element->localname = axutil_string_clone(localname, env);
if (!(om_element->localname))
return AXIS2_FAILURE;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_namespace_with_no_find_in_current_scope(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_namespace_t * om_ns)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
AXIS2_PARAM_CHECK(env->error, om_ns, AXIS2_FAILURE);
om_element->ns = om_ns;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_set_namespace_assume_param_ownership(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_namespace_t * ns)
{
om_element->ns = ns;
return AXIS2_SUCCESS;
}
/**
* declared a default namespace explicitly
*/
AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_element_declare_default_namespace(
axiom_element_t * om_element,
const axutil_env_t * env,
axis2_char_t * uri)
{
axiom_namespace_t *default_ns = NULL;
AXIS2_ENV_CHECK(env, NULL);
AXIS2_PARAM_CHECK(env->error, uri, NULL);
if (axutil_strcmp(uri, "") == 0)
return NULL;
default_ns = axiom_namespace_create(env, uri, "");
if (!default_ns)
return NULL;
if (!om_element->namespaces)
{
om_element->namespaces = axutil_hash_make(env);
if (!(om_element->namespaces))
{
axiom_namespace_free(default_ns, env);
return NULL;
}
}
axutil_hash_set(om_element->namespaces, "", AXIS2_HASH_KEY_STRING, default_ns);
axiom_namespace_increment_ref(default_ns, env);
return default_ns;
}
AXIS2_EXTERN axiom_element_t *AXIS2_CALL
axiom_element_create_str(
const axutil_env_t * env,
axiom_node_t * parent,
axutil_string_t * localname,
axiom_namespace_t * ns,
axiom_node_t ** node)
{
axiom_element_t *element;
if (!localname || !node)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localname or node is NULL");
return NULL;
}
(*node) = axiom_node_create(env);
if (!(*node))
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create axiom node");
return NULL;
}
element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t));
if (!element)
{
AXIS2_FREE(env->allocator, (*node));
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create axiom element");
return NULL;
}
memset(element, 0, sizeof(axiom_element_t));
element->localname = axutil_string_clone(localname, env);
/* clone can't be null so, no need to check for null validity*/
if (parent)
axiom_node_add_child(parent, env, (*node));
axiom_node_set_node_type((*node), env, AXIOM_ELEMENT);
axiom_node_set_data_element((*node), env, element);
if (ns)
{
axis2_char_t *uri = NULL;
axis2_char_t *prefix = NULL;
uri = axiom_namespace_get_uri(ns, env);
prefix = axiom_namespace_get_prefix(ns, env);
element->ns = axiom_element_find_namespace(element, env, *node, uri, prefix);
if (!(element->ns))
{
if (axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS)
element->ns = ns;
}
if (prefix && axutil_strcmp(prefix, "") == 0)
element->ns = NULL;
}
return element;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_element_remove_attribute(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_attribute_t * om_attribute)
{
axutil_qname_t *qname = NULL;
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
AXIS2_PARAM_CHECK(env->error, om_attribute, AXIS2_FAILURE);
qname = axiom_attribute_get_qname(om_attribute, env);
if (qname && (om_element->attributes))
{
axis2_char_t *name = NULL;
name = axutil_qname_to_string(qname, env);
if (name)
{
axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, NULL);
return AXIS2_SUCCESS;
}
}
return AXIS2_FAILURE;
}
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_element_to_string(
axiom_element_t * om_element,
const axutil_env_t * env,
axiom_node_t * element_node)
{
return axiom_node_to_string(element_node, env);
}