| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <oxs_axiom.h> |
| #include <axiom.h> |
| #include <axiom_util.h> |
| |
| /** |
| * Adds an attribute to a particular node |
| * @param env Environment. MUST NOT be NULL |
| * @param node the node where the attibute will be added |
| * @param attribute_ns the the ns_prefix of the attribute |
| * @param attribute_ns_uri the uri of the attribute |
| * @param attribute the localname of the attribute |
| * @param value the value of the attribute |
| * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE |
| */ |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| oxs_axiom_add_attribute( |
| const axutil_env_t *env, |
| axiom_node_t* node, |
| axis2_char_t* attribute_ns, |
| axis2_char_t* attribute_ns_uri, |
| axis2_char_t* attribute, |
| axis2_char_t* value) |
| { |
| axiom_attribute_t *attr = NULL; |
| axiom_element_t *ele = NULL; |
| axis2_status_t status = AXIS2_FAILURE; |
| axiom_namespace_t *ns = NULL; |
| |
| if(attribute_ns_uri) |
| { |
| ns = axiom_namespace_create(env, attribute_ns_uri, attribute_ns); |
| } |
| |
| ele = axiom_node_get_data_element(node, env); |
| attr = axiom_attribute_create(env, attribute , value, ns); |
| if((!attr) && ns) |
| { |
| axiom_namespace_free(ns, env); |
| } |
| status = axiom_element_add_attribute(ele, env, attr, node); |
| return status; |
| } |
| |
| /** |
| * Finds the number of childern with given qname |
| * @param env Environment. MUST NOT be NULL, |
| * @param parent the root element defining start of the search |
| * @param localname the local part of the qname |
| * @param ns_uri uri part of the qname |
| * @param prefix the prefix part of the qname |
| * @return the number of children found |
| */ |
| AXIS2_EXTERN int AXIS2_CALL |
| oxs_axiom_get_number_of_children_with_qname( |
| const axutil_env_t *env, |
| axiom_node_t* parent, |
| axis2_char_t* local_name, |
| axis2_char_t* ns_uri, |
| axis2_char_t* prefix) |
| { |
| axutil_qname_t *qname = NULL; |
| axiom_element_t *parent_ele = NULL; |
| axiom_children_qname_iterator_t *qname_iter = NULL; |
| int counter = 0; |
| |
| parent_ele = axiom_node_get_data_element(parent, env); |
| if(!parent_ele) |
| { |
| return -1; |
| } |
| |
| qname = axutil_qname_create(env, local_name, ns_uri, prefix); |
| qname_iter = axiom_element_get_children_with_qname(parent_ele, env, qname, parent); |
| while (axiom_children_qname_iterator_has_next(qname_iter , env)) |
| { |
| axiom_node_t *temp_node = NULL; |
| counter++; |
| temp_node = axiom_children_qname_iterator_next(qname_iter, env); |
| } |
| axutil_qname_free(qname, env); |
| qname = NULL; |
| |
| return counter; |
| } |
| |
| /** |
| * Traverse thru the node and its descendents. Check if the localname is equal to the given name |
| * @param env Environment. MUST NOT be NULL, |
| * @param node the node to be searched |
| * @param localname the local name of the node to be searched |
| * @return the node if found, else NULL |
| */ |
| AXIS2_EXTERN axiom_node_t* AXIS2_CALL |
| oxs_axiom_get_node_by_local_name( |
| const axutil_env_t *env, |
| axiom_node_t *node, |
| axis2_char_t *local_name) |
| { |
| axis2_char_t *temp_name = NULL; |
| |
| if(!node) |
| { |
| return NULL; |
| } |
| |
| if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) |
| { |
| return NULL; |
| } |
| |
| temp_name = axiom_util_get_localname(node, env); |
| AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, |
| "[rampart]Checking node %s for %s", temp_name, local_name ); |
| |
| if(!axutil_strcmp(temp_name, local_name)) |
| { |
| /* Gottcha.. return this node */ |
| return node; |
| } |
| else |
| { |
| /* Doesn't match? Get the children and search for them */ |
| axiom_node_t *temp_node = NULL; |
| |
| temp_node = axiom_node_get_first_element(node, env); |
| while(temp_node) |
| { |
| axiom_node_t *res_node = NULL; |
| res_node = oxs_axiom_get_node_by_local_name(env, temp_node, local_name); |
| if(res_node) |
| { |
| return res_node; |
| } |
| temp_node = axiom_node_get_next_sibling(temp_node, env); |
| } |
| } |
| return NULL; |
| } |
| |
| /** |
| * Traverse thru the node and its descendents. Check if the node has a particular attibure value, |
| * whose attribute name as in @attr and value as in @val |
| * @param env Environment. MUST NOT be NULL, |
| * @param node the node to be searched |
| * @param attr the attribute name of the node |
| * @param val the attribute value of the node |
| * @param ns namespace of the attribute |
| * @return the node if found, else NULL |
| */ |
| AXIS2_EXTERN axiom_node_t* AXIS2_CALL |
| oxs_axiom_get_node_by_id( |
| const axutil_env_t *env, |
| axiom_node_t *node, |
| axis2_char_t *attr, |
| axis2_char_t *val, |
| axis2_char_t *ns) |
| { |
| axis2_char_t *attribute_value = NULL; |
| |
| if(!node) |
| { |
| return NULL; |
| } |
| |
| if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) |
| { |
| return NULL; |
| } |
| |
| attribute_value = oxs_axiom_get_attribute_value_of_node_by_name(env, node, attr, ns); |
| |
| if(!axutil_strcmp(val, attribute_value)) |
| { |
| /* Gottcha.. return this node */ |
| return node; |
| } |
| else |
| { |
| /* Doesn't match? Get the children and search recursively. */ |
| axiom_node_t *temp_node = NULL; |
| temp_node = axiom_node_get_first_element(node, env); |
| while (temp_node) |
| { |
| axiom_node_t *res_node = NULL; |
| res_node = oxs_axiom_get_node_by_id(env, temp_node, attr, val, ns); |
| if(res_node) |
| { |
| return res_node; |
| } |
| temp_node = axiom_node_get_next_sibling(temp_node, env); |
| } |
| } |
| |
| return NULL; |
| } |
| |
| /** |
| * Traverse thru the node and its descendents. Check if the node has a particular attribute with |
| * name as in @attr and namespace as in @ns. Returns the attribute value. |
| * @param env Environment. MUST NOT be NULL, |
| * @param node the node to be searched |
| * @param attribute_name the attribute name of the node |
| * @param ns namespace of the attribute |
| * @return the attribute value if found, else NULL |
| */ |
| AXIS2_EXTERN axis2_char_t* AXIS2_CALL |
| oxs_axiom_get_attribute_value_of_node_by_name( |
| const axutil_env_t *env, |
| axiom_node_t *node, |
| axis2_char_t *attribute_name, |
| axis2_char_t *ns_uri) |
| { |
| axis2_char_t *found_val = NULL; |
| axiom_element_t *ele = NULL; |
| axutil_hash_t *attr_list = NULL; |
| axutil_hash_index_t *hi = NULL; |
| |
| ele = axiom_node_get_data_element(node, env); |
| |
| /* Get attribute list of the element */ |
| attr_list = axiom_element_extract_attributes(ele, env, node); |
| if(!attr_list) |
| { |
| return NULL; |
| } |
| |
| /* namespace uri can be NULL. In that case, use empty string */ |
| if(!ns_uri) |
| { |
| ns_uri = ""; |
| } |
| |
| /* Traverse thru all the attributes. If both localname and the nsuri matches return the val */ |
| for (hi = axutil_hash_first(attr_list, env); hi; hi = axutil_hash_next(env, hi)) |
| { |
| void *attr = NULL; |
| axiom_attribute_t *om_attr = NULL; |
| axutil_hash_this(hi, NULL, NULL, &attr); |
| if (attr) |
| { |
| axis2_char_t *this_attr_name = NULL; |
| axis2_char_t *this_attr_ns_uri = NULL; |
| axiom_namespace_t *attr_ns = NULL; |
| |
| om_attr = (axiom_attribute_t*)attr; |
| this_attr_name = axiom_attribute_get_localname(om_attr, env); |
| attr_ns = axiom_attribute_get_namespace(om_attr, env); |
| if(attr_ns) |
| { |
| this_attr_ns_uri = axiom_namespace_get_uri(attr_ns, env); |
| } |
| else |
| { |
| this_attr_ns_uri = ""; |
| } |
| |
| if((!axutil_strcmp(attribute_name, this_attr_name)) && |
| (!axutil_strcmp(ns_uri, this_attr_ns_uri))) |
| { |
| /* Got it !!! */ |
| found_val = axiom_attribute_get_value(om_attr, env); |
| AXIS2_FREE(env->allocator, hi); |
| break; |
| } |
| } |
| } |
| |
| for(hi = axutil_hash_first(attr_list, env); hi; hi = axutil_hash_next(env, hi)) |
| { |
| void *val = NULL; |
| axutil_hash_this(hi, NULL, NULL, &val); |
| if (val) |
| { |
| axiom_attribute_free((axiom_attribute_t *)val, env); |
| val = NULL; |
| } |
| } |
| axutil_hash_free(attr_list, env); |
| attr_list = NULL; |
| |
| return found_val; |
| } |
| |
| /** |
| * Traverse thru the node and its descendents. Check if the node has a particular attribute with |
| * qname as in @qname. Returns the attribute value. |
| * @param env Environment. MUST NOT be NULL, |
| * @param node the node to be searched |
| * @param qname the qname of the attribute |
| * @return the attribute value if found, else NULL |
| */ |
| AXIS2_EXTERN axis2_char_t* AXIS2_CALL |
| oxs_axiom_get_attribute_val_of_node_by_qname( |
| const axutil_env_t *env, |
| axiom_node_t *node, |
| axutil_qname_t *qname) |
| { |
| axis2_char_t *local_name = NULL; |
| axis2_char_t *ns_uri = NULL; |
| |
| /* Get localname of the qname */ |
| local_name = axutil_qname_get_localpart(qname, env); |
| |
| /* Get namespace uri of the qname */ |
| ns_uri = axutil_qname_get_uri(qname, env); |
| |
| return oxs_axiom_get_attribute_value_of_node_by_name(env, node, local_name, ns_uri); |
| } |
| |
| /** |
| * Check the node and its children. Check if the localname is equal to the given name |
| * Note: You may pass the prefix=NULL as the prefix may be different depending on the impl |
| * @param env Environment. MUST NOT be NULL, |
| * @param parent the node to be searched |
| * @param local_name the local name of the node to be searched |
| * @ns_uri namespace uri of the node to be searched |
| * @prefix prefix of the node to be searched. If NULL, node with any prefix will be considered |
| * @return the node if found, else NULL |
| */ |
| AXIS2_EXTERN axiom_node_t* AXIS2_CALL |
| oxs_axiom_get_first_child_node_by_name( |
| const axutil_env_t *env, |
| axiom_node_t* parent, |
| axis2_char_t* local_name, |
| axis2_char_t* ns_uri, |
| axis2_char_t* prefix) |
| { |
| axutil_qname_t *qname = NULL; |
| axiom_node_t *node = NULL; |
| axiom_element_t *parent_ele = NULL; |
| axiom_element_t *ele = NULL; |
| |
| qname = axutil_qname_create(env, local_name, ns_uri, prefix); |
| parent_ele = axiom_node_get_data_element(parent, env); |
| if (!parent_ele) |
| { |
| return NULL; |
| } |
| |
| /*Get the child*/ |
| ele = axiom_element_get_first_child_with_qname(parent_ele, env, qname, parent, &node); |
| axutil_qname_free(qname, env); |
| qname = NULL; |
| return node; |
| } |
| |
| /** |
| * Returns content of a node |
| * @param env Environment. MUST NOT be NULL, |
| * @param node the node whose content should be retrieved |
| * @return the content of the node if found, else NULL |
| */ |
| AXIS2_EXTERN axis2_char_t* AXIS2_CALL |
| oxs_axiom_get_node_content( |
| const axutil_env_t *env, |
| axiom_node_t* node) |
| { |
| axiom_element_t *ele = NULL; |
| axis2_char_t *content = NULL; |
| |
| ele = axiom_node_get_data_element(node, env); |
| if(!ele) |
| { |
| return NULL; |
| } |
| |
| content = axiom_element_get_text(ele, env, node); |
| return content; |
| } |
| |
| /** |
| * Deserialises given buffer and creates the axiom node |
| * @param env Environment. Must not be NULL |
| * @param buffer representation of serialised node |
| * @return deserialised node if success. NULL otherwise. |
| */ |
| AXIS2_EXTERN axiom_node_t *AXIS2_CALL |
| oxs_axiom_deserialize_node( |
| const axutil_env_t *env, |
| axis2_char_t* buffer) |
| { |
| axiom_document_t *doc = NULL; |
| axiom_stax_builder_t *builder = NULL; |
| axiom_xml_reader_t *reader = NULL; |
| axiom_node_t *node = NULL; |
| |
| if(!buffer) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[rampart]Deserialise method called with invalid buffer."); |
| return NULL; |
| } |
| reader = axiom_xml_reader_create_for_memory( |
| env, (void*)buffer, axutil_strlen(buffer), NULL, AXIS2_XML_PARSER_TYPE_BUFFER); |
| |
| if(!reader) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[rampart]Could not be able to create axiom_xml_reader."); |
| return NULL; |
| } |
| |
| builder = axiom_stax_builder_create(env, reader); |
| if(!builder) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[rampart]Could not be able to create axiom_stax_builder."); |
| return NULL; |
| } |
| |
| doc = axiom_document_create(env, NULL, builder); |
| if(!doc) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[rampart]Could not be able to create axiom_document."); |
| return NULL; |
| } |
| |
| node = axiom_document_build_all(doc, env); |
| if(!node) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[rampart]Could not be able to deserialize the node."); |
| axiom_document_free(doc, env); |
| return NULL; |
| } |
| |
| /* Free stax builder. The stax builder will free the reader. */ |
| axiom_stax_builder_free_self(builder, env); |
| builder = NULL; |
| |
| axiom_document_free_self(doc, env); |
| doc = NULL; |
| |
| return node; |
| } |
| |
| /** |
| * Checks whether given node is having same name and namespace as given |
| * @param env Environment. Must not be null |
| * @param node node to be checked for name and namespace |
| * @param name local name to be checked against given node |
| * @param ns namespace to be checked against given node. Can be null. If null, will be omitted |
| * @return AXIS2_TRUE if given name/ns is same as in the node. AXIS2_FALSE otherwise. |
| */ |
| AXIS2_EXTERN axis2_bool_t AXIS2_CALL |
| oxs_axiom_check_node_name( |
| const axutil_env_t *env, |
| axiom_node_t* node, |
| axis2_char_t* name, |
| axis2_char_t* ns) |
| { |
| axiom_element_t * ele = NULL; |
| axis2_char_t* namestr = NULL; |
| axis2_char_t* ns_str = NULL; |
| axutil_qname_t* qname = NULL; |
| |
| ele = axiom_node_get_data_element(node, env); |
| qname = axiom_element_get_qname(ele, env, node); |
| namestr = axutil_qname_get_localpart(qname, env); |
| |
| if(axutil_strcmp(namestr, name)) |
| { |
| return AXIS2_FALSE; |
| } |
| |
| if(ns) |
| { |
| ns_str = axutil_qname_get_uri(qname, env); |
| if(axutil_strcmp(ns_str, ns)) |
| { |
| return AXIS2_FALSE; |
| } |
| } |
| |
| return AXIS2_TRUE; |
| } |
| |
| /** |
| * moves the given node before second node. |
| * @param env Environment. Must not be null |
| * @param node_to_move node to be moved |
| * @param node_before node_to_move will be moved before this node |
| * @return status of the operation |
| */ |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| oxs_axiom_interchange_nodes( |
| const axutil_env_t *env, |
| axiom_node_t *node_to_move, |
| axiom_node_t *node_before) |
| { |
| axis2_status_t status = AXIS2_FAILURE; |
| axiom_node_t *temp_node = NULL; |
| |
| temp_node = axiom_node_detach(node_to_move,env); |
| status = axiom_node_insert_sibling_before(node_before, env, temp_node); |
| return status; |
| } |
| |
| /** |
| * Adds @child as the first child of @parent |
| * @param env Environment. Must not be null |
| * @param parent parent node |
| * @param child child node which has to be the first child of parent |
| * @return status of the operation |
| */ |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| oxs_axiom_add_as_the_first_child( |
| const axutil_env_t *env, |
| axiom_node_t *parent, |
| axiom_node_t *child) |
| { |
| axis2_status_t status = AXIS2_FAILURE; |
| axiom_node_t *first_child = NULL; |
| |
| first_child = axiom_node_get_first_child(parent, env); |
| status = axiom_node_insert_sibling_before(first_child, env, child); |
| return status; |
| } |
| |
| /**
|
| * First find the root of the scope node. Traverse thru the root node and its
|
| * children. Check if the element has the given qname and has a attribute
|
| * equal to the given values.
|
| * @param env Environment. MUST NOT be NULL,
|
| * @param node the node to be searched
|
| * @param e_name element name
|
| * @param e_ns element namespace. If NULL doesn't consider the namespaces
|
| * @param attr_name the attribute name of the node
|
| * @param attr_val the attribute value of the node
|
| * @param attr_ns the attribute namespace. If NULL doesn't consider namespaces.
|
| * @return the node if found, else NULL
|
| */ |
| AXIS2_EXTERN axiom_node_t * AXIS2_CALL |
| oxs_axiom_get_first_node_by_name_and_attr_val_from_xml_doc( |
| const axutil_env_t *env, |
| axiom_node_t *node, |
| axis2_char_t *e_name, |
| axis2_char_t *e_ns, |
| axis2_char_t *attr_name, |
| axis2_char_t *attr_val, |
| axis2_char_t *attr_ns) |
| { |
| axiom_node_t *p = NULL; |
| axiom_node_t *root = NULL; |
| |
| /* find the root node */ |
| p = node; |
| do |
| { |
| root = p; |
| p = axiom_node_get_parent(root, env); |
| } while (p); |
| |
| /* from the root node, find the node with name and attribute value */ |
| return oxs_axiom_get_first_node_by_name_and_attr_val( |
| env, root, e_name, e_ns, attr_name, attr_val, attr_ns); |
| } |
| |
| /**
|
| * Traverse thru the node and its children. Check if the element has the
|
| * given qname and has a id attribute equal to the given value.
|
| * @param env Environment. MUST NOT be NULL,
|
| * @param node the node to be searched
|
| * @param e_name element name
|
| * @param e_ns element namespace. If NULL doesn't consider the namespaces
|
| * @param attr_name the attribute name of the node
|
| * @param attr_val the attribute value of the node
|
| * @param attr_ns the attribute namespace. If NULL doesn't consider namespaces.
|
| * @return the node if found, else NULL
|
| */ |
| AXIS2_EXTERN axiom_node_t* AXIS2_CALL |
| oxs_axiom_get_first_node_by_name_and_attr_val( |
| const axutil_env_t *env, |
| axiom_node_t *node, |
| axis2_char_t *e_name, |
| axis2_char_t *e_ns, |
| axis2_char_t *attr_name, |
| axis2_char_t *attr_val, |
| axis2_char_t *attr_ns) |
| { |
| axis2_char_t *attribute_value = NULL; |
| axis2_char_t *localname = NULL; |
| axiom_namespace_t *nmsp = NULL; |
| axiom_element_t *element = NULL; |
| axis2_bool_t element_match = AXIS2_FALSE; |
| axiom_node_t *temp_node = NULL; |
| |
| if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) |
| { |
| return NULL; |
| } |
| |
| element = axiom_node_get_data_element(node, env); |
| localname = axiom_element_get_localname(element, env); |
| if(localname && !axutil_strcmp(localname, e_name)) |
| { |
| element_match = AXIS2_TRUE; |
| if(e_ns) |
| { |
| nmsp = axiom_element_get_namespace(element, env, node); |
| if(nmsp) |
| { |
| axis2_char_t *namespacea = NULL; |
| namespacea = axiom_namespace_get_uri(nmsp, env); |
| if(axutil_strcmp(e_ns, namespacea)) |
| { |
| element_match = AXIS2_FALSE; |
| } |
| } |
| } |
| |
| /* element is ok. So, we have to check the attribute value */ |
| if(element_match) |
| { |
| if(attr_ns) |
| { |
| axiom_attribute_t *attr = NULL; |
| axutil_qname_t *qname = axutil_qname_create(env, attr_name, attr_ns, NULL); |
| attr = axiom_element_get_attribute(element, env, qname); |
| if(attr) |
| { |
| attribute_value = axiom_attribute_get_value(attr, env); |
| } |
| axutil_qname_free(qname, env); |
| } |
| else |
| { |
| attribute_value = axiom_element_get_attribute_value_by_name( |
| element, env, attr_name); |
| } |
| } |
| if (attribute_value && !axutil_strcmp(attribute_value, attr_val)) |
| { |
| return node; |
| } |
| } |
| |
| /* Doesn't match? Get the children and search */ |
| temp_node = axiom_node_get_first_element(node, env); |
| while (temp_node) |
| { |
| axiom_node_t *res_node = NULL; |
| res_node = oxs_axiom_get_first_node_by_name_and_attr_val( |
| env, temp_node, e_name, e_ns, attr_name, attr_val, attr_ns); |
| if (res_node) |
| { |
| return res_node; |
| } |
| temp_node = axiom_node_get_next_sibling(temp_node, env); |
| } |
| return NULL; |
| } |
| |
| /** |
| * Clones the given node. |
| * @param env Environment. Must not be null |
| * @param node node to be cloned |
| * @return cloned node if success. NULL otherwise |
| */ |
| AXIS2_EXTERN axiom_node_t *AXIS2_CALL |
| oxs_axiom_clone_node( |
| const axutil_env_t *env, |
| axiom_node_t *node) |
| { |
| axis2_char_t* node_string = NULL; |
| axiom_node_t *clone = NULL; |
| |
| if(!node) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[rampart]Could not be able to clone the node. Given node is not valid."); |
| return NULL; |
| } |
| |
| node_string = axiom_node_sub_tree_to_string(node, env); |
| clone = oxs_axiom_deserialize_node(env, node_string); |
| |
| if(node_string) |
| { |
| AXIS2_FREE(env->allocator, node_string); |
| } |
| |
| return clone; |
| } |