/* * 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 #include #include #include #include #include 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. * 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((!temp_nsuri) || (axutil_strcmp(temp_nsuri, "") == 0)) { /** no namespace uri is available in given qname no need to bother about it */ return element; } element->ns = axiom_element_find_namespace(element, env, (*node), temp_nsuri, temp_prefix); if(!element->ns) { /** could not find a namespace so declare namespace */ 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); declared_ns = axiom_element_find_namespace(om_element, env, node, uri, prefix); if(declared_ns) { /*Namespace already declared, so return */ 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. * @qname 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. * @qname 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) { /* cannot find the attribute with given name. But this might not be an error, and a valid * case */ 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) { /* no attributes defined */ 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) { /* no attributes are defined. */ 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(element_qname != 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(!parent_namespaces) { /* no namespaces are declared. So, continue without processing */ 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; } /** * 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; } /** * 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_bool_t AXIS2_CALL axiom_element_get_is_empty( axiom_element_t * om_element, const axutil_env_t * env) { return om_element->is_empty; } 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); } #endif