From afe578cd8894b9a6cd6c6b65e552448536f02dce Mon Sep 17 00:00:00 2001 From: shankar Date: Thu, 1 Apr 2010 14:07:15 +0000 Subject: Refactor, adding comments, improving performance git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@929982 13f79535-47bb-0310-9956-ffa450edef68 --- axiom/include/axiom_element.h | 663 ++++------ axiom/src/om/axiom_element_internal.h | 147 +++ axiom/src/om/om_attribute.c | 8 +- axiom/src/om/om_element.c | 2241 +++++++++++++++++---------------- axiom/src/om/om_namespace.c | 2 +- axiom/src/om/om_node.c | 16 +- axiom/src/om/om_stax_builder.c | 18 +- util/include/axutil_utils.h | 4 + util/src/qname.c | 1 - 9 files changed, 1598 insertions(+), 1502 deletions(-) create mode 100644 axiom/src/om/axiom_element_internal.h diff --git a/axiom/include/axiom_element.h b/axiom/include/axiom_element.h index 1e10167..cd1de06 100644 --- a/axiom/include/axiom_element.h +++ b/axiom/include/axiom_element.h @@ -43,22 +43,20 @@ extern "C" */ /** - * 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 elment. 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 declared and will be - * freed when the tree is freed. - * If the value of the namespace has already been declared using - * another namespace structure then the namespace structure ns - * will be freed. - * @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 - */ + * 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, @@ -83,11 +81,37 @@ extern "C" axiom_node_t * parent, const axutil_qname_t * qname, axiom_node_t ** node); - /* + + /** + * 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 * element, + const axutil_env_t * env); + + /** + * finds a namespace in current element's scope, by uri or prefix or both + * @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); + + /** * 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 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.. @@ -104,41 +128,12 @@ extern "C" const axis2_char_t * prefix); /** - * Declare a namespace in current element (in the scope of this element ). - * It checks to see if it is already declared. - * @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 - * @return satus of the op. 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); - /** - * @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); - - /** - * Finds a namespace using qname - * Start to find from the given node and go up the hierarchy. + * 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 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 + * @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 @@ -149,211 +144,212 @@ extern "C" axutil_qname_t * qname); /** - * 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. + * 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 attribute attribute to be added. - * @param node axiom_node_t node that om_element is contained in - * @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE. + * @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_add_attribute( + axiom_element_declare_namespace( axiom_element_t * om_element, const axutil_env_t * env, - axiom_attribute_t * attribute, - axiom_node_t * node); + axiom_node_t * node, + axiom_namespace_t * ns); /** - * 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( + * 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, - axutil_qname_t * qname); + axiom_node_t * ele_node); /** - * 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( + * 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, - axutil_qname_t * qname); + axiom_namespace_t * ns, + axiom_node_t * node); /** - * Frees given element - * @param element AXIOM element to be freed. - * @param env Environment. MUST NOT be NULL. - * @return satus of the op. AXIS2_SUCCESS on success ,AXIS2_FAILURE on error. - */ - AXIS2_EXTERN void AXIS2_CALL - axiom_element_free( - axiom_element_t * element, + * 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); /** - * 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 satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE - */ + * 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_serialize_start_part( + axiom_element_add_attribute( axiom_element_t * om_element, const axutil_env_t * env, - axiom_output_t * om_output, - axiom_node_t * ele_node); + axiom_attribute_t * attribute, + axiom_node_t * node); /** - * 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 satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE + * 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 axis2_status_t AXIS2_CALL - axiom_element_serialize_end_part( + AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL + axiom_element_get_attribute( axiom_element_t * om_element, const axutil_env_t * env, - axiom_output_t * om_output); + axutil_qname_t * qname); /** - * finds a namespace in current element's scope, - * by uri or prefix or both + * get the attribute list of the element * @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 + * @returns axutil_hash pointer to attributes hash + * This hash table is read only */ - - AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL - axiom_element_find_declared_namespace( + AXIS2_EXTERN axutil_hash_t *AXIS2_CALL + axiom_element_get_all_attributes( axiom_element_t * om_element, - const axutil_env_t * env, - const axis2_char_t * uri, - const axis2_char_t * prefix); + const axutil_env_t * env); /** - * 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. + * 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_localname( + axiom_element_get_attribute_value( axiom_element_t * om_element, - const axutil_env_t * env); + const axutil_env_t * env, + axutil_qname_t * qname); /** - * set the localname of this element + * Extract attributes , returns a clones hash table of attributes, * @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 op, AXIS2_SUCCESS on success, - * AXIS2_FAILURE on error. + * @param om_node pointer to this element node */ - AXIS2_EXTERN axis2_status_t AXIS2_CALL - axiom_element_set_localname( + AXIS2_EXTERN axutil_hash_t *AXIS2_CALL + axiom_element_extract_attributes( axiom_element_t * om_element, const axutil_env_t * env, - const axis2_char_t * localname); + axiom_node_t * ele_node); /** - * get the namespace of om_element - * @param om_element om_element struct - * @param env environemt, 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 + * 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 axiom_namespace_t *AXIS2_CALL - axiom_element_get_namespace( - axiom_element_t * om_element, + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axiom_element_get_attribute_value_by_name( + axiom_element_t * om_ele, const axutil_env_t * env, - axiom_node_t * ele_node); + axis2_char_t * attr_name); /** - * set the namespace of the element + * 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 ns pointer to namespace - * 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 + * @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_status_t AXIS2_CALL - axiom_element_set_namespace( + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axiom_element_get_text( axiom_element_t * om_element, const axutil_env_t * env, - axiom_namespace_t * ns, - axiom_node_t * node); - + axiom_node_t * element_node); /** - * unconditionally set the namespace of the element + * 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 ns pointer to namespace - * The namespace ns is assumed to have been declared already. - * @returns status code of the op, with error code - * set to environment's error + * @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_namespace_assume_param_ownership( + axiom_element_set_text( axiom_element_t * om_element, const axutil_env_t * env, - axiom_namespace_t * ns); + const axis2_char_t * text, + axiom_node_t * element_node); /** - * get the attribute list of the element + * returns the localname of this element * @param om_element pointer to om_element * @param env environment MUST not be NULL - * @returns axutil_hash poiner to attributes hash - * This hash table is read only + * @returns localname of element, returns NULL on error. */ - AXIS2_EXTERN axutil_hash_t *AXIS2_CALL - axiom_element_get_all_attributes( + AXIS2_EXTERN axis2_char_t *AXIS2_CALL + axiom_element_get_localname( axiom_element_t * om_element, const axutil_env_t * env); /** - * get the namespace list of the element + * set the localname of this 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 + * @localname text value to be set as localname + * @returns status code of operation, AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error. */ - AXIS2_EXTERN axutil_hash_t *AXIS2_CALL - axiom_element_get_namespaces( + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_element_set_localname( axiom_element_t * om_element, - const axutil_env_t * env); + const axutil_env_t * env, + const axis2_char_t * localname); /** - *@return qname of this element - * the returned qname should not be externaly freed - * when om_element struct is freed qname is also - * freed + * 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 @@ -363,14 +359,11 @@ extern "C" axiom_node_t * ele_node); /** - * returns a list of children iterator - * returned iterator is freed when om_element struct - * is freed - * iterators reset function must be called by user + * 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( @@ -379,15 +372,13 @@ extern "C" axiom_node_t * element_node); /** - * returns a list of children iterator with qname - * returned iterator is freed when om element struct - * is freed + * 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, @@ -396,16 +387,15 @@ extern "C" axiom_node_t * element_node); /** - * Returns the om_element corresponding to element_qname + * 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 element_qname qname of the element * @param om_node pointer to this element node - * @param element_node - * @param child_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, @@ -414,63 +404,12 @@ extern "C" axiom_node_t * element_node, axiom_node_t ** child_node); - /** - * removes an attribute from the element attribute list - * user must free this attribute, element free function does not free - * attributes that are not is it's attribute list - * @param om_element pointer to om_element - * @param env environment MUST not be NULL - * @param om_attribute attribute to be removed - * @return AXIS2_SUCCESS if attribute was found and removed, else - * AXIS2_FAILURE - */ - 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); - - /** - * 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); - - /** - * 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); - /** * 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 availble otherwise return NULL + * @return om_element if one is available otherwise return NULL */ AXIS2_EXTERN axiom_element_t *AXIS2_CALL axiom_element_get_first_element( @@ -480,84 +419,88 @@ extern "C" axiom_node_t ** first_element_node); /** - * returns the serilized text of this element and its children + * 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 the container node this on element is contained - * @return a char array of xml , returns NULL on error + * @param element_node + * @returns axiom_child_element_iterator_t , NULL on error */ - AXIS2_EXTERN axis2_char_t *AXIS2_CALL - axiom_element_to_string( + 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); +#if 0 /** - * returns an iterator with child elements of type AXIOM_ELEMENT - * iterator is freed when om_element node is freed + * builds this om_element_node completely, This is only possible + * if the om_stax_builder is associated with the om_element_node, * @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 + * @param om_node pointer to this element node + * @param element_node corresponding om element node of this om element + * struct + * @returns AXIS2_SUCCESS if this element node was successfully completed, + * otherwise returns AXIS2_FAILURE */ - AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL - axiom_element_get_child_elements( + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_element_build( axiom_element_t * om_element, const axutil_env_t * env, axiom_node_t * element_node); - - /** - * retrieves the default namespace of this element , if available, - * @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 availale , NULL otherwise + * checks for the namespace in the context of this element + * with the given prefix + * @param om_element pointer to om_element + * @param env environment MUST not be NULL + * @param om_element_node pointer to this element node + * @returns pointer to relevent namespace */ AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL - axiom_element_get_default_namespace( + 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); /** - * declared a default namespace explicitly - * @param om_element pointer to om element + * Returns the Local name of the element + * @param om_element pointer to om_element * @param env environment MUST not be NULL - * @param uri namespace uri of the default namespace - * @returns the declared namespace - */ - AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL - axiom_element_declare_default_namespace( + * @param om_node pointer to this element node + * + * @return the Local name of the element + */ + AXIS2_EXTERN axutil_string_t *AXIS2_CALL + axiom_element_get_localname_str( axiom_element_t * om_element, - const axutil_env_t * env, - axis2_char_t * uri); + const axutil_env_t * env); /** - * checks for the namespace in the context of this element - * with the given prefix + * Set the Local name of the element * @param om_element pointer to om_element * @param env environment MUST not be NULL - * @param om_element_node pointer to this element node - * @returns pointer to relevent namespace + * @param localname the Local name of the element + * + * @return */ - AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL - axiom_element_find_namespace_uri( + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_element_set_localname_str( axiom_element_t * om_element, const axutil_env_t * env, - const axis2_char_t * prefix, - axiom_node_t * element_node); + axutil_string_t * localname); /** - *This will not search the namespace in the scope nor will + *This will not search the namespace in the scope nor will * declare in the current element, as in set_namespace. This will * just assign the given namespace to the element. * @param om_element pointer to om_element * @param env environment MUST not be NULL * @param om_node pointer to this element node * @param om_ns pointer to namespace to be set - * @returns + * @returns */ AXIS2_EXTERN axis2_status_t AXIS2_CALL axiom_element_set_namespace_with_no_find_in_current_scope( @@ -566,32 +509,45 @@ extern "C" axiom_namespace_t * om_ns); /** - * Extract attributes , returns a clones hash table of attributes, - * if attributes are associated with a namespace it is also cloned * @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 axutil_hash_t *AXIS2_CALL - axiom_element_extract_attributes( + 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_node_t * ele_node); + axiom_namespace_t * ns); /** - * Returns the attribute value as a string for the given element + * unconditionally set the namespace of the 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 + * @param ns pointer to namespace + * The namespace ns is assumed to have been declared already. + * @returns status code of the op, with error code + * set to environment's error */ - AXIS2_EXTERN axis2_char_t *AXIS2_CALL - axiom_element_get_attribute_value_by_name( - axiom_element_t * om_ele, + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_element_set_namespace_assume_param_ownership( + axiom_element_t * om_element, const axutil_env_t * env, - axis2_char_t * attr_name); + axiom_namespace_t * ns); + + /** + * declared a default namespace explicitly + * @param om_element pointer to om element + * @param env environment MUST not be NULL + * @param uri namespace uri of the default namespace + * @returns the declared namespace + */ + 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); /** * Create an OM Element and an OM node from given string params @@ -600,7 +556,7 @@ extern "C" * @param localname the locanmae of the element * @param ns the namespace of the element * @param node the reference ot the created node - * @return + * @return */ AXIS2_EXTERN axiom_element_t *AXIS2_CALL axiom_element_create_str( @@ -610,38 +566,11 @@ extern "C" axiom_namespace_t * ns, axiom_node_t ** node); - /** - * Returns the Local name of the element - * @param om_element pointer to om_element - * @param env environment MUST not be NULL - * @param om_node pointer to this element node - * - * @return the Local name of the element - */ - AXIS2_EXTERN axutil_string_t *AXIS2_CALL - axiom_element_get_localname_str( - axiom_element_t * om_element, - const axutil_env_t * env); - - /** - * Set the Local name of the element - * @param om_element pointer to om_element - * @param env environment MUST not be NULL - * @param localname the Local name of the element - * - * @return - */ - 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); - /** * Return whether the element is empty or not * @param om_element pointer to om_element * @param env environment MUST not be NULL - * + * * @return AXIS2_TRUE if empty AXIS2_FALSE if not empty */ AXIS2_EXTERN axis2_bool_t AXIS2_CALL @@ -650,97 +579,33 @@ extern "C" const axutil_env_t * env); /** - * 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 - */ - AXIS2_EXTERN void AXIS2_CALL - axiom_element_set_is_empty( - axiom_element_t * om_element, - const axutil_env_t * env, - axis2_bool_t is_empty); - - /** - * 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 - * that are inscope at this element and might be used - * by it or its children. - * @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 relevent namespaces - */ - AXIS2_EXTERN 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); - - /** - * If the provided namespace used by the provided element - * is one of the namespaces from the parent of the root - * root element, redeclares that namespace at the root element - * 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 root_element pointer to the subtree root element node - * @param inscope_namespaces pointer to hash of parent namespaces - */ - AXIS2_EXTERN 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, - axiom_element_t * root_element, - axutil_hash_t *inscope_namespaces); - - /** - * 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, redeclares - * that namespace at the level of the subtree root and removes - * it from the set of parent namespaces in scope and not yet - * declared + * removes an attribute from the element attribute list + * user must free this attribute, element free function does not free + * attributes that are not is it's attribute list * @param om_element pointer to om_element * @param env environment MUST not be NULL - * @param om_node pointer to this element node - * - * @param root_element pointer to the subtree root element node - * @param inscope_namespaces pointer to hash of parent namespaces + * @param om_attribute attribute to be removed + * @return AXIS2_SUCCESS if attribute was found and removed, else + * AXIS2_FAILURE */ - AXIS2_EXTERN void AXIS2_CALL - axiom_element_redeclare_parent_namespaces( + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_element_remove_attribute( axiom_element_t * om_element, const axutil_env_t * env, - axiom_node_t * om_node, - axiom_element_t * root_element, - axutil_hash_t *inscope_namespaces); + axiom_attribute_t * om_attribute); -#if 0 /** - * builds this om_element_node completely, This is only possible - * if the om_stax_builder is associated with the om_element_node, + * returns the serilized text of this element and its children * @param om_element pointer to om_element * @param env environment MUST not be NULL - * @param om_node pointer to this element node - * @param element_node corresponding om element node of this om element - * struct - * @returns AXIS2_SUCCESS if this element node was successfully completed, - * otherwise returns AXIS2_FAILURE + * @param element_node the container node this on element is contained + * @return a char array of xml , returns NULL on error */ - AXIS2_EXTERN axis2_status_t AXIS2_CALL - axiom_element_build( + 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); - #endif /** @} */ diff --git a/axiom/src/om/axiom_element_internal.h b/axiom/src/om/axiom_element_internal.h new file mode 100644 index 0000000..adbce79 --- /dev/null +++ b/axiom/src/om/axiom_element_internal.h @@ -0,0 +1,147 @@ +/* + * 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. + */ + +#ifndef AXIOM_ELEMENT_INTERNAL_H_ +#define AXIOM_ELEMENT_INTERNAL_H_ + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_element element + * @ingroup axiom + * @{ + */ + + /** + * 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 that are inscope at + * this element and might be used by it or its children. + * @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); + + /** + * 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); + + /** + * If the provided namespace used by the provided element is one of the namespaces from the + * parent of the root element, redeclares that namespace at the root element 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); + + /** + * 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); + + /** + * 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); + + /** + * 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); + + /** + * 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); + +#endif /* AXIOM_ELEMENT_INTERNAL_H_ */ diff --git a/axiom/src/om/om_attribute.c b/axiom/src/om/om_attribute.c index 9d2a81e..01c59ca 100644 --- a/axiom/src/om/om_attribute.c +++ b/axiom/src/om/om_attribute.c @@ -201,11 +201,9 @@ axiom_attribute_get_localname( axiom_attribute_t * attribute, const axutil_env_t * env) { - if(attribute->localname) - { - return (axis2_char_t *)axutil_string_get_buffer(attribute->localname, env); - } - return NULL; + AXIS2_ASSERT(attribute); + AXIS2_ASSERT(attribute->localname); + return (axis2_char_t *)axutil_string_get_buffer(attribute->localname, env); } AXIS2_EXTERN axis2_char_t *AXIS2_CALL diff --git a/axiom/src/om/om_element.c b/axiom/src/om/om_element.c index d334ab8..f02b9a2 100644 --- a/axiom/src/om/om_element.c +++ b/axiom/src/om/om_element.c @@ -15,7 +15,7 @@ * limitations under the License. */ -#include +#include "axiom_element_internal.h" #include "axiom_node_internal.h" #include #include @@ -36,7 +36,7 @@ struct axiom_element /** List of attributes */ axutil_hash_t *attributes; - /** List of namespaces */ + /** List of other namespaces */ axutil_hash_t *namespaces; /* denotes whether current element is an empty element. i.e. @@ -59,14 +59,12 @@ struct axiom_element * 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 elment. cannot 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 declared and will be + * then the namespace structure ns will be cloned and declared and will be * freed when the tree is freed. - * If the value of the namespace has already been declared using - * another namespace structure then the namespace structure ns - * will be 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 @@ -81,18 +79,13 @@ axiom_element_create( 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; - } + AXIS2_ASSERT(localname != NULL); + AXIS2_ASSERT(node != NULL); + AXIS2_ASSERT(env != 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 needed by element"); return NULL; } @@ -100,7 +93,7 @@ axiom_element_create( element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t)); if(!element) { - AXIS2_FREE(env->allocator, (*node)); + 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; @@ -110,9 +103,8 @@ axiom_element_create( element->localname = axutil_string_create(env, localname); if(!element->localname) { - AXIS2_FREE(env->allocator, element); - AXIS2_FREE(env->allocator, (*node)); - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + 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; } @@ -126,34 +118,27 @@ axiom_element_create( 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(ns != element->ns) - { - axiom_namespace_free(ns, env); - ns = NULL; - } - } - else + if(axiom_element_set_namespace(element, env, ns, *node) != AXIS2_SUCCESS) { - if(axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS) - { - element->ns = ns; - } + 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, @@ -161,243 +146,283 @@ axiom_element_create_with_qname( const axutil_qname_t * qname, axiom_node_t ** node) { - axiom_element_t *element = NULL; - axis2_char_t *localpart = NULL; + 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); - AXIS2_ENV_CHECK(env, NULL); - if(!qname || !node) - { - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); - AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "qname or node is NULL"); - return NULL; - } localpart = axutil_qname_get_localpart(qname, env); - if(!localpart) - { - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); - AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localpart is NULL"); - return NULL; - } + 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; } - if(*node) + 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)) { - axiom_element_t *om_element = NULL; - axis2_char_t *temp_nsuri = NULL; - axis2_char_t *temp_prefix = NULL; - axiom_namespace_t *ns = NULL; + /** no namespace uri is available in given qname no need to bother about it */ + return element; + } - om_element = ((axiom_element_t *)axiom_node_get_data_element((*node), env)); - temp_nsuri = axutil_qname_get_uri(qname, env); - temp_prefix = axutil_qname_get_prefix(qname, env); - if(!om_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((!temp_nsuri) || (axutil_strcmp(temp_nsuri, "") == 0)) + if(axiom_element_declare_namespace(element, env, *node, ns) != AXIS2_SUCCESS) { - - /** no namespace uri is available in given qname - no need to bother about it - */ - return om_element; + 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; } - om_element->ns = axiom_element_find_namespace(om_element, env, (*node), temp_nsuri, - temp_prefix); - - if(!(element->ns)) - { - - /** could not find a namespace so declare namespace */ - ns = axiom_namespace_create(env, temp_nsuri, temp_prefix); - if(ns && axiom_element_declare_namespace(om_element, env, *node, ns) == AXIS2_SUCCESS) - { - (element->ns) = ns; - return om_element; - } - else - { - if(ns) - { - axiom_namespace_free(ns, env); - } - axiom_element_free(om_element, env); - AXIS2_FREE(env->allocator, *node); - 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; } -AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL -axiom_element_find_namespace( +/** + * 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, - axiom_node_t * element_node, - const axis2_char_t * uri, - const axis2_char_t * prefix) + const axutil_env_t * env) { - axiom_node_t *parent = NULL; - AXIS2_ENV_CHECK(env, NULL); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(om_element->localname != NULL); - if(!element_node || !om_element) + axutil_string_free(om_element->localname, env); + if(om_element->ns) { - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); - AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element_node or om_element is NULL"); - return NULL; + axiom_namespace_free(om_element->ns, env); } - if(!axiom_node_get_data_element(element_node, env) || axiom_node_get_node_type(element_node, - env) != AXIOM_ELEMENT) + + if(om_element->attributes) { - /* wrong element type or null node */ - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); - AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Wrong element type or null node"); - return NULL; + 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) { - void *ns = NULL; - - if(uri && (!prefix || axutil_strcmp(prefix, "") == 0)) + 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); + } - /** check for a default namepsace */ - axiom_namespace_t *default_ns = NULL; - axutil_hash_index_t *hashindex; - - default_ns = axiom_element_get_default_namespace(om_element, env, element_node); - if(default_ns) - { - axis2_char_t *default_uri = NULL; - default_uri = axiom_namespace_get_uri(default_ns, 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); +} - if(axutil_strcmp(uri, default_uri) == 0) - { - return default_ns; - } - } +/** + * 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 */ - for(hashindex = axutil_hash_first(om_element->namespaces, env); hashindex; hashindex - = axutil_hash_next(env, hashindex)) + 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 = NULL; - axis2_char_t *temp_nsuri = NULL; - temp_ns = (axiom_namespace_t *)ns; - temp_nsuri = axiom_namespace_get_uri(temp_ns, env); - + 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 hashindex and return ns*/ + /** namespace uri matches, so free hash index and return ns*/ AXIS2_FREE(env->allocator, hashindex); - return (axiom_namespace_t *)(ns); + return temp_ns; } - temp_ns = NULL; - temp_nsuri = NULL; - ns = NULL; } } - ns = NULL; } else if(prefix) { - /** prefix is not null get namespace directly if exist */ - ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); + axiom_namespace_t *ns = (axiom_namespace_t *)axutil_hash_get( + om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); if(ns) { - axiom_namespace_t *found_ns = NULL; - axis2_char_t *found_uri = NULL; - found_ns = (axiom_namespace_t *)ns; - found_uri = axiom_namespace_get_uri(found_ns, env); - if(uri) + /* if uri provided, return found ns only if uri matches */ + if((uri) && (axutil_strcmp(axiom_namespace_get_uri(ns, env), uri) != 0)) { - /* if uri provided, return found ns only if uri matches */ - return (axutil_strcmp(found_uri, uri) == 0) ? found_ns : NULL; + ns = NULL; } - return found_ns; - } - } - } - - /** could not find the namespace in current element scope - look in the parent */ - - parent = axiom_node_get_parent(element_node, env); - - if(parent) - { - if(axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) - { - axiom_element_t *om_element = NULL; - 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 ns; } } } return NULL; } -AXIS2_EXTERN axis2_status_t AXIS2_CALL -axiom_element_declare_namespace_assume_param_ownership( +/** + * 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_namespace_t * ns) + axiom_node_t * element_node, + const axis2_char_t * uri, + const axis2_char_t * prefix) { - axis2_char_t *prefix = NULL; - axis2_char_t *uri = NULL; + axiom_node_t *parent; + axiom_namespace_t *ns; - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(element_node != NULL); - if(!ns || !om_element) + /* check whether we can find the namespace in current element scope */ + ns = axiom_element_find_declared_namespace(om_element, env, uri, prefix); + if(ns) { - 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; + return ns; } - uri = axiom_namespace_get_uri(ns, env); - prefix = axiom_namespace_get_prefix(ns, env); - - if(!(om_element->namespaces)) + /* 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)) { - om_element->namespaces = axutil_hash_make(env); - if(!(om_element->namespaces)) + axiom_element_t *om_element; + om_element = (axiom_element_t *)axiom_node_get_data_element(parent, env); + if(om_element) { - return AXIS2_FAILURE; + /** parent exist, parent is om element so find in parent*/ + return axiom_element_find_namespace(om_element, env, parent, uri, prefix); } } - if(prefix) - { - axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns); - } - else - { - axis2_char_t *key = NULL; - key = AXIS2_MALLOC(env->allocator, sizeof(char) * 10); - memset(key, 0, sizeof(char) * 10); - key[0] = '\0'; - axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns); - } - axiom_namespace_increment_ref(ns, env); + return NULL; +} - return AXIS2_SUCCESS; +/** + * 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, @@ -405,142 +430,182 @@ axiom_element_declare_namespace( axiom_node_t * node, axiom_namespace_t * ns) { - axiom_namespace_t *declared_ns = NULL; - axis2_char_t *prefix = NULL; - axis2_char_t *uri = NULL; + axiom_namespace_t *declared_ns; + axis2_char_t *prefix; + axis2_char_t *uri; - if(!node || !ns || !om_element) - { - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); - AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "node or namespace or om_element is NULL"); - return AXIS2_FAILURE; - } + 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) { - if(axiom_namespace_equals(ns, env, declared_ns) == AXIS2_TRUE) - { - /*Namespace already declared, so return */ - return AXIS2_SUCCESS; - } + /*Namespace already declared, so return */ + return AXIS2_SUCCESS; } - if(!(om_element->namespaces)) + if(!om_element->namespaces) { om_element->namespaces = axutil_hash_make(env); - if(!(om_element->namespaces)) + 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 { - axis2_char_t *key = NULL; - key = AXIS2_MALLOC(env->allocator, sizeof(char) * 10); - memset(key, 0, sizeof(char) * 10); + /* 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; } -AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL -axiom_element_find_declared_namespace( +/** + * 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, - const axis2_char_t * uri, - const axis2_char_t * prefix) + axiom_node_t * element_node) { - axutil_hash_index_t *hash_index = NULL; - void *ns = NULL; - AXIS2_ENV_CHECK(env, NULL); + axiom_node_t *parent_node; + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(element_node != NULL); - if(!(om_element->namespaces)) - { - return NULL; - } - if(uri && (!prefix || axutil_strcmp(prefix, "") == 0)) + if(om_element->namespaces) { - /** prefix null iterate the namespace hash for matching uri */ - for(hash_index = axutil_hash_first(om_element->namespaces, env); hash_index; hash_index - = axutil_hash_next(env, hash_index)) + axiom_namespace_t *default_ns; + default_ns = axutil_hash_get(om_element->namespaces, "", AXIS2_HASH_KEY_STRING); + if(default_ns) { - axutil_hash_this(hash_index, NULL, NULL, &ns); - if(ns) - { - axiom_namespace_t *temp_ns = NULL; - axis2_char_t *temp_nsuri = NULL; - temp_ns = (axiom_namespace_t *)(ns); - temp_nsuri = axiom_namespace_get_uri(temp_ns, env); - if(axutil_strcmp(temp_nsuri, uri) == 0) - { - AXIS2_FREE(env->allocator, hash_index); - return temp_ns; - } - temp_ns = NULL; - temp_nsuri = NULL; - } + return default_ns; } - ns = NULL; - return NULL; } - else if(prefix) + + parent_node = axiom_node_get_parent(element_node, env); + if((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT)) { - axiom_namespace_t *found_ns = NULL; - ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); - if(ns) - { - axis2_char_t *found_uri = NULL; - found_ns = (axiom_namespace_t *)ns; - found_uri = axiom_namespace_get_uri(found_ns, env); - /* If uri provided, ensure this namespace found by prefix matches the uri */ - if(uri) - { - return (axutil_strcmp(found_uri, uri) == 0) ? found_ns : NULL; - } - return found_ns; - } + 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_find_namespace_with_qname( - axiom_element_t * element, +axiom_element_get_namespace( + axiom_element_t * om_element, const axutil_env_t * env, - axiom_node_t * node, - axutil_qname_t * qname) + axiom_node_t * ele_node) { - AXIS2_ENV_CHECK(env, NULL); - if(!element || !node || !qname) - { - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); - AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element or node or qname is NULL"); - return NULL; - } + axiom_namespace_t *ns; + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(ele_node != NULL); - if(axutil_qname_get_uri(qname, env)) + if(om_element->ns) { - return axiom_element_find_namespace(element, env, node, axutil_qname_get_uri(qname, env), - axutil_qname_get_prefix(qname, env)); + ns = om_element->ns; } else { - return NULL; + 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, @@ -548,40 +613,32 @@ axiom_element_add_attribute( axiom_attribute_t * attribute, axiom_node_t * element_node) { + axutil_qname_t *qname; + axiom_namespace_t *om_namespace; - axutil_qname_t *qname = NULL; - axiom_namespace_t *om_namespace = NULL; - axiom_namespace_t *temp_ns = NULL; - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, attribute, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); + AXIS2_ASSERT(attribute != NULL); + AXIS2_ASSERT(element_node != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(om_element != NULL); - /* ensure the attribute's namespace structure is declared */ om_namespace = axiom_attribute_get_namespace(attribute, env); if(om_namespace) { - temp_ns = axiom_element_find_namespace(om_element, env, element_node, - axiom_namespace_get_uri(om_namespace, env), axiom_namespace_get_prefix(om_namespace, - env)); - if(temp_ns != om_namespace) + /* Declare the namespace in element */ + if(axiom_element_declare_namespace(om_element, env, element_node, om_namespace) + != AXIS2_SUCCESS) { - axis2_status_t status; - /* as the attribute's namespace structure is not declared in scope, - declare it here */ - status = axiom_element_declare_namespace_assume_param_ownership(om_element, env, - om_namespace); - if(status != AXIS2_SUCCESS) - { - return status; - } + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to declare attribute namespace"); + return AXIS2_FAILURE; } } - if(!(om_element->attributes)) + if(!om_element->attributes) { om_element->attributes = axutil_hash_make(env); - if(!(om_element->attributes)) + if(!om_element->attributes) { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create hash map to store attributes"); return AXIS2_FAILURE; } } @@ -593,384 +650,436 @@ axiom_element_add_attribute( axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, attribute); axiom_attribute_increment_ref(attribute, env); } - return ((qname) ? AXIS2_SUCCESS : AXIS2_FAILURE); + 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 = NULL; - axiom_attribute_t *attr = NULL; - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, qname, NULL); + axis2_char_t *name; + void *attr; - name = axutil_qname_to_string(qname, env); + 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; + } - if((om_element->attributes) && name) + name = axutil_qname_to_string(qname, env); + if(!name) { - attr = (axiom_attribute_t *)(axutil_hash_get(om_element->attributes, name, - AXIS2_HASH_KEY_STRING)); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to get string representation of qname"); + return NULL; } - return attr; + + attr = axutil_hash_get(om_element->attributes, name, AXIS2_HASH_KEY_STRING); + return (axiom_attribute_t *)attr; } -AXIS2_EXTERN void AXIS2_CALL -axiom_element_free( +/** + * 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) { - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); - if(!om_element) + + 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) { - return; + /* cannot find the attribute with given name. But this might not be an error, and a valid + * case */ + return NULL; } - if(om_element->localname) + 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) { - axutil_string_free(om_element->localname, env); + /* no attributes defined */ + return NULL; } - if(om_element->ns) + + ht_cloned = axutil_hash_make(env); + if(!ht_cloned) { - /* it is the responsibility of the element where the namespace is declared to free it */ + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create hashmap to extract attributes"); + return NULL; } - if(om_element->attributes) + + for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) { - axutil_hash_index_t *hi; - void *val = NULL; + void *val; + axiom_attribute_t *cloned_attr; + axis2_char_t *key = NULL; - for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) - { - axutil_hash_this(hi, NULL, NULL, &val); + axutil_hash_this(hi, NULL, NULL, &val); + AXIS2_ASSERT(val != NULL); - if(val) + 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) { - axiom_attribute_free((axiom_attribute_t *)val, env); + key = axutil_qname_to_string(qn, env); } } - axutil_hash_free(om_element->attributes, env); - } - if(om_element->namespaces) - { - axutil_hash_index_t *hi; - void *val = NULL; - for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi)) + if(key) { - axutil_hash_this(hi, NULL, NULL, &val); - if(val) - { - axiom_namespace_free((axiom_namespace_t *)val, env); - } + 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; } - 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); - - return; + return ht_cloned; } -AXIS2_EXTERN axis2_status_t AXIS2_CALL -axiom_element_serialize_start_part( +/** + * 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, - axiom_output_t * om_output, - axiom_node_t * ele_node) + axis2_char_t * attr_name) { - int status = AXIS2_SUCCESS; + axutil_hash_index_t *hi; - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + AXIS2_ASSERT(attr_name != NULL); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); - if(om_element->is_empty) + if(!om_element->attributes) { - if(om_element->ns) - { - axis2_char_t *uri = NULL; - axis2_char_t *prefix = NULL; - - uri = axiom_namespace_get_uri(om_element->ns, env); - prefix = axiom_namespace_get_prefix(om_element->ns, env); - - if((uri) && (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 if(uri) - { - 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); - } + /* no attributes are defined. */ + return NULL; } - else + + for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) { - if(om_element->ns) - { - axis2_char_t *uri = NULL; - axis2_char_t *prefix = NULL; + void *attr; + axis2_char_t *this_attr_name; + axiom_namespace_t *attr_ns; + axis2_char_t *prefix; - uri = axiom_namespace_get_uri(om_element->ns, env); - prefix = axiom_namespace_get_prefix(om_element->ns, env); + axutil_hash_this(hi, NULL, NULL, &attr); + AXIS2_ASSERT(attr != NULL); - if((uri) && (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 if(uri) + 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) { - status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 2, - axutil_string_get_buffer(om_element-> localname, env), uri); + /* not the attribute we are looking for */ + AXIS2_FREE(env->allocator, attr_qn_str); + continue; } + AXIS2_FREE(env->allocator, attr_qn_str); } else { - status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 1, axutil_string_get_buffer( - om_element-> localname, 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); - - if(val) - { - status = axiom_attribute_serialize((axiom_attribute_t *)val, env, om_output); - } - else + /* no namespace or no prefix. so compare only local name */ + if(axutil_strcmp(this_attr_name, attr_name) != 0) { - status = AXIS2_FAILURE; + /* not the attribute we are looking for */ + continue; } } - } - if(om_element->namespaces) + /* 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) { - axutil_hash_index_t *hi; - void *val; - for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi)) + 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) { - axutil_hash_this(hi, NULL, NULL, &val); + const axis2_char_t *temp_text; + axiom_text_t *text_ele; - if(val) + 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) { - status = axiom_namespace_serialize((axiom_namespace_t *)val, env, om_output); + axis2_char_t *temp_dest = axutil_stracat(env, dest, temp_text); + AXIS2_FREE(env->allocator, dest); + dest = temp_dest; } - else + else if(!dest && temp_text && axutil_strcmp(temp_text, "") != 0) { - status = AXIS2_FAILURE; + dest = axutil_strdup(env, temp_text); } } + temp_node = axiom_node_get_next_sibling(temp_node, env); } - return status; + 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_serialize_end_part( +axiom_element_set_text( axiom_element_t * om_element, const axutil_env_t * env, - axiom_output_t * om_output) + const axis2_char_t * text, + axiom_node_t * element_node) { - int status = AXIS2_SUCCESS; - AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); - status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 0); - return status; -} + axiom_node_t *temp_node, *next_node; -AXIS2_EXTERN axis2_char_t *AXIS2_CALL -axiom_element_get_localname( - axiom_element_t * om_element, - const axutil_env_t * env) -{ - if(om_element->localname) - return (axis2_char_t *)axutil_string_get_buffer(om_element->localname, env); - else - return NULL; -} + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(text != NULL); + AXIS2_ASSERT(element_node != NULL); -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) -{ - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); - if(om_element->localname) + next_node = axiom_node_get_first_child(element_node, env); + while(next_node) { - axutil_string_free(om_element->localname, env); - om_element->localname = NULL; + 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); + } } - om_element->localname = axutil_string_create(env, localname); - if(!(om_element->localname)) + + 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; } -AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL -axiom_element_get_namespace( +/** + * 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, - axiom_node_t * ele_node) + const axutil_env_t * env) { - axiom_namespace_t *ns = NULL; - AXIS2_ENV_CHECK(env, NULL); - - if(om_element->ns) - { - ns = om_element->ns; - } - else - { - ns = axiom_element_get_default_namespace(om_element, env, ele_node); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(om_element->localname != NULL); - } - return ns; + 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_namespace( +axiom_element_set_localname( axiom_element_t * om_element, const axutil_env_t * env, - axiom_namespace_t * ns, - axiom_node_t * node) + const axis2_char_t * localname) { - axiom_namespace_t *om_ns = NULL; - axis2_status_t status = AXIS2_SUCCESS; - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, ns, AXIS2_FAILURE); - om_ns = axiom_element_find_namespace(om_element, env, node, axiom_namespace_get_uri(ns, env), - axiom_namespace_get_prefix(ns, env)); - if(!om_ns) - { - status = axiom_element_declare_namespace(om_element, env, node, ns); - if(status == AXIS2_FAILURE) - { - return AXIS2_FAILURE; - } - om_element->ns = ns; - } - else + 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) { - om_element->ns = om_ns; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to set local name of element"); + return AXIS2_FAILURE; } - 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; + axutil_string_free(om_element->localname, env); + om_element->localname = new_name; return AXIS2_SUCCESS; } -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; -} - -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; -} - +/** + * 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) { - axiom_namespace_t *ns = NULL; - AXIS2_ENV_CHECK(env, NULL); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(ele_node != NULL); - if(om_element->qname) - { - return om_element->qname; - } - else + if(!om_element->qname) { - ns = axiom_element_get_namespace(om_element, env, ele_node); + 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) { - if(axiom_namespace_get_prefix(ns, env)) - { - om_element->qname = axutil_qname_create(env, axutil_string_get_buffer( - om_element->localname, env), axiom_namespace_get_uri(ns, env), - axiom_namespace_get_prefix(ns, env)); - } - else - { - om_element->qname = axutil_qname_create(env, axutil_string_get_buffer( - om_element->localname, env), axiom_namespace_get_uri(ns, env), NULL); - } - } - else - { - om_element->qname = axutil_qname_create(env, axutil_string_get_buffer( - om_element->localname, env), NULL, NULL); + 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_PARAM_CHECK(env->error, element_node, NULL); + 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)); + om_element->children_iter = axiom_children_iterator_create(env, + axiom_node_get_first_child(element_node, env)); } else { @@ -979,6 +1088,14 @@ axiom_element_get_children( 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, @@ -986,51 +1103,50 @@ axiom_element_get_children_with_qname( axutil_qname_t * element_qname, axiom_node_t * element_node) { - AXIS2_PARAM_CHECK(env->error, element_node, NULL); + 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 = NULL; } 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 * element_qname, + axutil_qname_t * qname, axiom_node_t * element_node, axiom_node_t ** child_node) { - axiom_node_t *om_node = NULL; - axiom_children_qname_iterator_t *children_iterator = NULL; - - AXIS2_PARAM_CHECK(env->error, element_qname, NULL); - AXIS2_PARAM_CHECK(env->error, element_node, NULL); - - om_node = axiom_node_get_first_child(element_node, env); - if(!om_node) - { - AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "There are no child elements for the node"); - return NULL; - } - children_iterator = axiom_children_qname_iterator_create(env, om_node, element_qname); + 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_DEBUG(env->log, AXIS2_LOG_SI, "Could not create children qname iterator"); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Could not get children qname iterator"); return NULL; } - om_node = NULL; + if(axiom_children_qname_iterator_has_next(children_iterator, env)) { - om_node = axiom_children_qname_iterator_next(children_iterator, env); - } - if(om_node && (axiom_node_get_node_type(om_node, env) == AXIOM_ELEMENT)) - { - axiom_children_qname_iterator_free(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) { @@ -1039,35 +1155,16 @@ axiom_element_get_first_child_with_qname( return (axiom_element_t *)axiom_node_get_data_element(om_node, env); } - axiom_children_qname_iterator_free(children_iterator, env); - return NULL; } -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; -} - +/** + * 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, @@ -1075,9 +1172,10 @@ axiom_element_get_first_element( axiom_node_t * element_node, axiom_node_t ** first_ele_node) { - axiom_node_t *temp_node = NULL; - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, element_node, NULL); + 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) @@ -1098,200 +1196,407 @@ axiom_element_get_first_element( return NULL; } -AXIS2_EXTERN axis2_char_t *AXIS2_CALL -axiom_element_get_text( +/** + * 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_char_t *dest = NULL; - const axis2_char_t *temp_text = NULL; - axiom_text_t *text_node = NULL; - axiom_node_t *temp_node = NULL; + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(element_node != NULL); - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, element_node, NULL); - - if(om_element->text_value) + if(om_element->child_ele_iter) { - AXIS2_FREE(env->allocator, om_element->text_value); - om_element->text_value = NULL; + return om_element->child_ele_iter; } - - temp_node = axiom_node_get_first_child(element_node, env); - - while(temp_node) + else { - if(axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT) + axiom_node_t *first_node; + axiom_element_t *ele; + ele = axiom_element_get_first_element(om_element, env, element_node, &first_node); + if(ele) { - int dest_len = 0; - int curr_len = 0; - axis2_char_t *temp_dest = NULL; - - text_node = (axiom_text_t *)axiom_node_get_data_element(temp_node, env); - if(text_node) - { - temp_text = axiom_text_get_value(text_node, env); - if(dest && temp_text && axutil_strcmp(temp_text, "") != 0) - { - dest_len = axutil_strlen(dest); - curr_len = dest_len + axutil_strlen(temp_text); - temp_dest = AXIS2_MALLOC(env->allocator, (curr_len + 1) * sizeof(axis2_char_t)); - - memcpy(temp_dest, dest, dest_len * sizeof(axis2_char_t)); - memcpy((temp_dest + dest_len * sizeof(axis2_char_t)), temp_text, curr_len - - dest_len); - - temp_dest[curr_len] = '\0'; - - AXIS2_FREE(env->allocator, dest); - dest = NULL; - dest = temp_dest; - } - else if(!dest && temp_text && axutil_strcmp(temp_text, "") != 0) - { - dest = axutil_strdup(env, temp_text); - } - } + AXIS2_ASSERT(first_node != NULL); + om_element->child_ele_iter = axiom_child_element_iterator_create(env, first_node); + return om_element->child_ele_iter; } - temp_node = axiom_node_get_next_sibling(temp_node, env); } - - om_element->text_value = dest; - return om_element->text_value; + return NULL; } -AXIS2_EXTERN axis2_status_t AXIS2_CALL -axiom_element_set_text( + + +/** + * 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, - const axis2_char_t * text, - axiom_node_t * element_node) + axiom_node_t * om_node) { - axiom_node_t *temp_node, *next_node; - axiom_text_t *om_text = NULL; - AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); + axutil_hash_t *inscope_namespaces; + axiom_node_t *parent_node = om_node; - next_node = axiom_node_get_first_child(element_node, env); - while(next_node) + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(om_node != NULL); + + inscope_namespaces = axutil_hash_make(env); + if(!inscope_namespaces) { - 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) + 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) { - axiom_node_free_tree(temp_node, env); + /* 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); + } } } - om_text = axiom_text_create(env, element_node, text, &temp_node); - return AXIS2_SUCCESS; + return inscope_namespaces; } -AXIS2_EXTERN axis2_char_t *AXIS2_CALL -axiom_element_to_string( +/** + * 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 * element_node) + axiom_node_t * om_node, + axiom_namespace_t *ns, + axutil_hash_t *inscope_namespaces) { - return axiom_node_to_string(element_node, env); + 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); + } + } } -AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL -axiom_element_get_child_elements( +/** + * 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 * element_node) + axiom_node_t * om_node, + axutil_hash_t *inscope_namespaces) { - axiom_node_t *first_node = NULL; - axiom_element_t *ele = NULL; - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, element_node, NULL); - ele = axiom_element_get_first_element(om_element, env, element_node, &first_node); - if(om_element->child_ele_iter) + 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) { - return om_element->child_ele_iter; + 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); + } } - else if(ele && first_node) + + /* 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)) { - om_element->child_ele_iter = axiom_child_element_iterator_create(env, first_node); - return om_element->child_ele_iter; + 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); } - return NULL; } - - -AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL -axiom_element_get_default_namespace( +/** + * 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_node_t * element_node) + axiom_output_t * om_output, + axiom_node_t * ele_node) { - axiom_node_t *parent_node = NULL; - axiom_namespace_t *default_ns = NULL; + axis2_status_t status = AXIS2_SUCCESS; - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, element_node, NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(om_output != NULL); + AXIS2_ASSERT(ele_node != NULL); - if(om_element->namespaces) + if(om_element->is_empty) { - default_ns = axutil_hash_get(om_element->namespaces, "", AXIS2_HASH_KEY_STRING); - if(default_ns) + if(om_element->ns) { - return default_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); - parent_node = axiom_node_get_parent(element_node, env); - if((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT)) + 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) { - axiom_element_t *parent_ele = NULL; - parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); - if(parent_ele) + 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)) { - return axiom_element_get_default_namespace(parent_ele, env, parent_node); + 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; + } } } - return NULL; + + 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; } /** - * declared a default namespace explicitly + * 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_EXTERN axiom_namespace_t *AXIS2_CALL -axiom_element_declare_default_namespace( +axis2_status_t AXIS2_CALL +axiom_element_serialize_end_part( axiom_element_t * om_element, const axutil_env_t * env, - axis2_char_t * uri) + axiom_output_t * om_output) { - axiom_namespace_t *default_ns = NULL; - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, uri, NULL); + AXIS2_ASSERT(env != NULL); + AXIS2_ASSERT(om_element != NULL); + AXIS2_ASSERT(om_output != NULL); - if(axutil_strcmp(uri, "") == 0) + 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; +} + +#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 NULL; + return AXIS2_FAILURE; } - default_ns = axiom_namespace_create(env, uri, ""); - if(!default_ns) + builder = axiom_node_get_builder(om_ele_node, env); + if(!builder) { - return NULL; + return AXIS2_FAILURE; } - if(!om_element->namespaces) + while(!axiom_node_is_complete(om_ele_node, env) + && !axiom_stax_builder_is_complete(builder, env)) { - om_element->namespaces = axutil_hash_make(env); - if(!(om_element->namespaces)) + void *value = NULL; + value = axiom_stax_builder_next(builder, env); + if(!value) { - axiom_namespace_free(default_ns, env); - return NULL; + return AXIS2_FAILURE; } } - - axutil_hash_set(om_element->namespaces, "", AXIS2_HASH_KEY_STRING, default_ns); - axiom_namespace_increment_ref(default_ns, env); - return default_ns; + return AXIS2_SUCCESS; } /** @@ -1335,167 +1640,140 @@ axiom_element_find_namespace_uri( return NULL; } -AXIS2_EXTERN axis2_char_t *AXIS2_CALL -axiom_element_get_attribute_value( +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_qname_t * qname) + axutil_string_t * localname) { - axis2_char_t *name = NULL; - axiom_attribute_t *attr = NULL; - AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, qname, NULL); + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); - name = axutil_qname_to_string(qname, env); + 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_declare_namespace_assume_param_ownership( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_namespace_t * ns) +{ + axis2_char_t *prefix = NULL; + axis2_char_t *uri = NULL; - if((om_element->attributes) && (NULL != name)) + if(!ns || !om_element) { - attr = (axiom_attribute_t *)axutil_hash_get(om_element->attributes, name, - AXIS2_HASH_KEY_STRING); - if(attr) + 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; + } + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + if(!(om_element->namespaces)) + { + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) { - return axiom_attribute_get_value(attr, env); + return AXIS2_FAILURE; } } - return NULL; + if(prefix) + { + axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns); + } + else + { + axis2_char_t *key = NULL; + key = AXIS2_MALLOC(env->allocator, sizeof(char) * 10); + memset(key, 0, sizeof(char) * 10); + key[0] = '\0'; + axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns); + } + axiom_namespace_increment_ref(ns, env); + + return AXIS2_SUCCESS; } AXIS2_EXTERN axis2_status_t AXIS2_CALL -axiom_element_set_namespace_with_no_find_in_current_scope( +axiom_element_set_namespace_assume_param_ownership( axiom_element_t * om_element, const axutil_env_t * env, - axiom_namespace_t * om_ns) + axiom_namespace_t * ns) { - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); - AXIS2_PARAM_CHECK(env->error, om_ns, AXIS2_FAILURE); - om_element->ns = om_ns; + om_element->ns = ns; return AXIS2_SUCCESS; } -AXIS2_EXTERN axutil_hash_t *AXIS2_CALL -axiom_element_extract_attributes( +/** + * 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, - axiom_node_t * ele_node) + axis2_char_t * uri) { - axutil_hash_index_t *hi = NULL; - axutil_hash_t *ht_cloned = NULL; - - axiom_attribute_t *om_attr = NULL; - axiom_attribute_t *cloned_attr = NULL; - - axiom_namespace_t *om_ns = NULL; - /*axiom_namespace_t *cloned_ns = NULL; */ - - axis2_char_t *key = NULL; - axutil_qname_t *qn = NULL; + axiom_namespace_t *default_ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); - AXIS2_PARAM_CHECK(env->error, ele_node, NULL); - if(!om_element->attributes) - { - return NULL; - } - ht_cloned = axutil_hash_make(env); - if(!ht_cloned) + if(axutil_strcmp(uri, "") == 0) { - AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); return NULL; } - for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) - { - void *val = NULL; - axutil_hash_this(hi, NULL, NULL, &val); - if(val) - { - om_attr = (axiom_attribute_t *)val; - cloned_attr = axiom_attribute_clone(om_attr, env); - - om_ns = axiom_attribute_get_namespace(om_attr, env); - if(om_ns) - { - /*cloned_ns = axiom_namespace_clone(om_ns, env); */ - /*axiom_attribute_set_namespace(cloned_attr, env, cloned_ns); */ - axiom_attribute_set_namespace(cloned_attr, env, om_ns); - } - qn = axiom_attribute_get_qname(cloned_attr, env); - key = axutil_qname_to_string(qn, env); - axutil_hash_set(ht_cloned, key, AXIS2_HASH_KEY_STRING, cloned_attr); - } - val = NULL; - key = NULL; - qn = NULL; - om_attr = NULL; - cloned_attr = NULL; - om_ns = NULL; - /*cloned_ns = NULL; */ - } - return ht_cloned; -} - -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 = NULL; - - AXIS2_PARAM_CHECK(env->error, attr_name, NULL); - if(!om_element->attributes) + default_ns = axiom_namespace_create(env, uri, ""); + if(!default_ns) { return NULL; } - for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) + if(!om_element->namespaces) { - void *attr = NULL; - axiom_attribute_t *om_attr = NULL; - axutil_hash_this(hi, NULL, NULL, &attr); - if(attr) + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) { - axis2_char_t *this_attr_name; - axis2_char_t *this_attr_value; - axis2_char_t *attr_qn_str = NULL; - axiom_namespace_t *attr_ns = NULL; - axis2_char_t *prefix = NULL; - - om_attr = (axiom_attribute_t *)attr; - this_attr_name = axiom_attribute_get_localname(om_attr, env); - this_attr_value = axiom_attribute_get_value(om_attr, env); - attr_ns = axiom_attribute_get_namespace(om_attr, env); - if(attr_ns) - { - prefix = axiom_namespace_get_prefix(attr_ns, env); - if(prefix) - { - axis2_char_t *tmp_val = NULL; - tmp_val = axutil_stracat(env, prefix, ":"); - attr_qn_str = axutil_stracat(env, tmp_val, this_attr_name); - if(tmp_val) - { - AXIS2_FREE(env->allocator, tmp_val); - tmp_val = NULL; - } - } - } - else - { - attr_qn_str = axutil_strdup(env, this_attr_name); - } - - if(attr_qn_str && axutil_strcmp(attr_qn_str, attr_name) == 0) - { - AXIS2_FREE(env->allocator, attr_qn_str); - attr_qn_str = NULL; - AXIS2_FREE(env->allocator, hi); - return this_attr_value; - } - - AXIS2_FREE(env->allocator, attr_qn_str); - attr_qn_str = NULL; + axiom_namespace_free(default_ns, env); + return NULL; } } - 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 @@ -1568,38 +1846,6 @@ axiom_element_create_str( return element; } -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_bool_t AXIS2_CALL axiom_element_get_is_empty( axiom_element_t * om_element, @@ -1608,189 +1854,36 @@ axiom_element_get_is_empty( return om_element->is_empty; } -AXIS2_EXTERN 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; -} - -/** - * Scan the parents of the element, to determine which namespaces are inscope for the - * the element and its children. - */ -AXIS2_EXTERN 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 = NULL; - axiom_node_t *parent_node = om_node; - - 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 = (axiom_element_t *)axiom_node_get_data_element( - parent_node, env); - axutil_hash_t *parent_namespaces = axiom_element_get_namespaces(parent_element, env); - if(parent_namespaces) - { - axutil_hash_index_t *hi; - void *val; - for(hi = axutil_hash_first(parent_namespaces, env); hi; hi = axutil_hash_next(env, hi)) - { - axutil_hash_this(hi, NULL, NULL, &val); - if(val) - { - /* Check if prefix is already associated with some namespace in node being detached */ - if(!axiom_element_find_declared_namespace(om_element, env, NULL, - axiom_namespace_get_prefix((axiom_namespace_t *)val, env))) - { - axis2_char_t *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(!(inscope_namespaces && axutil_hash_get(inscope_namespaces, key, - AXIS2_HASH_KEY_STRING))) - { - /* Remember this namespace as needing to be declared, if used */ - if(!inscope_namespaces) - inscope_namespaces = axutil_hash_make(env); - if(inscope_namespaces) - axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, val); - } - } - } - } - } - } - - return inscope_namespaces; -} - -/** - * Test if the provided namespace pointer is declared in a parent namespace - * If so, redeclare it in the provided root element - */ -AXIS2_EXTERN 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, - axiom_element_t * root_element, - axutil_hash_t *inscope_namespaces) -{ - 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 && (parent_ns == ns) && (ns != axiom_element_find_namespace(om_element, env, - om_node, axiom_namespace_get_uri(ns, env), axiom_namespace_get_prefix(ns, env)))) - { - /* Redeclare this parent namespace at the level of the element being detached */ - axiom_element_declare_namespace_assume_param_ownership(root_element, env, 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); - } - } -} - -/** - * For each child node, determine if it uses a namespace from a parent of the node being detached - * If so, re-declare that namespace in the node being detached - */ -AXIS2_EXTERN void AXIS2_CALL -axiom_element_redeclare_parent_namespaces( +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_remove_attribute( axiom_element_t * om_element, const axutil_env_t * env, - axiom_node_t * om_node, - axiom_element_t * root_element, - axutil_hash_t *inscope_namespaces) + axiom_attribute_t * om_attribute) { - axiom_node_t *child_node; - axutil_hash_t * attributes; - - if(!om_element || !om_node || !inscope_namespaces) - return; - - /* ensure the element's namespace is declared */ - axiom_element_use_parent_namespace(om_element, env, om_node, om_element->ns, root_element, - inscope_namespaces); - - /* for each attribute, ensure the attribute's namespace is declared */ - attributes = om_element->attributes; - if(attributes) - { - axutil_hash_index_t *hi; - void *val; - for(hi = axutil_hash_first(attributes, env); hi; hi = axutil_hash_next(env, hi)) - { - axutil_hash_this(hi, NULL, NULL, &val); - if(val) - { - axiom_element_use_parent_namespace(om_element, env, om_node, - axiom_attribute_get_namespace((axiom_attribute_t *)val, env), root_element, - inscope_namespaces); - } - } - } + axutil_qname_t *qname = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_attribute, AXIS2_FAILURE); - /* 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)) + qname = axiom_attribute_get_qname(om_attribute, env); + if(qname && (om_element->attributes)) { - if(axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT) + axis2_char_t *name = NULL; + name = axutil_qname_to_string(qname, env); + if(name) { - axiom_element_redeclare_parent_namespaces(axiom_node_get_data_element(child_node, env), - env, child_node, root_element, inscope_namespaces); + axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, NULL); + return AXIS2_SUCCESS; } - child_node = axiom_node_get_next_sibling(child_node, env); } + return AXIS2_FAILURE; } -#if 0 -AXIS2_EXTERN axis2_status_t AXIS2_CALL -axiom_element_build( +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_to_string( axiom_element_t * om_element, const axutil_env_t * env, - axiom_node_t * om_ele_node) + axiom_node_t * element_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; + return axiom_node_to_string(element_node, env); } #endif diff --git a/axiom/src/om/om_namespace.c b/axiom/src/om/om_namespace.c index e5a361e..090c523 100644 --- a/axiom/src/om/om_namespace.c +++ b/axiom/src/om/om_namespace.c @@ -53,7 +53,7 @@ axiom_namespace_create( return NULL; } - om_namespace->ref = 0; + om_namespace->ref = 1; om_namespace->prefix = NULL; om_namespace->uri = NULL; om_namespace->key = NULL; diff --git a/axiom/src/om/om_node.c b/axiom/src/om/om_node.c index 6566a1c..eb2a50e 100644 --- a/axiom/src/om/om_node.c +++ b/axiom/src/om/om_node.c @@ -16,8 +16,8 @@ */ #include "axiom_node_internal.h" +#include "axiom_element_internal.h" #include "axiom_stax_builder_internal.h" -#include #include #include #include @@ -332,10 +332,9 @@ axiom_node_detach( axiom_node_t * om_node, const axutil_env_t * env) { - axutil_hash_t *inscope_namespaces = NULL; + axutil_hash_t *namespaces = NULL; axiom_element_t *om_element = NULL; - AXIS2_ENV_CHECK(env, NULL); if(!om_node) { return NULL; @@ -345,7 +344,7 @@ axiom_node_detach( from its parent nodes. */ if((om_node->node_type == AXIOM_ELEMENT) && (om_element = om_node->data_element)) { - inscope_namespaces = axiom_element_gather_parent_namespaces(om_element, env, om_node); + namespaces = axiom_element_gather_parent_namespaces(om_element, env, om_node); } /* Detach this node from its parent. */ @@ -353,15 +352,14 @@ axiom_node_detach( /* If this is an element node, ensure that any namespaces available to it or its children remain available after the detach. */ - if(om_node && inscope_namespaces) + if(om_node && namespaces) { - axiom_element_redeclare_parent_namespaces(om_element, env, om_node, om_element, - inscope_namespaces); + axiom_element_redeclare_parent_namespaces(om_element, env, om_node, namespaces); } - if(inscope_namespaces) + if(namespaces) { - axutil_hash_free(inscope_namespaces, env); + axutil_hash_free(namespaces, env); } return om_node; diff --git a/axiom/src/om/om_stax_builder.c b/axiom/src/om/om_stax_builder.c index 6f43bf0..ddd6f0e 100644 --- a/axiom/src/om/om_stax_builder.c +++ b/axiom/src/om/om_stax_builder.c @@ -16,7 +16,7 @@ */ #include -#include +#include "axiom_element_internal.h" #include #include #include @@ -376,7 +376,7 @@ axiom_stax_builder_process_namespaces( return AXIS2_FAILURE; } - status = axiom_element_declare_namespace_assume_param_ownership(om_ele, env, om_ns); + status = axiom_element_declare_namespace(om_ele, env, node, om_ns); prefix = axiom_namespace_get_prefix(om_ns, env); axutil_hash_set(om_builder->declared_namespaces, prefix, AXIS2_HASH_KEY_STRING, om_ns); } @@ -397,7 +397,7 @@ axiom_stax_builder_process_namespaces( if(om_ns) { - axiom_element_set_namespace_assume_param_ownership(om_ele, env, om_ns); + axiom_element_set_namespace(om_ele, env, om_ns, node); } else { @@ -422,7 +422,6 @@ axiom_stax_builder_create_om_element( axiom_node_t *element_node = NULL; axiom_element_t *om_ele = NULL; axis2_char_t *temp_localname = NULL; - axutil_string_t *temp_localname_str = NULL; axiom_node_t *parent = NULL; temp_localname = axiom_xml_reader_get_name(om_builder->parser, env); @@ -433,13 +432,6 @@ axiom_stax_builder_create_om_element( return NULL; } -#ifdef AXIS2_LIBXML2_ENABLED - temp_localname_str = axutil_string_create(env, temp_localname); - axiom_xml_reader_xml_free(om_builder->parser, env, temp_localname); -#else - temp_localname_str = axutil_string_create_assume_ownership(env, &temp_localname); -#endif - om_builder->element_level++; if(om_builder->lastnode) { @@ -455,8 +447,8 @@ axiom_stax_builder_create_om_element( } } - om_ele = axiom_element_create_str(env, parent, temp_localname_str, NULL, &element_node); - axutil_string_free(temp_localname_str, env); + om_ele = axiom_element_create(env, parent, temp_localname, NULL, &element_node); + axiom_xml_reader_xml_free(om_builder->parser, env, temp_localname); if((!om_ele) || (!element_node)) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create axiom element"); diff --git a/util/include/axutil_utils.h b/util/include/axutil_utils.h index 8c156d1..1cef523 100644 --- a/util/include/axutil_utils.h +++ b/util/include/axutil_utils.h @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" @@ -43,6 +44,9 @@ extern "C" #define AXUTIL_LOG_FILE_SIZE 1024 * 1024 * 32 #define AXUTIL_LOG_FILE_NAME_SIZE 512 + +#define AXIS2_ASSERT assert + /** This macro is called to check whether structure on which function is called * is NULL and to check whether the environment structure passed is valid. * @param object structure on which function is called diff --git a/util/src/qname.c b/util/src/qname.c index e4197c3..49b2069 100644 --- a/util/src/qname.c +++ b/util/src/qname.c @@ -119,7 +119,6 @@ axutil_qname_free( axutil_qname_t *qname, const axutil_env_t *env) { - AXIS2_ENV_CHECK(env, AXIS2_FAILURE); qname->ref--; -- cgit v1.1-32-gdbae