diff options
Diffstat (limited to 'axiom/src/om')
-rw-r--r-- | axiom/src/om/Makefile.am | 35 | ||||
-rw-r--r-- | axiom/src/om/axiom_namespace_internal.h | 46 | ||||
-rw-r--r-- | axiom/src/om/axiom_node_internal.h | 165 | ||||
-rw-r--r-- | axiom/src/om/axiom_stax_builder_internal.h | 75 | ||||
-rw-r--r-- | axiom/src/om/om_attribute.c | 433 | ||||
-rw-r--r-- | axiom/src/om/om_child_element_iterator.c | 119 | ||||
-rw-r--r-- | axiom/src/om/om_children_iterator.c | 138 | ||||
-rw-r--r-- | axiom/src/om/om_children_qname_iterator.c | 190 | ||||
-rw-r--r-- | axiom/src/om/om_children_with_specific_attribute_iterator.c | 177 | ||||
-rw-r--r-- | axiom/src/om/om_comment.c | 142 | ||||
-rw-r--r-- | axiom/src/om/om_data_source.c | 133 | ||||
-rw-r--r-- | axiom/src/om/om_doctype.c | 131 | ||||
-rw-r--r-- | axiom/src/om/om_document.c | 263 | ||||
-rw-r--r-- | axiom/src/om/om_element.c | 1818 | ||||
-rw-r--r-- | axiom/src/om/om_namespace.c | 385 | ||||
-rw-r--r-- | axiom/src/om/om_navigator.c | 206 | ||||
-rw-r--r-- | axiom/src/om/om_node.c | 1455 | ||||
-rw-r--r-- | axiom/src/om/om_output.c | 638 | ||||
-rw-r--r-- | axiom/src/om/om_processing_instruction.c | 187 | ||||
-rw-r--r-- | axiom/src/om/om_stax_builder.c | 1072 | ||||
-rw-r--r-- | axiom/src/om/om_text.c | 637 |
21 files changed, 8445 insertions, 0 deletions
diff --git a/axiom/src/om/Makefile.am b/axiom/src/om/Makefile.am new file mode 100644 index 0000000..40db6c5 --- /dev/null +++ b/axiom/src/om/Makefile.am @@ -0,0 +1,35 @@ +lib_LTLIBRARIES = libaxis2_axiom.la +libaxis2_axiom_la_SOURCES = om_attribute.c \ + om_document.c \ + om_node.c \ + om_text.c \ + om_data_source.c \ + om_comment.c \ + om_element.c \ + om_output.c \ + om_doctype.c \ + om_namespace.c \ + om_processing_instruction.c \ + om_stax_builder.c \ + om_children_iterator.c \ + om_children_qname_iterator.c \ + om_child_element_iterator.c \ + om_children_with_specific_attribute_iterator.c \ + om_navigator.c + +libaxis2_axiom_la_LIBADD = $(top_builddir)/src/soap/libaxis2_soap.la \ + $(top_builddir)/src/attachments/libaxis2_attachments.la \ + $(top_builddir)/src/util/libaxis2_axiom_util.la \ + ../parser/${WRAPPER_DIR}/libaxis2_parser.la \ + ../../../util/src/libaxutil.la + +libaxis2_axiom_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/parser \ + -I$(top_builddir)/src/om \ + -I$(top_builddir)/src/attachments \ + -I ../../../util/include + +EXTRA_DIST = axiom_namespace_internal.h axiom_node_internal.h axiom_stax_builder_internal.h + diff --git a/axiom/src/om/axiom_namespace_internal.h b/axiom/src/om/axiom_namespace_internal.h new file mode 100644 index 0000000..833de7f --- /dev/null +++ b/axiom/src/om/axiom_namespace_internal.h @@ -0,0 +1,46 @@ + +/* + * 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_NAMESPACE_INTERNAL_H +#define AXIOM_NAMESPACE_INTERNAL_H + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_namespace.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_namespace_set_uri( + axiom_namespace_t * ns, + const axutil_env_t * env, + const axis2_char_t * ns_uri); + +#ifdef __cplusplus +} +#endif + +#endif /** AXIOM_NAMESPACE_H */ diff --git a/axiom/src/om/axiom_node_internal.h b/axiom/src/om/axiom_node_internal.h new file mode 100644 index 0000000..6e9adb4 --- /dev/null +++ b/axiom/src/om/axiom_node_internal.h @@ -0,0 +1,165 @@ + +/* + * 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_NODE_INTERNAL_H +#define AXIOM_NODE_INTERNAL_H + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_node.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_node OM Node + * @ingroup axiom + * @{ + */ + struct axiom_document; + struct axiom_stax_builder; + + /** + * Sets a parent node to a given node, if a parent already exist for this node + * then it is detached before seting the parent internal function; + * @param om_node child node to whom a parent to be added. , cannot be NULL. + * @param env Environment. MUST NOT be NULL, . + * @param parent_node the node that will be set as parent. , cannot be NULL. + * @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_parent( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * parent); + + /** + * Sets a node as first child of om_node + * @param om_node om_node + * @param env environment, MUST NOT be NULL. + * @param first_child child to be set as first child + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_first_child( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * first_child); + + /** + * Sets previous sibling + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param prev_sibling + * @return status of the op, AXIS2_SUCCESS on success + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_previous_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * prev_sibling); + + /** + * Sets next sibling + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param last_sibling + * @return status of the op, AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_next_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * next_sibling); + + /** + * Sets node type + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param type type of the node + * @return status code of the op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_node_type( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_types_t type); + + /** + * Sets data element + * @param om_node node struct + * @param env environment, MUST NOT be NULL. + * @param data_element + * @return status code of the op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_data_element( + axiom_node_t * om_node, + const axutil_env_t * env, + void *data_element); + + /** + * Sets the build status , if the node if completety build, this attribute is + * set to AXIS2_TRUE , otherwise AXIS2_FALSE + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param done + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_complete( + axiom_node_t * om_node, + const axutil_env_t * env, + axis2_bool_t done); + + /** + * This functions is only to be used by builder + * do not use this function + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_document( + axiom_node_t * om_node, + const axutil_env_t * env, + struct axiom_document *om_doc); + + /** + * Sets the builder + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_builder( + axiom_node_t * om_node, + const axutil_env_t * env, + struct axiom_stax_builder *builder); + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** AXIOM_NODE_INTERNAL_H */ diff --git a/axiom/src/om/axiom_stax_builder_internal.h b/axiom/src/om/axiom_stax_builder_internal.h new file mode 100644 index 0000000..788ecf6 --- /dev/null +++ b/axiom/src/om/axiom_stax_builder_internal.h @@ -0,0 +1,75 @@ + +/* + * 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_STAX_BUILDER_INTERNAL_H +#define AXIOM_STAX_BUILDER_INTERNAL_H + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_stax_builder.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_stax builder + * @ingroup axiom + * @{ + */ + + AXIS2_EXTERN int AXIS2_CALL + axiom_stax_builder_get_current_event( + axiom_stax_builder_t * builder, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_stax_builder_set_lastnode( + axiom_stax_builder_t * builder, + const axutil_env_t * env, + axiom_node_t * om_node); + + AXIS2_EXTERN axiom_node_t *AXIS2_CALL + axiom_stax_builder_get_lastnode( + axiom_stax_builder_t * builder, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_stax_builder_set_element_level( + axiom_stax_builder_t * builder, + const axutil_env_t * env, + int element_level); + + AXIS2_EXTERN int AXIS2_CALL + axiom_stax_builder_get_element_level( + axiom_stax_builder_t * builder, + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** AXIOM_STAX_BUILDER_INTERNAL_H */ diff --git a/axiom/src/om/om_attribute.c b/axiom/src/om/om_attribute.c new file mode 100644 index 0000000..9d2a81e --- /dev/null +++ b/axiom/src/om/om_attribute.c @@ -0,0 +1,433 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_attribute.h> +#include <string.h> +#include <axutil_utils_defines.h> + +struct axiom_attribute +{ + + /** localname of this attribute */ + axutil_string_t *localname; + + /** value of this attribute */ + axutil_string_t *value; + + /** attribute namespace */ + axiom_namespace_t *ns; + + /** store qname here */ + axutil_qname_t *qname; + int ref; +}; + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_attribute_create( + const axutil_env_t * env, + const axis2_char_t * localname, + const axis2_char_t * value, + axiom_namespace_t * ns) +{ + axiom_attribute_t *attribute = NULL; + + AXIS2_ENV_CHECK(env, NULL); + /* localname is mandatory */ + AXIS2_PARAM_CHECK(env->error, localname, NULL); + + attribute = (axiom_attribute_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_attribute_t)); + if(!attribute) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /** initialize fields */ + attribute->localname = NULL; + attribute->value = NULL; + attribute->ns = NULL; + attribute->qname = NULL; + + attribute->localname = axutil_string_create(env, localname); + if(!(attribute->localname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + if(value) + { + attribute->value = axutil_string_create(env, value); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axutil_string_free(attribute->localname, env); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + } + attribute->ns = ns; + + attribute->ref = 0; + + return attribute; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_attribute_free( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + if(--attribute->ref > 0) + { + return; + } + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(attribute->localname) + { + axutil_string_free(attribute->localname, env); + } + if(attribute->value) + { + axutil_string_free(attribute->value, env); + } + if(attribute->qname) + { + axutil_qname_free(attribute->qname, env); + } + + AXIS2_FREE(env->allocator, attribute); + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_attribute_free_void_arg( + void *attribute, + const axutil_env_t * env) +{ + axiom_attribute_t *om_attribute_l = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_attribute_l = (axiom_attribute_t *)attribute; + axiom_attribute_free(om_attribute_l, env); + return; +} + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axiom_attribute_get_qname( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + axutil_qname_t *qname = NULL; + AXIS2_ENV_CHECK(env, NULL); + if(!(attribute->qname)) + { + if(attribute->ns) + { + qname = axutil_qname_create(env, axutil_string_get_buffer(attribute-> localname, env), + axiom_namespace_get_uri(attribute->ns, env), axiom_namespace_get_prefix( + attribute-> ns, env)); + } + else + { + qname = axutil_qname_create(env, axutil_string_get_buffer(attribute-> localname, env), + NULL, NULL); + } + attribute->qname = qname; + return qname; + } + return attribute->qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_serialize( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(attribute->ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(attribute->ns, env); + prefix = axiom_namespace_get_prefix(attribute->ns, env); + + if((uri) && (NULL != prefix) && (axutil_strcmp(prefix, "") != 0)) + { + status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 4, + axutil_string_get_buffer(attribute-> localname, env), axutil_string_get_buffer( + attribute-> value, env), uri, prefix); + } + else if(uri) + { + status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 3, + axutil_string_get_buffer(attribute-> localname, env), axutil_string_get_buffer( + attribute-> value, env), uri); + } + } + else + { + status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 2, axutil_string_get_buffer( + attribute-> localname, env), axutil_string_get_buffer(attribute->value, env)); + } + return status; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +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_EXTERN axis2_char_t *AXIS2_CALL +axiom_attribute_get_value( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + if(attribute->value) + { + return (axis2_char_t *)axutil_string_get_buffer(attribute->value, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_attribute_get_namespace( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return attribute->ns; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_localname( + axiom_attribute_t * attribute, + 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(attribute->localname) + { + axutil_string_free(attribute->localname, env); + attribute->localname = NULL; + } + + attribute->localname = axutil_string_create(env, localname); + + if(!(attribute->localname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_value( + axiom_attribute_t * attribute, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + if(attribute->value) + { + axutil_string_free(attribute->value, env); + attribute->value = NULL; + } + + attribute->value = axutil_string_create(env, value); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_namespace( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axiom_namespace_t * om_namespace) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_FUNC_PARAM_CHECK(om_namespace, env, AXIS2_FAILURE); + attribute->ns = om_namespace; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_attribute_clone( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + axiom_attribute_t *cloned_attr = NULL; + if(!attribute) + return NULL; + AXIS2_ENV_CHECK(env, NULL); + + /** namespace is not cloned since it is a shollow copy*/ + cloned_attr = axiom_attribute_create_str(env, attribute->localname, attribute->value, + attribute->ns); + if(cloned_attr) + { + return cloned_attr; + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_increment_ref( + struct axiom_attribute * om_attribute, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_attribute->ref++; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_attribute_create_str( + const axutil_env_t * env, + axutil_string_t * localname, + axutil_string_t * value, + axiom_namespace_t * ns) +{ + axiom_attribute_t *attribute = NULL; + + AXIS2_ENV_CHECK(env, NULL); + /* localname is mandatory */ + AXIS2_PARAM_CHECK(env->error, localname, NULL); + + attribute = (axiom_attribute_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_attribute_t)); + if(!attribute) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /** initialize fields */ + attribute->localname = NULL; + attribute->value = NULL; + attribute->ns = NULL; + attribute->qname = NULL; + + attribute->localname = axutil_string_clone(localname, env); + if(!(attribute->localname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + if(value) + { + attribute->value = axutil_string_clone(value, env); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axutil_string_free(attribute->localname, env); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + } + attribute->ns = ns; + + attribute->ref = 0; + + return attribute; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_attribute_get_localname_str( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + return attribute->localname; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_attribute_get_value_str( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + return attribute->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_localname_str( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axutil_string_t * localname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + + if(attribute->localname) + { + axutil_string_free(attribute->localname, env); + attribute->localname = NULL; + } + + attribute->localname = axutil_string_clone(localname, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_value_str( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axutil_string_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + if(attribute->value) + { + axutil_string_free(attribute->value, env); + attribute->value = NULL; + } + + attribute->value = axutil_string_clone(value, env); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} diff --git a/axiom/src/om/om_child_element_iterator.c b/axiom/src/om/om_child_element_iterator.c new file mode 100644 index 0000000..622cfbd --- /dev/null +++ b/axiom/src/om/om_child_element_iterator.c @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_child_element_iterator.h> + +struct axiom_child_element_iterator +{ + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; +}; + +AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL +axiom_child_element_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child) +{ + axiom_child_element_iterator_t *iterator = NULL; + AXIS2_ENV_CHECK(env, NULL); + + iterator = (axiom_child_element_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_child_element_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = current_child; + iterator->last_child = NULL; + + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL axiom_child_element_iterator_free( + void *iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_child_element_iterator_remove( + axiom_child_element_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + return AXIS2_FAILURE; + if(iterator->remove_called) + return AXIS2_FAILURE; + + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + return AXIS2_FAILURE; + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_child_element_iterator_has_next( + axiom_child_element_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + return (iterator->current_child) ? AXIS2_TRUE : AXIS2_FALSE; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_child_element_iterator_next( + axiom_child_element_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + if (iterator->current_child) + { + iterator->last_child = iterator->current_child; + do + { + iterator->current_child = + axiom_node_get_next_sibling(iterator->current_child, env); + + } + while (iterator->current_child && + (axiom_node_get_node_type(iterator->current_child, env) + != AXIOM_ELEMENT)); + + return iterator->last_child; + } + return NULL; +} diff --git a/axiom/src/om/om_children_iterator.c b/axiom/src/om/om_children_iterator.c new file mode 100644 index 0000000..42046e5 --- /dev/null +++ b/axiom/src/om/om_children_iterator.c @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_children_iterator.h> + +struct axiom_children_iterator +{ + axiom_node_t *first_child; + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; +}; + +AXIS2_EXTERN axiom_children_iterator_t *AXIS2_CALL +axiom_children_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child) +{ + axiom_children_iterator_t *iterator = NULL; + AXIS2_ENV_CHECK(env, NULL); + + iterator = (axiom_children_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_children_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = NULL; + iterator->last_child = NULL; + iterator->first_child = NULL; + + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + + iterator->first_child = current_child; + iterator->current_child = current_child; + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_children_iterator_free( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_iterator_remove( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(iterator->remove_called) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + { + return AXIS2_FAILURE; + } + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_children_iterator_has_next( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + return (iterator->current_child) ? AXIS2_TRUE : AXIS2_FALSE; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_children_iterator_next( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + if(iterator->current_child) + { + iterator->last_child = iterator->current_child; + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + return iterator->last_child; + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_iterator_reset( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + iterator->current_child = iterator->first_child; + return AXIS2_SUCCESS; +} diff --git a/axiom/src/om/om_children_qname_iterator.c b/axiom/src/om/om_children_qname_iterator.c new file mode 100644 index 0000000..d508a9e --- /dev/null +++ b/axiom/src/om/om_children_qname_iterator.c @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_children_qname_iterator.h> +#include <axiom_element.h> + +struct axiom_children_qname_iterator +{ + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; + axutil_qname_t *given_qname; + axis2_bool_t need_to_move_forward; + axis2_bool_t matching_node_found; + +}; + +AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL +axiom_children_qname_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child, + axutil_qname_t * given_qname) +{ + axiom_children_qname_iterator_t *iterator = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, current_child, NULL); + + iterator = (axiom_children_qname_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_children_qname_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = NULL; + iterator->last_child = NULL; + iterator->need_to_move_forward = AXIS2_TRUE; + iterator->matching_node_found = AXIS2_FALSE; + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + iterator->given_qname = NULL; + + iterator->current_child = current_child; + if(given_qname) + { + iterator->given_qname = axutil_qname_clone(given_qname, env); + if(!(iterator->given_qname)) + { + axiom_children_qname_iterator_free(iterator, env); + return NULL; + } + } + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_children_qname_iterator_free( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(iterator->given_qname) + { + axutil_qname_free(iterator->given_qname, env); + } + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_qname_iterator_remove( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(iterator->remove_called) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + return AXIS2_FAILURE; + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_children_qname_iterator_has_next( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + while(iterator->need_to_move_forward) + { + if(iterator->current_child) + { + axiom_element_t *om_element = NULL; + axutil_qname_t *element_qname = NULL; + + if(axiom_node_get_node_type(iterator->current_child, env) == AXIOM_ELEMENT) + { + om_element = (axiom_element_t *)axiom_node_get_data_element( + iterator-> current_child, env); + } + + if(om_element) + { + element_qname = axiom_element_get_qname(om_element, env, iterator->current_child); + } + + if(om_element && axutil_qname_equals(element_qname, env, iterator->given_qname)) + { + iterator->matching_node_found = AXIS2_TRUE; + iterator->need_to_move_forward = AXIS2_FALSE; + } + else + { + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + if(iterator->current_child) + { + iterator->need_to_move_forward = AXIS2_TRUE; + iterator->matching_node_found = AXIS2_TRUE; + } + else + { + iterator->need_to_move_forward = AXIS2_FALSE; + iterator->matching_node_found = AXIS2_FALSE; + } + } + } + else + { + iterator->need_to_move_forward = AXIS2_FALSE; + } + } + return iterator->matching_node_found; + +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_children_qname_iterator_next( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + iterator->need_to_move_forward = AXIS2_TRUE; + iterator->matching_node_found = AXIS2_FALSE; + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + + iterator->last_child = iterator->current_child; + if(iterator->current_child) + { + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + } + return iterator->last_child; +} + diff --git a/axiom/src/om/om_children_with_specific_attribute_iterator.c b/axiom/src/om/om_children_with_specific_attribute_iterator.c new file mode 100644 index 0000000..8f2e463 --- /dev/null +++ b/axiom/src/om/om_children_with_specific_attribute_iterator.c @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_children_with_specific_attribute_iterator.h> +#include <axiom_attribute.h> +#include <axiom_element.h> + +struct axiom_children_with_specific_attribute_iterator +{ + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; + axutil_qname_t *attr_qname; + axis2_char_t *attr_value; + axis2_bool_t detach; +}; + +AXIS2_EXTERN axiom_children_with_specific_attribute_iterator_t *AXIS2_CALL +axiom_children_with_specific_attribute_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child, + axutil_qname_t * attr_qname, + axis2_char_t * attr_value, + axis2_bool_t detach) +{ + axiom_children_with_specific_attribute_iterator_t *iterator = NULL; + + AXIS2_PARAM_CHECK(env->error, current_child, NULL); + AXIS2_PARAM_CHECK(env->error, attr_qname, NULL); + AXIS2_PARAM_CHECK(env->error, attr_value, NULL); + iterator = (axiom_children_with_specific_attribute_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_children_with_specific_attribute_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = NULL; + iterator->last_child = NULL; + + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + + iterator->attr_qname = axutil_qname_clone(attr_qname, env); + iterator->attr_value = attr_value; + iterator->detach = detach; + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_children_with_specific_attribute_iterator_free( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + if(iterator->attr_qname) + { + axutil_qname_free(iterator->attr_qname, env); + } + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_with_specific_attribute_iterator_remove( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(iterator->remove_called) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + return AXIS2_FAILURE; + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_children_with_specific_attribute_iterator_has_next( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + axis2_bool_t matching_node_found = AXIS2_FALSE; + axis2_bool_t need_to_move_forward = AXIS2_TRUE; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(iterator->current_child)) + { + return AXIS2_FALSE; + } + while(need_to_move_forward) + { + if(axiom_node_get_node_type(iterator->current_child, env) == AXIOM_ELEMENT) + { + axiom_attribute_t *om_attr = NULL; + axiom_element_t *om_ele = NULL; + om_ele = (axiom_element_t *)axiom_node_get_data_element(iterator-> current_child, env); + om_attr = axiom_element_get_attribute(om_ele, env, iterator->attr_qname); + break; + /*if (om_attr && + (axutil_strcmp(axiom_attribute_get_value(om_attr, env), + iterator->attr_value) == 0)) + { + matching_node_found = AXIS2_TRUE; + need_to_move_forward = AXIS2_FALSE; + } + else + { + iterator->current_child = + axiom_node_get_next_sibling(iterator->current_child, env); + need_to_move_forward = (iterator->current_child != NULL); + + }*/ + } + else + { + + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + need_to_move_forward = (iterator->current_child != NULL); + } + + } + return matching_node_found; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_children_with_specific_attribute_iterator_next( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, iterator, NULL); + + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + iterator->last_child = iterator->current_child; + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + if(iterator->last_child && iterator->detach + && (axiom_node_get_parent(iterator->last_child, env))) + { + axiom_node_free_tree(iterator->last_child, env); + } + return iterator->last_child; +} diff --git a/axiom/src/om/om_comment.c b/axiom/src/om/om_comment.c new file mode 100644 index 0000000..ad17f74 --- /dev/null +++ b/axiom/src/om/om_comment.c @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_comment.h> +#include "axiom_node_internal.h" +#include <axutil_string.h> + +struct axiom_comment +{ + + /** comment text */ + axis2_char_t *value; +}; + +AXIS2_EXTERN axiom_comment_t *AXIS2_CALL +axiom_comment_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_comment_t *comment = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, value, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + *node = NULL; + *node = axiom_node_create(env); + if(!*node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + comment = (axiom_comment_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_comment_t)); + if(!comment) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + comment->value = NULL; + + if(value) + { + comment->value = (axis2_char_t *)axutil_strdup(env, value); + if(!comment->value) + { + AXIS2_FREE(env->allocator, comment); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + axiom_node_set_data_element((*node), env, comment); + axiom_node_set_node_type((*node), env, AXIOM_COMMENT); + + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + + return comment; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_comment_free( + axiom_comment_t * comment, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(comment->value) + { + AXIS2_FREE(env->allocator, comment->value); + } + AXIS2_FREE(env->allocator, comment); + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_comment_get_value( + axiom_comment_t * comment, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return comment->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_comment_set_value( + axiom_comment_t * comment, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + if(comment->value) + { + AXIS2_FREE(env->allocator, comment->value); + } + + comment->value = (axis2_char_t *)axutil_strdup(env, value); + + if(!comment->value) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_comment_serialize( + axiom_comment_t * comment, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(comment->value) + { + return axiom_output_write(om_output, env, AXIOM_COMMENT, 1, comment->value); + } + return AXIS2_FAILURE; +} diff --git a/axiom/src/om/om_data_source.c b/axiom/src/om/om_data_source.c new file mode 100644 index 0000000..3959e49 --- /dev/null +++ b/axiom/src/om/om_data_source.c @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_data_source.h> +#include <axiom_output.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" +#include <axiom_xml_writer.h> +#include <axiom_output.h> +#include <axiom_attribute.h> +#include <axiom_namespace.h> +#include <axutil_base64.h> + +/********************* axiom_data_source_struct ***************/ + +struct axiom_data_source +{ + + /** stream holding serialized XML string */ + axutil_stream_t *stream; +}; + +AXIS2_EXTERN axiom_data_source_t *AXIS2_CALL +axiom_data_source_create( + const axutil_env_t * env, + axiom_node_t * parent, + axiom_node_t ** node) +{ + + axiom_data_source_t *data_source = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + data_source = (axiom_data_source_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_data_source_t)); + if(!data_source) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + axiom_node_set_data_element((*node), env, data_source); + axiom_node_set_node_type((*node), env, AXIOM_DATA_SOURCE); + axiom_node_set_complete((*node), env, AXIS2_FALSE); + + data_source->stream = NULL; + + data_source->stream = axutil_stream_create_basic(env); + if(!(data_source->stream)) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_FREE(env->allocator, data_source); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_node_add_child(parent, env, (*node)); + } + + return data_source; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_data_source_free( + axiom_data_source_t * data_source, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(data_source->stream) + { + axutil_stream_free(data_source->stream, env); + } + + AXIS2_FREE(env->allocator, data_source); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_source_serialize( + axiom_data_source_t * data_source, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + axis2_char_t *data = NULL; + unsigned int data_len = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + data = axutil_stream_get_buffer(data_source->stream, env); + data_len = axutil_stream_get_len(data_source->stream, env); + if(data) + { + data[data_len] = '\0'; + status = axiom_output_write(om_output, env, AXIOM_DATA_SOURCE, 1, data); + } + return status; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axiom_data_source_get_stream( + axiom_data_source_t * data_source, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return data_source->stream; +} diff --git a/axiom/src/om/om_doctype.c b/axiom/src/om/om_doctype.c new file mode 100644 index 0000000..fa5616b --- /dev/null +++ b/axiom/src/om/om_doctype.c @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_doctype.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" + +struct axiom_doctype +{ + + /** Doctype value */ + axis2_char_t *value; +}; + +AXIS2_EXTERN axiom_doctype_t *AXIS2_CALL +axiom_doctype_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_doctype_t *doctype = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + if(!*node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + doctype = (axiom_doctype_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_doctype_t)); + + if(!doctype) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + doctype->value = NULL; + + if(value) + { + doctype->value = (axis2_char_t *)axutil_strdup(env, value); + if(!doctype->value) + { + AXIS2_FREE(env->allocator, doctype); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + axiom_node_set_data_element((*node), env, doctype); + axiom_node_set_node_type((*node), env, AXIOM_DOCTYPE); + + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + + return doctype; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_doctype_free( + axiom_doctype_t * om_doctype, + const axutil_env_t * env) +{ + if(om_doctype) + { + if(om_doctype->value) + { + AXIS2_FREE(env->allocator, om_doctype->value); + } + AXIS2_FREE(env->allocator, om_doctype); + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_doctype_set_value( + axiom_doctype_t * om_doctype, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + om_doctype->value = (axis2_char_t *)axutil_strdup(env, value); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_doctype_get_value( + axiom_doctype_t * om_doctype, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return om_doctype->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_doctype_serialize( + axiom_doctype_t * om_doctype, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_doctype->value) + return axiom_output_write(om_output, env, AXIOM_DOCTYPE, 1, om_doctype->value); + + return AXIS2_FAILURE; +} diff --git a/axiom/src/om/om_document.c b/axiom/src/om/om_document.c new file mode 100644 index 0000000..149edec --- /dev/null +++ b/axiom/src/om/om_document.c @@ -0,0 +1,263 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_document.h> +#include <axiom_stax_builder.h> +#include <axutil_string.h> + +struct axiom_document +{ + + /** root element */ + axiom_node_t *root_element; + + /** last child */ + axiom_node_t *last_child; + + /** first child */ + axiom_node_t *first_child; + + /** done building the document */ + axis2_bool_t done; + + /** builder of the document */ + struct axiom_stax_builder *builder; + + /** char set encoding */ + axis2_char_t *char_set_encoding; + + /** XML version */ + axis2_char_t *xml_version; +}; + +AXIS2_EXTERN axiom_document_t *AXIS2_CALL +axiom_document_create( + const axutil_env_t * env, + axiom_node_t * root, + axiom_stax_builder_t * builder) +{ + axiom_document_t *document = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + document = (axiom_document_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_document_t)); + + if(!document) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + document->builder = builder; + document->root_element = root; + document->first_child = root; + document->last_child = root; + document->xml_version = XML_VERSION; + document->char_set_encoding = CHAR_SET_ENCODING; + document->done = AXIS2_FALSE; + + return document; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_document_free( + axiom_document_t * document, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(document->root_element) + { + axiom_node_free_tree(document->root_element, env); + } + AXIS2_FREE(env->allocator, document); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_document_free_self( + axiom_document_t * document, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, document); + return; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_document_build_next( + axiom_document_t * document, + const axutil_env_t * env) +{ + axiom_node_t *last_child = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!document->builder) + { + return NULL; + } + + if(!(document->root_element)) + { + last_child = axiom_stax_builder_next(document->builder, env); + if(last_child) + { + document->last_child = last_child; + document->root_element = last_child; + } + return last_child; + } + else if((document->root_element) && (axiom_node_is_complete(document->root_element, env) + == AXIS2_TRUE)) + return NULL; /* Nothing wrong but done with pulling */ + + last_child = axiom_stax_builder_next(document->builder, env); + if(last_child) + { + document->last_child = last_child; + } + return last_child; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_document_get_root_element( + axiom_document_t * document, + const axutil_env_t * env) +{ + axiom_node_t *node = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(document->root_element) + { + return document->root_element; + } + node = axiom_document_build_next(document, env); + + if(document->root_element) + { + return document->root_element; + } + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_DOCUMENT_STATE_ROOT_NULL, AXIS2_FAILURE); + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_document_set_root_element( + axiom_document_t * document, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(document->root_element) + { + axiom_node_free_tree(document->root_element, env); + document->root_element = node; + return AXIS2_SUCCESS; + } + else + { + document->root_element = node; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_document_build_all( + struct axiom_document * document, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + if(!document) + { + return NULL; + } + if(!document->root_element) + { + axiom_document_get_root_element(document, env); + } + if(document->root_element) + { + do + { + axiom_node_t *ret_val = NULL; + ret_val = axiom_document_build_next(document, env); + if(!ret_val) + { + if(axiom_node_is_complete(document->root_element, env) == AXIS2_TRUE) + { + + /** document is completly build */ + return document->root_element; + } + else + { + + /** error occurred */ + return NULL; + } + } + } + while(!axiom_node_is_complete(document->root_element, env)); + return document->root_element; + } + else + return NULL; +} + +AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL +axiom_document_get_builder( + axiom_document_t * document, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return document->builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_document_set_builder( + axiom_document_t * document, + const axutil_env_t * env, + axiom_stax_builder_t * builder) +{ + document->builder = builder; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_document_serialize( + axiom_document_t * document, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + if(!document) + return AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!(document->root_element)) + { + axiom_document_get_root_element(document, env); + } + if(document->root_element) + { + return axiom_node_serialize(document->root_element, env, om_output); + } + else + { + return AXIS2_FAILURE; + } +} diff --git a/axiom/src/om/om_element.c b/axiom/src/om/om_element.c new file mode 100644 index 0000000..84982cd --- /dev/null +++ b/axiom/src/om/om_element.c @@ -0,0 +1,1818 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_element.h> +#include "axiom_node_internal.h" +#include <axiom_attribute.h> +#include <axiom_namespace.h> +#include <axiom_xml_writer.h> +#include <axiom_stax_builder.h> +#include <string.h> +#include <stdio.h> + +struct axiom_element +{ + + /** Element's namespace */ + axiom_namespace_t *ns; + + /** Element's local name */ + axutil_string_t *localname; + + /** List of attributes */ + axutil_hash_t *attributes; + + /** List of namespaces */ + axutil_hash_t *namespaces; + + axutil_qname_t *qname; + + axiom_child_element_iterator_t *child_ele_iter; + + axiom_children_iterator_t *children_iter; + + axiom_children_qname_iterator_t *children_qname_iter; + + axis2_char_t *text_value; + + int next_ns_prefix_number; + + axis2_bool_t is_empty; + +}; + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * localname, + axiom_namespace_t * ns, + axiom_node_t ** node) +{ + axiom_element_t *element; + AXIS2_ENV_CHECK(env, NULL); + + if(!localname || !node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localname or node is NULL"); + return NULL; + } + + (*node) = axiom_node_create(env); + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Memory"); + return NULL; + } + element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t)); + + if(!element) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Memory"); + return NULL; + } + element->ns = NULL; + element->localname = NULL; + element->attributes = NULL; + element->namespaces = NULL; + element->qname = NULL; + element->child_ele_iter = NULL; + element->children_iter = NULL; + element->children_qname_iter = NULL; + element->text_value = NULL; + element->next_ns_prefix_number = 0; + element->is_empty = AXIS2_FALSE; + + 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); + return NULL; + } + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + axiom_node_set_complete((*node), env, AXIS2_FALSE); + axiom_node_set_node_type((*node), env, AXIOM_ELEMENT); + axiom_node_set_data_element((*node), env, element); + + if(ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + /* + if (prefix && axutil_strcmp(prefix, "") == 0) + { + element->ns = NULL; + return element; + } + */ + 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; + } + } + + if(!(element->ns)) + { + if(axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS) + { + element->ns = ns; + } + } + + /*if (prefix && axutil_strcmp(prefix, "") == 0) + { + element->ns = NULL; + } + */ + } + + return element; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_create_with_qname( + const axutil_env_t * env, + axiom_node_t * parent, + const axutil_qname_t * qname, + axiom_node_t ** node) +{ + axiom_element_t *element = NULL; + axis2_char_t *localpart = 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; + } + element = axiom_element_create(env, parent, localpart, NULL, node); + if(!element) + { + return NULL; + } + + if(*node) + { + axiom_element_t *om_element = NULL; + axis2_char_t *temp_nsuri = NULL; + axis2_char_t *temp_prefix = NULL; + axiom_namespace_t *ns = NULL; + + 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) + { + return NULL; + } + + if((!temp_nsuri) || (axutil_strcmp(temp_nsuri, "") == 0)) + { + + /** no namespace uri is available in given qname + no need to bother about it + */ + return om_element; + } + + 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; + } + } + } + return element; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_find_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axiom_node_t *parent = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!element_node || !om_element) + { + 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; + } + if(!axiom_node_get_data_element(element_node, env) || axiom_node_get_node_type(element_node, + env) != AXIOM_ELEMENT) + { + /* 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; + } + + if(om_element->namespaces) + { + void *ns = NULL; + + if(uri && (!prefix || axutil_strcmp(prefix, "") == 0)) + { + + /** 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(axutil_strcmp(uri, default_uri) == 0) + { + return default_ns; + } + } + + /** 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_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); + + if(axutil_strcmp(temp_nsuri, uri) == 0) + { + /** namespace uri matches, so free hashindex and return ns*/ + AXIS2_FREE(env->allocator, hashindex); + return (axiom_namespace_t *)(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); + 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 */ + return (axutil_strcmp(found_uri, uri) == 0) ? found_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 NULL; +} + +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; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!ns || !om_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "namespace or om_element is NULL"); + return AXIS2_FAILURE; + } + + 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 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); + om_element->next_ns_prefix_number++; + 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_declare_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * node, + axiom_namespace_t * ns) +{ + axiom_namespace_t *declared_ns = NULL; + axis2_char_t *prefix = NULL; + axis2_char_t *uri = NULL; + + 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; + } + + 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; + } + } + + if(!(om_element->namespaces)) + { + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) + { + 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); + om_element->next_ns_prefix_number++; + 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( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axutil_hash_index_t *hash_index = NULL; + void *ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!(om_element->namespaces)) + { + return NULL; + } + if(uri && (!prefix || axutil_strcmp(prefix, "") == 0)) + { + /** 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)) + { + 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; + } + } + ns = NULL; + return NULL; + } + else if(prefix) + { + 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; + } + } + return NULL; +} + +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_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; + } + + if(axutil_qname_get_uri(qname, env)) + { + return axiom_element_find_namespace(element, env, node, axutil_qname_get_uri(qname, env), + axutil_qname_get_prefix(qname, env)); + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_add_attribute( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_attribute_t * attribute, + axiom_node_t * element_node) +{ + + axutil_qname_t *qname = 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); + + /* 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) + { + 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; + } + } + } + + if(!(om_element->attributes)) + { + om_element->attributes = axutil_hash_make(env); + if(!(om_element->attributes)) + { + return AXIS2_FAILURE; + } + } + + qname = axiom_attribute_get_qname(attribute, env); + if(qname) + { + axis2_char_t *name = axutil_qname_to_string(qname, env); + axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, attribute); + axiom_attribute_increment_ref(attribute, env); + } + return ((qname) ? AXIS2_SUCCESS : AXIS2_FAILURE); +} + +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); + + name = axutil_qname_to_string(qname, env); + + if((om_element->attributes) && name) + { + attr = (axiom_attribute_t *)(axutil_hash_get(om_element->attributes, name, + AXIS2_HASH_KEY_STRING)); + } + return attr; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_element_free( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!om_element) + { + return; + } + + if(om_element->localname) + { + axutil_string_free(om_element->localname, env); + } + if(om_element->ns) + { + /* it is the responsibility of the element where the namespace is declared to free it */ + } + if(om_element->attributes) + { + axutil_hash_index_t *hi; + void *val = NULL; + + 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) + { + axiom_attribute_free((axiom_attribute_t *)val, env); + } + } + axutil_hash_free(om_element->attributes, env); + } + + if(om_element->namespaces) + { + axutil_hash_index_t *hi; + void *val = NULL; + for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + axiom_namespace_free((axiom_namespace_t *)val, env); + } + } + axutil_hash_free(om_element->namespaces, env); + } + if(om_element->qname) + { + axutil_qname_free(om_element->qname, env); + } + if(om_element->children_iter) + { + axiom_children_iterator_free(om_element->children_iter, env); + } + if(om_element->child_ele_iter) + { + AXIOM_CHILD_ELEMENT_ITERATOR_FREE(om_element->child_ele_iter, env); + } + if(om_element->children_qname_iter) + { + axiom_children_qname_iterator_free(om_element->children_qname_iter, env); + } + if(om_element->text_value) + { + AXIS2_FREE(env->allocator, om_element->text_value); + } + AXIS2_FREE(env->allocator, om_element); + + return; +} + +AXIS2_EXTERN 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) +{ + int status = AXIS2_SUCCESS; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_element->is_empty) + { + 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); + } + } + else + { + 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, 3, + axutil_string_get_buffer(om_element-> localname, env), uri, prefix); + } + else if(uri) + { + 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(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 + { + status = AXIS2_FAILURE; + } + } + } + + if(om_element->namespaces) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + status = axiom_namespace_serialize((axiom_namespace_t *)val, env, om_output); + } + else + { + status = AXIS2_FAILURE; + } + } + } + + return status; +} + +AXIS2_EXTERN 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) +{ + 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; +} + +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_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) + { + axutil_string_free(om_element->localname, env); + om_element->localname = NULL; + } + om_element->localname = axutil_string_create(env, localname); + if(!(om_element->localname)) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_get_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * ele_node) +{ + axiom_namespace_t *ns = 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); + + } + return ns; +} + +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) +{ + 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 + { + om_element->ns = om_ns; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_namespace_assume_param_ownership( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_namespace_t * ns) +{ + om_element->ns = ns; + return AXIS2_SUCCESS; +} + +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; +} + +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); + + if(om_element->qname) + { + return om_element->qname; + } + else + { + ns = axiom_element_get_namespace(om_element, env, ele_node); + 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); + } + } + return om_element->qname; +} + +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); + + if(!om_element->children_iter) + { + om_element->children_iter = axiom_children_iterator_create(env, axiom_node_get_first_child( + element_node, env)); + } + else + { + axiom_children_iterator_reset(om_element->children_iter, env); + } + return om_element->children_iter; +} + +AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL +axiom_element_get_children_with_qname( + axiom_element_t * om_element, + const axutil_env_t * env, + axutil_qname_t * element_qname, + axiom_node_t * element_node) +{ + AXIS2_PARAM_CHECK(env->error, element_node, 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; +} + +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, + 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); + if(!children_iterator) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Could not create 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); + + if(child_node) + { + *child_node = om_node; + } + 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; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_get_first_element( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node, + axiom_node_t ** first_ele_node) +{ + axiom_node_t *temp_node = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + temp_node = axiom_node_get_first_child(element_node, env); + while(temp_node) + { + if(axiom_node_get_node_type(temp_node, env) == AXIOM_ELEMENT) + { + if(first_ele_node) + { + *first_ele_node = temp_node; + } + return (axiom_element_t *)axiom_node_get_data_element(temp_node, env); + } + else + { + temp_node = axiom_node_get_next_sibling(temp_node, env); + } + } + return NULL; +} + +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) +{ + 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_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + if(om_element->text_value) + { + AXIS2_FREE(env->allocator, om_element->text_value); + om_element->text_value = NULL; + } + + temp_node = axiom_node_get_first_child(element_node, env); + + while(temp_node) + { + if(axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT) + { + 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); + } + } + } + temp_node = axiom_node_get_next_sibling(temp_node, env); + } + + om_element->text_value = dest; + return om_element->text_value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_text( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * text, + axiom_node_t * element_node) +{ + axiom_node_t *temp_node, *next_node; + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); + + next_node = axiom_node_get_first_child(element_node, env); + while(next_node) + { + temp_node = next_node; + next_node = axiom_node_get_next_sibling(temp_node, env); + if(axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT) + { + axiom_node_free_tree(temp_node, env); + } + } + + om_text = axiom_text_create(env, NULL, text, &temp_node); + axiom_node_add_child(element_node, env, temp_node); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_to_string( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + return axiom_node_to_string(element_node, env); +} + +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) +{ + 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) + { + return om_element->child_ele_iter; + } + else if(ele && first_node) + { + om_element->child_ele_iter = axiom_child_element_iterator_create(env, first_node); + return om_element->child_ele_iter; + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_build( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * om_ele_node) +{ + axiom_stax_builder_t *builder = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + AXIS2_PARAM_CHECK(env->error, om_ele_node, AXIS2_FAILURE); + if(axiom_node_get_node_type(om_ele_node, env) != AXIOM_ELEMENT) + { + return AXIS2_FAILURE; + } + + builder = axiom_node_get_builder(om_ele_node, env); + if(!builder) + { + return AXIS2_FAILURE; + } + while(!axiom_node_is_complete(om_ele_node, env) + && !axiom_stax_builder_is_complete(builder, env)) + { + void *value = NULL; + value = axiom_stax_builder_next(builder, env); + if(!value) + { + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_get_default_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + axiom_node_t *parent_node = NULL; + axiom_namespace_t *default_ns = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + if(om_element->namespaces) + { + default_ns = axutil_hash_get(om_element->namespaces, "", AXIS2_HASH_KEY_STRING); + if(default_ns) + { + return default_ns; + } + } + + parent_node = axiom_node_get_parent(element_node, env); + if((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT)) + { + axiom_element_t *parent_ele = NULL; + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(parent_ele) + { + return axiom_element_get_default_namespace(parent_ele, env, parent_node); + } + } + return NULL; +} + +/** + * declared a default namespace explicitly + */ +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_declare_default_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axiom_namespace_t *default_ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + + if(axutil_strcmp(uri, "") == 0) + { + return NULL; + } + + default_ns = axiom_namespace_create(env, uri, ""); + if(!default_ns) + { + return NULL; + } + if(!om_element->namespaces) + { + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) + { + axiom_namespace_free(default_ns, env); + return NULL; + } + } + + axutil_hash_set(om_element->namespaces, "", AXIS2_HASH_KEY_STRING, default_ns); + axiom_namespace_increment_ref(default_ns, env); + return default_ns; +} + +/** + * checks for the namespace in the context of this element + * with the given prefix + */ + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_find_namespace_uri( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * prefix, + axiom_node_t * element_node) +{ + axiom_node_t *parent_node = NULL; + axiom_namespace_t *ns = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + AXIS2_PARAM_CHECK(env->error, prefix, NULL); + + if(om_element->namespaces) + { + ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(ns) + { + return ns; + } + } + + parent_node = axiom_node_get_parent(element_node, env); + if((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT)) + { + axiom_element_t *parent_ele = NULL; + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(parent_ele) + { + return axiom_element_find_namespace_uri(parent_ele, env, prefix, parent_node); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_get_attribute_value( + 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); + + name = axutil_qname_to_string(qname, env); + + if((om_element->attributes) && (NULL != name)) + { + attr = (axiom_attribute_t *)axutil_hash_get(om_element->attributes, name, + AXIS2_HASH_KEY_STRING); + if(attr) + { + return axiom_attribute_get_value(attr, env); + } + } + return NULL; +} + +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 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 = 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; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + if(!om_element->attributes) + { + return NULL; + } + ht_cloned = axutil_hash_make(env); + if(!ht_cloned) + { + 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) + { + return NULL; + } + for(hi = axutil_hash_first(om_element->attributes, 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; + 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; + } + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_create_str( + const axutil_env_t * env, + axiom_node_t * parent, + axutil_string_t * localname, + axiom_namespace_t * ns, + axiom_node_t ** node) +{ + axiom_element_t *element; + AXIS2_ENV_CHECK(env, NULL); + + if(!localname || !node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localname or node is NULL"); + return NULL; + } + + (*node) = axiom_node_create(env); + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t)); + + if(!element) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + element->ns = NULL; + element->localname = NULL; + element->attributes = NULL; + element->namespaces = NULL; + element->qname = NULL; + element->child_ele_iter = NULL; + element->children_iter = NULL; + element->children_qname_iter = NULL; + element->text_value = NULL; + element->next_ns_prefix_number = 0; + element->is_empty = AXIS2_FALSE; + + element->localname = axutil_string_clone(localname, env); + if(!element->localname) + { + AXIS2_FREE(env->allocator, element); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + axiom_node_set_complete((*node), env, AXIS2_FALSE); + axiom_node_set_node_type((*node), env, AXIOM_ELEMENT); + axiom_node_set_data_element((*node), env, element); + + if(ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + element->ns = axiom_element_find_namespace(element, env, *node, uri, prefix); + if(!(element->ns)) + { + if(axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS) + { + element->ns = ns; + } + } + if(prefix && axutil_strcmp(prefix, "") == 0) + { + element->ns = NULL; + } + } + + return element; +} + +AXIS2_EXTERN 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, + const axutil_env_t * env) +{ + 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( + 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_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); + } + } + } + + /* ensure the namespaces in all the children are declared */ + child_node = axiom_node_get_first_child(om_node, env); + while(child_node && (axutil_hash_count(inscope_namespaces) > 0)) + { + if(axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT) + { + axiom_element_redeclare_parent_namespaces(axiom_node_get_data_element(child_node, env), + env, child_node, root_element, inscope_namespaces); + } + child_node = axiom_node_get_next_sibling(child_node, env); + } +} diff --git a/axiom/src/om/om_namespace.c b/axiom/src/om/om_namespace.c new file mode 100644 index 0000000..2d9df2f --- /dev/null +++ b/axiom/src/om/om_namespace.c @@ -0,0 +1,385 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_namespace.h> +#include <axutil_string.h> +#include "axiom_namespace_internal.h" + +struct axiom_namespace +{ + + /** namespace URI */ + axutil_string_t *uri; + + /** namespace prefix */ + axutil_string_t *prefix; + + axis2_char_t *key; + + int ref; +}; + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_namespace_create( + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axiom_namespace_t *om_namespace = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!uri) + { + uri = ""; + } + + om_namespace = (axiom_namespace_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_namespace_t)); + if(!om_namespace) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_namespace->ref = 0; + om_namespace->prefix = NULL; + om_namespace->uri = NULL; + om_namespace->key = NULL; + + om_namespace->uri = axutil_string_create(env, uri); + if(!om_namespace->uri) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(prefix) + { + om_namespace->prefix = axutil_string_create(env, prefix); + if(!om_namespace->prefix) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_FREE(env->allocator, om_namespace->uri); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + return om_namespace; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_namespace_free( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(--om_namespace->ref > 0) + { + return; + } + + if(om_namespace->prefix) + { + axutil_string_free(om_namespace->prefix, env); + } + + if(om_namespace->uri) + { + axutil_string_free(om_namespace->uri, env); + } + + if(om_namespace->key) + { + AXIS2_FREE(env->allocator, om_namespace->key); + } + + AXIS2_FREE(env->allocator, om_namespace); + + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_namespace_equals( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + axiom_namespace_t * om_namespace1) +{ + int uris_differ = 0; + int prefixes_differ = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_namespace, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_namespace1, AXIS2_FAILURE); + + if(!om_namespace || !om_namespace1) + { + return AXIS2_FALSE; + } + + if(om_namespace->uri && om_namespace1->uri) + { + uris_differ = axutil_strcmp(axutil_string_get_buffer(om_namespace->uri, env), + axutil_string_get_buffer(om_namespace1->uri, env)); + } + else + { + uris_differ = (om_namespace->uri || om_namespace1->uri); + } + + if(om_namespace->prefix && om_namespace1->prefix) + { + prefixes_differ = axutil_strcmp(axutil_string_get_buffer(om_namespace->prefix, env), + axutil_string_get_buffer(om_namespace1->prefix, env)); + } + else + { + prefixes_differ = (om_namespace->prefix || om_namespace1->prefix); + } + + return (!uris_differ && !prefixes_differ); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_serialize( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + if(!om_namespace) + { + return AXIS2_FAILURE; + } + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_namespace->uri && NULL != om_namespace->prefix && axutil_strcmp(axutil_string_get_buffer( + om_namespace->prefix, env), "") != 0) + { + status = axiom_output_write(om_output, env, AXIOM_NAMESPACE, 2, axutil_string_get_buffer( + om_namespace-> prefix, env), axutil_string_get_buffer(om_namespace->uri, env)); + } + else if(om_namespace->uri) + { + status = axiom_output_write(om_output, env, AXIOM_NAMESPACE, 2, NULL, + axutil_string_get_buffer(om_namespace->uri, env)); + } + return status; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_namespace_get_uri( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + if(om_namespace->uri) + { + return (axis2_char_t *)axutil_string_get_buffer(om_namespace->uri, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_namespace_get_prefix( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + if(om_namespace->prefix) + { + return (axis2_char_t *)axutil_string_get_buffer(om_namespace->prefix, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_namespace_clone( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + axiom_namespace_t *cloned_ns = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + cloned_ns = axiom_namespace_create_str(env, om_namespace->uri, om_namespace->prefix); + if(cloned_ns) + { + return cloned_ns; + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_namespace_to_string( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + axis2_char_t *temp_str = NULL; + AXIS2_ENV_CHECK(env, NULL); + if(om_namespace->key) + { + AXIS2_FREE(env->allocator, om_namespace->key); + om_namespace->key = NULL; + } + if((om_namespace->uri) && (NULL != om_namespace->prefix)) + { + temp_str = axutil_stracat(env, axutil_string_get_buffer(om_namespace->uri, env), "|"); + om_namespace->key = axutil_stracat(env, temp_str, axutil_string_get_buffer( + om_namespace->prefix, env)); + if(temp_str) + { + AXIS2_FREE(env->allocator, temp_str); + temp_str = NULL; + } + } + else if((om_namespace->uri) && !(om_namespace->prefix)) + { + om_namespace->key = axutil_strdup(env, axutil_string_get_buffer(om_namespace->uri, env)); + if(!(om_namespace->key)) + { + return NULL; + } + } + return om_namespace->key; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_set_uri( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + const axis2_char_t * uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + + if(om_namespace->uri) + { + axutil_string_free(om_namespace->uri, env); + om_namespace->uri = NULL; + } + + om_namespace->uri = axutil_string_create(env, uri); + if(!(om_namespace->uri)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_increment_ref( + struct axiom_namespace * om_namespace, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_namespace->ref++; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_namespace_create_str( + const axutil_env_t * env, + axutil_string_t * uri, + axutil_string_t * prefix) +{ + axiom_namespace_t *om_namespace = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!uri) + { + uri = axutil_string_create(env, ""); + } + + om_namespace = (axiom_namespace_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_namespace_t)); + if(!om_namespace) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_namespace->ref = 0; + om_namespace->prefix = NULL; + om_namespace->uri = NULL; + om_namespace->key = NULL; + + om_namespace->uri = axutil_string_clone(uri, env); + if(!om_namespace->uri) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(prefix) + { + om_namespace->prefix = axutil_string_clone(prefix, env); + if(!om_namespace->prefix) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_FREE(env->allocator, om_namespace->uri); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + return om_namespace; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_set_uri_str( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + axutil_string_t * uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + + if(om_namespace->uri) + { + axutil_string_free(om_namespace->uri, env); + om_namespace->uri = NULL; + } + + om_namespace->uri = axutil_string_clone(uri, env); + if(!(om_namespace->uri)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_namespace_get_uri_str( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + return om_namespace->uri; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_namespace_get_prefix_str( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + return om_namespace->prefix; +} diff --git a/axiom/src/om/om_navigator.c b/axiom/src/om/om_navigator.c new file mode 100644 index 0000000..c0405b8 --- /dev/null +++ b/axiom/src/om/om_navigator.c @@ -0,0 +1,206 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_navigator.h> + +static void +axiom_navigator_update_next_node( + axiom_navigator_t * om_navigator, + const axutil_env_t * env); + +struct axiom_navigator +{ + axiom_node_t *node; + + axis2_bool_t visited; + + axiom_node_t *next; + + axiom_node_t *root; + + axis2_bool_t backtracked; + + axis2_bool_t end; + + axis2_bool_t start; + +}; + +AXIS2_EXTERN axiom_navigator_t *AXIS2_CALL +axiom_navigator_create( + const axutil_env_t * env, + axiom_node_t * om_node) +{ + axiom_navigator_t *om_navigator = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + om_navigator = (axiom_navigator_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_navigator_t)); + if(!om_navigator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_navigator->node = NULL; + om_navigator->visited = AXIS2_FALSE; + om_navigator->next = NULL; + om_navigator->root = NULL; + om_navigator->end = AXIS2_FALSE; + om_navigator->start = AXIS2_TRUE; + om_navigator->backtracked = AXIS2_FALSE; + + om_navigator->next = om_node; + om_navigator->root = om_node; + + return om_navigator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_navigator_free( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, om_navigator); + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_navigator_is_navigable( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + if(AXIS2_TRUE == om_navigator->end) + { + return AXIS2_FALSE; + } + else + { + if(om_navigator->next) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_navigator_is_completed( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + return om_navigator->end; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_navigator_visited( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + return om_navigator->visited; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_navigator_next( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + if(!om_navigator->next) + { + return NULL; + } + + om_navigator->node = om_navigator->next; + om_navigator->visited = om_navigator->backtracked; + om_navigator->backtracked = AXIS2_FALSE; + + axiom_navigator_update_next_node(om_navigator, env); + + /** set the starting and ending flags */ + if(om_navigator->root == om_navigator->next) + { + if(!(om_navigator->start)) + { + om_navigator->end = AXIS2_TRUE; + } + else + { + om_navigator->start = AXIS2_FALSE; + } + } + return om_navigator->node; +} + +/** this method encapsulate searching logic */ +static void +axiom_navigator_update_next_node( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + if(!om_navigator) + { + return; + } + + if(!om_navigator->next) + { + return; + } + + if((AXIOM_ELEMENT == axiom_node_get_node_type(om_navigator->next, env)) + && !(om_navigator->visited)) + { + if(axiom_node_get_first_child(om_navigator->next, env)) + { + om_navigator->next = axiom_node_get_first_child(om_navigator->next, env); + } + else if(AXIS2_TRUE == axiom_node_is_complete(om_navigator->next, env)) + { + om_navigator->backtracked = AXIS2_TRUE; + } + else + { + om_navigator->next = NULL; + } + } + else + { + axiom_node_t *parent = NULL; + axiom_node_t *next_sibling = NULL; + + next_sibling = axiom_node_get_next_sibling(om_navigator->next, env); + + parent = axiom_node_get_parent(om_navigator->next, env); + + if(next_sibling) + { + om_navigator->next = next_sibling; + } + else if((parent) && axiom_node_is_complete(parent, env)) + { + om_navigator->next = parent; + om_navigator->backtracked = AXIS2_TRUE; + } + else + { + om_navigator->next = NULL; + } + } +} diff --git a/axiom/src/om/om_node.c b/axiom/src/om/om_node.c new file mode 100644 index 0000000..9b525aa --- /dev/null +++ b/axiom/src/om/om_node.c @@ -0,0 +1,1455 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "axiom_node_internal.h" +#include "axiom_stax_builder_internal.h" +#include <axiom_element.h> +#include <axiom_text.h> +#include <axiom_data_source.h> +#include <axiom_comment.h> +#include <axiom_processing_instruction.h> +#include <axiom_doctype.h> +#include <axiom_document.h> +#include <axiom_stax_builder.h> + +struct axiom_node +{ + + /** document only available if build through builder */ + struct axiom_document *om_doc; + + axiom_stax_builder_t *builder; + + /** parent node */ + axiom_node_t *parent; + + /** previous sibling */ + axiom_node_t *prev_sibling; + + /** next sibling */ + axiom_node_t *next_sibling; + + /** first child */ + axiom_node_t *first_child; + + /** last child */ + axiom_node_t *last_child; + + /** node type, indicates the type stored in data_element */ + axiom_types_t node_type; + + /** done true means that this node is completely built , false otherwise */ + int done; + + /** instances of an om struct, whose type is defined by node type */ + void *data_element; + +}; + +static axiom_node_t * +axiom_node_detach_without_namespaces( + axiom_node_t * om_node, + const axutil_env_t * env); + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_create( + const axutil_env_t * env) +{ + axiom_node_t *node = NULL; + AXIS2_ENV_CHECK(env, NULL); + + node = (axiom_node_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_node_t)); + if(!node) + { + env->error->error_number = AXIS2_ERROR_NO_MEMORY; + return NULL; + } + node->first_child = NULL; + node->last_child = NULL; + node->next_sibling = NULL; + node->prev_sibling = NULL; + node->parent = NULL; + node->node_type = AXIOM_INVALID; + node->done = AXIS2_FALSE; + node->data_element = NULL; + node->om_doc = NULL; + node->builder = NULL; + return node; +} + +AXIS2_EXTERN axiom_node_t* AXIS2_CALL +axiom_node_create_from_buffer( + const axutil_env_t * env, + axis2_char_t *buffer) +{ + axiom_xml_reader_t *reader = NULL; + axiom_stax_builder_t *builder = NULL; + axiom_document_t *document = NULL; + axiom_node_t *om_node = NULL; + + reader = axiom_xml_reader_create_for_memory(env, buffer, axutil_strlen(buffer), "UTF-8", + AXIS2_XML_PARSER_TYPE_BUFFER); + + if(!reader) + { + return NULL; + } + + builder = axiom_stax_builder_create(env, reader); + + if(!builder) + { + return NULL; + } + document = axiom_stax_builder_get_document(builder, env); + if(!document) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Document is null for deserialization"); + return NULL; + } + + om_node = axiom_document_get_root_element(document, env); + + if(!om_node) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Root element of the document is not found"); + return NULL; + } + axiom_document_build_all(document, env); + + axiom_stax_builder_free_self(builder, env); + + return om_node; +} + +static void +axiom_node_free_detached_subtree( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + /* Free any child nodes first */ + if(om_node->first_child) + { + axiom_node_t *child_node = om_node->first_child, *next_sibling; + while(child_node) + { + next_sibling = child_node->next_sibling; + axiom_node_free_detached_subtree(child_node, env); + child_node = next_sibling; + } + } + + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + axiom_element_free((axiom_element_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_COMMENT) + { + if(om_node->data_element) + { + axiom_comment_free((axiom_comment_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_DOCTYPE) + { + /*axiom_doctype_free((axiom_doctype_t*)(om_node->data_element), env); */ + } + else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION) + { + if(om_node->data_element) + { + axiom_processing_instruction_free( + (axiom_processing_instruction_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_TEXT) + { + if(om_node->data_element) + { + axiom_text_free((axiom_text_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_DATA_SOURCE) + { + if(om_node->data_element) + { + axiom_data_source_free((axiom_data_source_t *)(om_node->data_element), env); + } + } + + AXIS2_FREE(env->allocator, om_node); + + return; +} + +/** + * This free function will free an om_element and all the children contained in it + * If the node is still attached to the tree, it will be detached first + */ +AXIS2_EXTERN void AXIS2_CALL +axiom_node_free_tree( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + if(!om_node) + { + return; + } + + /* Detach this node before freeing it and its subtree. */ + axiom_node_detach_without_namespaces(om_node, env); + + /* Free this node and its subtree */ + axiom_node_free_detached_subtree(om_node, env); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_add_child( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * child) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, child, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + + if(child->parent) + { + child = axiom_node_detach(child, env); + } + + if(!(om_node->first_child)) + { + om_node->first_child = child; + } + else + { + axiom_node_t *last_sib = NULL; + last_sib = om_node->last_child; + if(last_sib) + { + last_sib->next_sibling = child; + child->prev_sibling = last_sib; + } + } + + child->parent = om_node; + om_node->last_child = child; + return AXIS2_SUCCESS; +} + +/** + * Detach the node without regard to any namespace references in the node or + * its children. + */ +static axiom_node_t * +axiom_node_detach_without_namespaces( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axiom_node_t *parent = NULL; + + parent = om_node->parent; + if(!parent) + { + /* Node is already detached */ + om_node->builder = NULL; + return om_node; + } + + if(!om_node->prev_sibling) + { + parent->first_child = om_node->next_sibling; + } + else + { + axiom_node_t *prev_sib = NULL; + prev_sib = om_node->prev_sibling; + if(prev_sib) + { + prev_sib->next_sibling = om_node->next_sibling; + } + } + + if(om_node->next_sibling) + { + axiom_node_t *next_sibling = NULL; + next_sibling = om_node->next_sibling; + if(next_sibling) + { + next_sibling->prev_sibling = om_node->prev_sibling; + } + } + + if(parent->last_child && (parent->last_child == om_node)) + { + parent->last_child = om_node->prev_sibling; + } + + /* if the STAX builder's last node is what we are detaching, then we should adjust the + * last node if previous sibling is available, set that as the builder's last node. Else set the + * parent as the last node*/ + if(om_node->builder && (axiom_stax_builder_get_lastnode(om_node->builder, env) == om_node)) + { + axiom_node_t *lastnode = parent; + if(om_node->prev_sibling) + { + lastnode = om_node->prev_sibling; + } + axiom_stax_builder_set_lastnode(om_node->builder, env, lastnode); + } + + om_node->parent = NULL; + om_node->prev_sibling = NULL; + om_node->next_sibling = NULL; + om_node->builder = NULL; + return om_node; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_detach( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axutil_hash_t *inscope_namespaces = NULL; + axiom_element_t *om_element = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!om_node) + { + return NULL; + } + + /* If this is an element node, determine which namespaces are available to it + 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); + } + + /* Detach this node from its parent. */ + om_node = axiom_node_detach_without_namespaces(om_node, env); + + /* 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) + { + axiom_element_redeclare_parent_namespaces(om_element, env, om_node, om_element, + inscope_namespaces); + } + + if(inscope_namespaces) + { + axutil_hash_free(inscope_namespaces, env); + } + + return om_node; +} + +/** + Internal function , only used in om and soap + not to be used by users + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_parent( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * parent) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!om_node) + { + return AXIS2_FAILURE; + } + + AXIS2_PARAM_CHECK(env->error, parent, AXIS2_FAILURE); + + if(parent == om_node->parent) + { /* same parent already exist */ + return AXIS2_SUCCESS; + } + /* if a new parent is assigned in place of existing + one first the node should be detached + */ + if(om_node->parent) + { + om_node = axiom_node_detach_without_namespaces(om_node, env); + } + + om_node->parent = parent; + + return AXIS2_SUCCESS; +} + +/** + * This will insert a sibling just after the current information item + * @param node the node in consideration + * @param nodeto_insert the node that will be inserted + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_insert_sibling_after( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * node_to_insert) +{ + axiom_node_t *next_sib = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + AXIS2_PARAM_CHECK(env->error, node_to_insert, AXIS2_FAILURE); + + if(!om_node->parent) + { + /* We shouldn't add a sibling because this node doesn't has a parent. + * This can be the root node of the tree*/ + return AXIS2_FAILURE; + } + + node_to_insert->parent = om_node->parent; + + node_to_insert->prev_sibling = om_node; + + next_sib = om_node->next_sibling; + + if(next_sib) + { + next_sib->prev_sibling = node_to_insert; + } + + node_to_insert->next_sibling = om_node->next_sibling; + + om_node->next_sibling = node_to_insert; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_insert_sibling_before( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * node_to_insert) +{ + axiom_node_t *prev_sibling = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, node_to_insert, AXIS2_FAILURE); + + if(!om_node->parent) + { + /* We shouldn't add a sibling because this node doesn't has a parent. + * This can be the root node of the tree*/ + return AXIS2_FAILURE; + } + + node_to_insert->parent = om_node->parent; + + node_to_insert->prev_sibling = om_node->prev_sibling; + + node_to_insert->next_sibling = om_node; + + prev_sibling = om_node->prev_sibling; + + if(!prev_sibling) + { + axiom_node_t *parent = om_node->parent; + parent->first_child = node_to_insert; + } + else + { + axiom_node_t *prev_sibling = om_node->prev_sibling; + if(prev_sibling) + { + prev_sibling->next_sibling = node_to_insert; + } + } + om_node->prev_sibling = node_to_insert; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_serialize( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + + int status = AXIS2_SUCCESS; + axiom_node_t *temp_node = NULL; + axiom_node_t *nodes[256]; + int count = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!om_node) + { + return AXIS2_SUCCESS; + } + + nodes[count++] = om_node; + + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + do + { + + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + status = axiom_element_serialize_start_part( + (axiom_element_t *)(om_node-> data_element), env, om_output, om_node); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_DATA_SOURCE) + { + if(om_node->data_element) + { + status = axiom_data_source_serialize( + (axiom_data_source_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_TEXT) + { + if(om_node->data_element) + { + status = axiom_text_serialize((axiom_text_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_COMMENT) + { + if(om_node->data_element) + { + status = axiom_comment_serialize((axiom_comment_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_DOCTYPE) + { + if(om_node->data_element) + { + status = axiom_doctype_serialize((axiom_doctype_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION) + { + if(om_node->data_element) + { + status = axiom_processing_instruction_serialize( + (axiom_processing_instruction_t *)(om_node->data_element), env, om_output); + } + + if(status != AXIS2_SUCCESS) + { + return status; + } + } + + temp_node = axiom_node_get_first_child(om_node, env); + /* serialize children of this node */ + if(temp_node) + { + om_node = temp_node; + nodes[count++] = om_node; + } + else + { + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node-> data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + + temp_node = axiom_node_get_next_sibling(om_node, env); + if(temp_node) + { + om_node = temp_node; + nodes[count - 1] = om_node; + } + else + { + while(count > 1 && !temp_node) + { + count--; + om_node = nodes[count - 1]; + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + + temp_node = axiom_node_get_next_sibling(om_node, env); + } + + if(temp_node && count > 1) + { + om_node = temp_node; + nodes[count - 1] = om_node; + } + else + { + count--; + } + } + + } + } + while(count > 0); + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_serialize_sub_tree( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + + int status = AXIS2_SUCCESS; + axiom_node_t *temp_node = NULL; + axiom_node_t *nodes[256]; + int count = 0; + axutil_hash_t *namespaces = NULL; + axutil_hash_t *namespaces_from_parents = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!om_node) + { + return AXIS2_SUCCESS; + } + + namespaces = axutil_hash_make(env); + if(!namespaces) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "hash for namespaces creation failed"); + return AXIS2_FAILURE; + } + + namespaces_from_parents = axutil_hash_make(env); + if(!namespaces_from_parents) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "hash for namespaces_from_parents creation failed"); + return AXIS2_FAILURE; + } + + nodes[count++] = om_node; + + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + do + { + + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + axutil_hash_t *temp_namespaces = NULL; + axutil_hash_t *temp_attributes = NULL; + axiom_namespace_t *namespace = NULL; + status = axiom_element_serialize_start_part( + (axiom_element_t *)(om_node-> data_element), env, om_output, om_node); + temp_namespaces = axiom_element_get_namespaces( + (axiom_element_t *)(om_node-> data_element), env); + if(temp_namespaces) + { + axutil_hash_t *new_hash = NULL; + new_hash = axutil_hash_overlay(temp_namespaces, env, namespaces); + if(namespaces) + axutil_hash_free(namespaces, env); + namespaces = new_hash; + } + namespace = axiom_element_get_namespace( + (axiom_element_t *)(om_node-> data_element), env, om_node); + if(namespace) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(!ns) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(!ns) + { + axiom_namespace_serialize(namespace, env, om_output); + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, namespace); + } + } + } + } + + temp_attributes = axiom_element_get_all_attributes( + (axiom_element_t *)(om_node->data_element), env); + if(temp_attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(temp_attributes, env); hi; hi = axutil_hash_next( + env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + + namespace + = axiom_attribute_get_namespace((axiom_attribute_t *)val, env); + + if(namespace) + { + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(!ns) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(!ns) + { + axiom_namespace_serialize(namespace, env, om_output); + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, namespace); + } + } + } + } + } + else + { + status = AXIS2_FAILURE; + } + } + } + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_DATA_SOURCE) + { + if(om_node->data_element) + { + status = axiom_data_source_serialize( + (axiom_data_source_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_TEXT) + { + if(om_node->data_element) + { + status = axiom_text_serialize((axiom_text_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_COMMENT) + { + if(om_node->data_element) + { + status = axiom_comment_serialize((axiom_comment_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_DOCTYPE) + { + if(om_node->data_element) + { + status = axiom_doctype_serialize((axiom_doctype_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION) + { + if(om_node->data_element) + { + status = axiom_processing_instruction_serialize( + (axiom_processing_instruction_t *)(om_node->data_element), env, om_output); + } + + if(status != AXIS2_SUCCESS) + { + break; + } + } + + temp_node = axiom_node_get_first_child(om_node, env); + /* serialize children of this node */ + if(temp_node) + { + om_node = temp_node; + nodes[count++] = om_node; + } + else + { + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + + axutil_hash_t *temp_attributes = NULL; + axiom_namespace_t *namespace = NULL; + /* at the writing of end part all the namespaces declared + specially to that element should be cancelled */ + + /* first checking the element namespace */ + namespace = axiom_element_get_namespace( + (axiom_element_t *)(om_node-> data_element), env, om_node); + if(namespace) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, NULL); + } + } + } + + /* then checking the attribute namespaces */ + + temp_attributes = axiom_element_get_all_attributes( + (axiom_element_t *)(om_node->data_element), env); + if(temp_attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(temp_attributes, env); hi; hi + = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + + namespace = axiom_attribute_get_namespace((axiom_attribute_t *)val, + env); + + if(namespace) + { + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, NULL); + } + } + } + } + } + } + + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node-> data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + /* We need to make make sure that om_node is not the root when we take the next sibling */ + if(count > 1) + { + temp_node = axiom_node_get_next_sibling(om_node, env); + } + if(temp_node) + { + om_node = temp_node; + nodes[count - 1] = om_node; + } + else + { + while(count > 1 && !temp_node) + { + count--; + om_node = nodes[count - 1]; + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + axutil_hash_t *temp_attributes = NULL; + axiom_namespace_t *namespace = NULL; + + /* similar to the earlier time, whenever the ending is happened + * namespaces declared specially to that element should be cancelled */ + + /* first checking the element namespace */ + namespace = axiom_element_get_namespace( + (axiom_element_t *)(om_node-> data_element), env, om_node); + if(namespace) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, NULL); + } + } + } + + /* then checking the attribute namespaces */ + + temp_attributes = axiom_element_get_all_attributes( + (axiom_element_t *)(om_node->data_element), env); + if(temp_attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(temp_attributes, env); hi; hi + = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + + namespace = axiom_attribute_get_namespace( + (axiom_attribute_t *)val, env); + + if(namespace) + { + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, + prefix, AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, + prefix, AXIS2_HASH_KEY_STRING, NULL); + } + } + } + } + } + } + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + + temp_node = axiom_node_get_next_sibling(om_node, env); + } + + if(temp_node && count > 1) + { + om_node = temp_node; + nodes[count - 1] = om_node; + } + else + { + count--; + } + } + } + } + while(count > 0); + + axutil_hash_free(namespaces_from_parents, env); + axutil_hash_free(namespaces, env); + + return status; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_parent( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->parent; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_first_child( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int token = 0; + if(!om_node) + { + return NULL; + } + + /**********************************************************/ + while(!(om_node->first_child) && !(om_node->done) && om_node->builder) + { + token = axiom_stax_builder_next_with_token(om_node->builder, env); + if(token == -1) + { + return NULL; + } + } + + /**********************************************************/ + return om_node->first_child; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_first_element( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int token = 0; + axiom_node_t *first_element; + if(!om_node) + { + return NULL; + } + + /**********************************************************/ + while(!(om_node->first_child) && !(om_node->done) && om_node->builder) + { + token = axiom_stax_builder_next_with_token(om_node->builder, env); + if(token == -1) + { + return NULL; + } + } + + /**********************************************************/ + first_element = om_node->first_child; + + while(first_element && (axiom_node_get_node_type(first_element, env) != AXIOM_ELEMENT)) + { + first_element = axiom_node_get_next_sibling(first_element, env); + } + + return first_element; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_last_child( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->last_child; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_previous_sibling( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->prev_sibling; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_next_sibling( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int token = 0; + if(!om_node) + { + return NULL; + } + + while(!(om_node->next_sibling) && om_node->parent && om_node->builder + && !(axiom_node_is_complete(om_node->parent, env))) + { + token = axiom_stax_builder_next_with_token(om_node->builder, env); + if(token == -1) + { + return NULL; + } + } + + return om_node->next_sibling; +} + +AXIS2_EXTERN axiom_types_t AXIS2_CALL +axiom_node_get_node_type( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->node_type; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_node_is_complete( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->done; + +} + +AXIS2_EXTERN struct axiom_document *AXIS2_CALL +axiom_node_get_document( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->om_doc; +} + +AXIS2_EXTERN void *AXIS2_CALL +axiom_node_get_data_element( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->data_element; +} + +/** + internal function , not to be used by users + only sets the first_child link because this is needed by builder + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_first_child( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * first_child) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, first_child, AXIS2_FAILURE); + + /** set the parent */ + axiom_node_set_parent(first_child, env, om_node); + + om_node->first_child = first_child; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + only sets the previous sibling link as it is needed by builders + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_previous_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * prev_sibling) +{ + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prev_sibling, AXIS2_FAILURE); + + om_node->prev_sibling = prev_sibling; + return AXIS2_SUCCESS; +} + +/** + internal function, not to be used by users + only sets the next sibling link; + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_next_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * next_sibling) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, next_sibling, AXIS2_FAILURE); + om_node->next_sibling = next_sibling; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + sets the node type only used in soap and om + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_node_type( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_types_t type) +{ + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + om_node->node_type = type; + return AXIS2_SUCCESS; +} + +/** + internal function , not to be used by users + only used in om and soap + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_data_element( + axiom_node_t * om_node, + const axutil_env_t * env, + void *data_element) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data_element, AXIS2_FAILURE); + om_node->data_element = data_element; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + only sets the build status + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_complete( + axiom_node_t * om_node, + const axutil_env_t * env, + axis2_bool_t done) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + om_node->done = done; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + only used by om builder + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_document( + axiom_node_t * om_node, + const axutil_env_t * env, + struct axiom_document * om_doc) +{ + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + om_node->om_doc = om_doc; + return AXIS2_SUCCESS; +} + +/** + internal function only sets the builder reference , + should not be used by user + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_builder( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_stax_builder_t * builder) +{ + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + om_node->builder = builder; + return AXIS2_SUCCESS; +} + +/** + * This is an internal function + */ +AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL +axiom_node_get_builder( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + if(!om_node) + { + return NULL; + } + return om_node->builder; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_node_to_string( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_output_t *om_output = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *xml = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + return NULL; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + axiom_xml_writer_free(xml_writer, env); + return NULL; + } + status = axiom_node_serialize(om_node, env, om_output); + if(status == AXIS2_SUCCESS) + { + xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env)); + } + axiom_output_free(om_output, env); + return xml; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_node_sub_tree_to_string( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_output_t *om_output = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *xml = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + return NULL; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + axiom_xml_writer_free(xml_writer, env); + return NULL; + } + status = axiom_node_serialize_sub_tree(om_node, env, om_output); + if(status == AXIS2_SUCCESS) + { + xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env)); + } + axiom_output_free(om_output, env); + return xml; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_node_to_string_non_optimized( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_output_t *om_output = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *xml = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + return NULL; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + axiom_xml_writer_free(xml_writer, env); + return NULL; + } + /*This is where we set the output to be non-optimized*/ + axiom_output_set_do_optimize(om_output, env, AXIS2_FALSE); + status = axiom_node_serialize(om_node, env, om_output); + if(status == AXIS2_SUCCESS) + { + xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env)); + } + axiom_output_free(om_output, env); + return xml; +} + diff --git a/axiom/src/om/om_output.c b/axiom/src/om/om_output.c new file mode 100644 index 0000000..893f426 --- /dev/null +++ b/axiom/src/om/om_output.c @@ -0,0 +1,638 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_output.h> +#include <stdarg.h> +#include <axutil_string.h> +#include <axiom_xml_writer.h> +#include <axiom_text.h> +#include <axiom_soap_const.h> +#include <axutil_array_list.h> +#include <axutil_uuid_gen.h> +#include <axiom_mime_part.h> + +#define AXIS2_DEFAULT_CHAR_SET_ENCODING "UTF-8" + +/** also defined in axiom_soap.h */ + +/** max args for om_output_write function */ +#define MAX_ARGS 4 + +struct axiom_output +{ + + /** axiom_xml_writer. any xml writer which + implemet axiom_xml_writer.h interface */ + axiom_xml_writer_t *xml_writer; + + axis2_bool_t do_optimize; + + axis2_char_t *mime_boundary; + + axis2_char_t *root_content_id; + + int next_id; + + axis2_char_t *next_content_id; + + axis2_bool_t is_soap11; + + axis2_char_t *char_set_encoding; + + axis2_char_t *xml_version; + + axis2_bool_t ignore_xml_declaration; + + axutil_array_list_t *binary_node_list; + + axis2_char_t *mime_boundry; + + axis2_char_t *content_type; + + axutil_array_list_t *mime_parts; + +}; + +AXIS2_EXTERN axiom_output_t *AXIS2_CALL +axiom_output_create( + const axutil_env_t * env, + axiom_xml_writer_t * xml_writer) +{ + axiom_output_t *om_output = NULL; + AXIS2_ENV_CHECK(env, NULL); + + om_output = (axiom_output_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_output_t)); + + if(!om_output) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_output->xml_writer = xml_writer; + om_output->do_optimize = AXIS2_TRUE; + om_output->mime_boundary = NULL; + om_output->root_content_id = NULL; + om_output->next_content_id = NULL; + om_output->next_id = 0; + om_output->is_soap11 = AXIS2_TRUE; + om_output->char_set_encoding = AXIS2_DEFAULT_CHAR_SET_ENCODING; + om_output->xml_version = NULL; + om_output->ignore_xml_declaration = AXIS2_TRUE; + om_output->binary_node_list = NULL; + om_output->mime_boundry = NULL; + om_output->content_type = NULL; + om_output->mime_parts = NULL; + + return om_output; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_output_free( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(om_output->xml_version) + { + AXIS2_FREE(env->allocator, om_output->xml_version); + } + if(om_output->mime_boundary) + { + AXIS2_FREE(env->allocator, om_output->mime_boundary); + } + if(om_output->next_content_id) + { + AXIS2_FREE(env->allocator, om_output->next_content_id); + } + if(om_output->root_content_id) + { + AXIS2_FREE(env->allocator, om_output->root_content_id); + } + + if(om_output->xml_writer) + { + axiom_xml_writer_free(om_output->xml_writer, env); + } + + if(om_output->binary_node_list) + { + axutil_array_list_free(om_output->binary_node_list, env); + } + + if(om_output->content_type) + { + AXIS2_FREE(env->allocator, om_output->content_type); + } + + AXIS2_FREE(env->allocator, om_output); + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_output_is_soap11( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return om_output->is_soap11; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_output_is_ignore_xml_declaration( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return om_output->ignore_xml_declaration; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_set_ignore_xml_declaration( + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_bool_t ignore_xml_dec) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_output->ignore_xml_declaration = ignore_xml_dec; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_set_soap11( + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_bool_t soap11) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_output->is_soap11 = soap11; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_set_xml_version( + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_char_t * xml_version) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + AXIS2_PARAM_CHECK(env->error, xml_version, AXIS2_FAILURE); + + if(om_output->xml_version) + { + AXIS2_FREE(env->allocator, om_output->xml_version); + om_output->xml_version = NULL; + } + + om_output->xml_version = axutil_strdup(env, xml_version); + if(!om_output->xml_version) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_output_get_xml_version( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + return om_output->xml_version; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_set_char_set_encoding( + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_char_t * char_set_encoding) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_output->char_set_encoding = char_set_encoding; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_output_get_char_set_encoding( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + return om_output->char_set_encoding; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_set_do_optimize( + axiom_output_t * om_output, + const axutil_env_t * env, + axis2_bool_t optimize) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_output->do_optimize = optimize; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL +axiom_output_get_xml_writer( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + return om_output->xml_writer; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_output_is_optimized( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + return om_output->do_optimize; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_output_get_content_type( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + const axis2_char_t *soap_content_type = NULL; + if(AXIS2_TRUE == om_output->do_optimize) + { + if(AXIS2_TRUE == om_output->is_soap11) + { + soap_content_type = AXIOM_SOAP11_CONTENT_TYPE; + } + else + { + soap_content_type = AXIOM_SOAP12_CONTENT_TYPE; + } + if(om_output->content_type) + { + AXIS2_FREE(env->allocator, om_output->content_type); + om_output->content_type = NULL; + } + + om_output->content_type = (axis2_char_t *)axiom_mime_part_get_content_type_for_mime(env, + om_output->mime_boundry, om_output->root_content_id, om_output->char_set_encoding, + soap_content_type); + return om_output->content_type; + } + else if(AXIS2_TRUE == om_output->is_soap11) + { + return AXIOM_SOAP11_CONTENT_TYPE; + } + return AXIOM_SOAP12_CONTENT_TYPE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_write_optimized( + axiom_output_t * om_output, + const axutil_env_t * env, + axiom_text_t * om_text) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(om_output->binary_node_list) + { + axutil_array_list_add(om_output->binary_node_list, env, om_text); + } + else + { + om_output->binary_node_list = axutil_array_list_create(env, 5); + if(!(om_output->binary_node_list)) + { + return AXIS2_FAILURE; + } + axutil_array_list_add(om_output->binary_node_list, env, om_text); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_output_get_next_content_id( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + axis2_char_t *uuid = NULL; + axis2_char_t *temp_str = NULL; + axis2_char_t *temp_str1 = NULL; + axis2_char_t id[256]; + om_output->next_id++; + + /** free existing id */ + if(om_output->next_content_id) + { + AXIS2_FREE(env->allocator, om_output->next_content_id); + om_output->next_content_id = NULL; + } + + uuid = axutil_uuid_gen(env); + if(!uuid) + { + return NULL; + } + + sprintf(id, "%d", om_output->next_id); + + temp_str = axutil_stracat(env, id, "."); + temp_str1 = axutil_stracat(env, temp_str, uuid); + om_output->next_content_id = axutil_stracat(env, temp_str1, "@apache.org"); + if(temp_str) + { + AXIS2_FREE(env->allocator, temp_str); + temp_str = NULL; + } + if(temp_str1) + { + AXIS2_FREE(env->allocator, temp_str1); + temp_str1 = NULL; + } + if(uuid) + { + AXIS2_FREE(env->allocator, uuid); + uuid = NULL; + } + return om_output->next_content_id; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_output_get_root_content_id( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + axis2_char_t *temp_str = NULL; + axis2_char_t *uuid = NULL; + + if(!om_output->root_content_id) + { + uuid = axutil_uuid_gen(env); + + temp_str = axutil_stracat(env, "0.", uuid); + + om_output->root_content_id = axutil_stracat(env, temp_str, "@apache.org"); + + if(temp_str) + { + AXIS2_FREE(env->allocator, temp_str); + temp_str = NULL; + } + if(uuid) + { + AXIS2_FREE(env->allocator, uuid); + uuid = NULL; + } + } + + return om_output->root_content_id; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_output_get_mime_boundry( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + axis2_char_t *uuid = NULL; + if(!om_output->mime_boundary) + { + uuid = axutil_uuid_gen(env); + + om_output->mime_boundary = axutil_stracat(env, "MIMEBoundary", uuid); + if(uuid) + { + AXIS2_FREE(env->allocator, uuid); + uuid = NULL; + } + } + return om_output->mime_boundary; +} + +/******************************************************************************/ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_write( + axiom_output_t * om_output, + const axutil_env_t * env, + axiom_types_t type, + int no_of_args, + ...) +{ + int status = AXIS2_SUCCESS; + axis2_char_t *args_list[MAX_ARGS]; + int i = 0; + va_list ap; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + va_start(ap, no_of_args); + for(i = 0; i < no_of_args; i++) + { + args_list[i] = va_arg(ap, axis2_char_t *); + } + va_end(ap); + + if(type == AXIOM_ELEMENT) + { + if(no_of_args == 0) + { + status = axiom_xml_writer_write_end_element(om_output->xml_writer, env); + } + else if(no_of_args == 1) + { + status = axiom_xml_writer_write_start_element(om_output->xml_writer, env, args_list[0]); + } + else if(no_of_args == 2) + { + status = axiom_xml_writer_write_start_element_with_namespace( + om_output->xml_writer, env, args_list[0], args_list[1]); + } + else if(no_of_args == 3) + { + status = axiom_xml_writer_write_start_element_with_namespace_prefix( + om_output->xml_writer, env, args_list[0], args_list[1], args_list[2]); + } + else if(no_of_args == 4) + { + if(!args_list[0]) + { + status = AXIS2_FAILURE; + } + else if(!args_list[1]) + { + status = axiom_xml_writer_write_empty_element( + om_output->xml_writer, env,args_list[0]); + } + else if(!args_list[2]) + { + status = axiom_xml_writer_write_empty_element_with_namespace( + om_output->xml_writer, env, args_list[0], args_list[1]); + } + else + { + status = axiom_xml_writer_write_empty_element_with_namespace_prefix( + om_output->xml_writer, env, args_list[0], args_list[1], args_list[2]); + } + } + } + else if(type == AXIOM_DATA_SOURCE) + { + status = axiom_xml_writer_write_raw(om_output->xml_writer, env, args_list[0]); + } + else if(type == AXIOM_ATTRIBUTE) + { + if(no_of_args == 2) + { + status = axiom_xml_writer_write_attribute( + om_output->xml_writer, env, args_list[0], args_list[1]); + } + else if(no_of_args == 3) + { + status = axiom_xml_writer_write_attribute_with_namespace( + om_output-> xml_writer, env, args_list[0], args_list[1], args_list[2]); + } + else if(no_of_args == 4) + { + status = axiom_xml_writer_write_attribute_with_namespace_prefix( + om_output->xml_writer, env, args_list[0], args_list[1], args_list[2], args_list[3]); + } + } + else if(type == AXIOM_NAMESPACE) + { + /* If the namespace prefix is xml, it must be the pre-defined xml + namespace. Although the XML spec allows it to be declared + explicitly, this is superfluous and not accepted by all xml + parsers. */ + if((!args_list[0]) || (strcmp(args_list[0], "xml") != 0)) + { + status = axiom_xml_writer_write_namespace( + om_output->xml_writer, env, args_list[0], args_list[1]); + } + } + else if(type == AXIOM_TEXT) + { + status = axiom_xml_writer_write_characters(om_output->xml_writer, env, args_list[0]); + } + else if(type == AXIOM_COMMENT) + { + status = axiom_xml_writer_write_comment(om_output->xml_writer, env, args_list[0]); + } + else if(type == AXIOM_PROCESSING_INSTRUCTION) + { + if(no_of_args == 1) + { + status = axiom_xml_writer_write_processing_instruction( + om_output-> xml_writer, env, args_list[0]); + } + else if(no_of_args == 2) + { + status = axiom_xml_writer_write_processing_instruction_data( + om_output-> xml_writer, env, args_list[0], args_list[1]); + } + } + else if(type == AXIOM_DOCTYPE) + { + status = axiom_xml_writer_write_dtd(om_output->xml_writer, env, args_list[0]); + } + + if(status == AXIS2_SUCCESS) + { + return AXIS2_SUCCESS; + } + else + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axiom_output_write_xml_version_encoding( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!om_output->xml_version) + { + axiom_output_set_xml_version(om_output, env, "1.0"); + } + if(!om_output->char_set_encoding) + { + axiom_output_set_char_set_encoding(om_output, env, "UTF-8"); + } + return axiom_xml_writer_write_start_document_with_version_encoding(om_output-> xml_writer, env, + om_output-> xml_version, om_output-> char_set_encoding); + +} + +/* This method will be called from transport. After this method each and every + * message part needs to be send are stored in an arraylits. So the transport + * sender should correctly figure out how to send from the given information. + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_output_flush( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + const axis2_char_t *soap_content_type = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(om_output->do_optimize) + { + axis2_char_t *root_content_id = NULL; + axis2_char_t *buffer = NULL; + + /* Extracting the soap part */ + + buffer = axiom_xml_writer_get_xml(om_output->xml_writer, env); + if(om_output->is_soap11) + { + soap_content_type = AXIOM_SOAP11_CONTENT_TYPE; + } + else + { + soap_content_type = AXIOM_SOAP12_CONTENT_TYPE; + } + + /* The created mime_boundary for this soap message */ + + om_output->mime_boundry = axiom_output_get_mime_boundry(om_output, env); + + /* This is also created for attachments*/ + root_content_id = axiom_output_get_root_content_id(om_output, env); + + /* different parts of the message is added according to their order + * to an arraylist */ + om_output->mime_parts = axiom_mime_part_create_part_list(env, buffer, + om_output->binary_node_list, om_output->mime_boundry, om_output->root_content_id, + om_output->char_set_encoding, soap_content_type); + + if(om_output->mime_parts) + { + return AXIS2_SUCCESS; + } + else + { + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axiom_output_get_mime_parts( + axiom_output_t * om_output, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return om_output->mime_parts; +} + diff --git a/axiom/src/om/om_processing_instruction.c b/axiom/src/om/om_processing_instruction.c new file mode 100644 index 0000000..5be688b --- /dev/null +++ b/axiom/src/om/om_processing_instruction.c @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_processing_instruction.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" + +struct axiom_processing_instruction +{ + + /** processing instruction target */ + axis2_char_t *target; + + /** processing instruction value */ + axis2_char_t *value; +}; + +AXIS2_EXTERN axiom_processing_instruction_t *AXIS2_CALL +axiom_processing_instruction_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * target, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_processing_instruction_t *processing_instruction = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!node || !target || !value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Node or target or value is NULL"); + return NULL; + } + + *node = axiom_node_create(env); + + if(!*node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + processing_instruction = (axiom_processing_instruction_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_processing_instruction_t)); + + if(!processing_instruction) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + processing_instruction->value = NULL; + + if(value) + { + processing_instruction->value = (axis2_char_t *)axutil_strdup(env, value); + if(!processing_instruction->value) + { + AXIS2_FREE(env->allocator, processing_instruction); + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + processing_instruction->target = NULL; + + if(target) + { + processing_instruction->target = (axis2_char_t *)axutil_strdup(env, target); + if(!processing_instruction->target) + { + AXIS2_FREE(env->allocator, processing_instruction->value); + AXIS2_FREE(env->allocator, processing_instruction); + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + axiom_node_set_data_element(*node, env, processing_instruction); + axiom_node_set_node_type(*node, env, AXIOM_PROCESSING_INSTRUCTION); + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + + return processing_instruction; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_processing_instruction_free( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(om_pi->value) + { + AXIS2_FREE(env->allocator, om_pi->value); + om_pi->value = NULL; + } + + if(om_pi->target) + { + AXIS2_FREE(env->allocator, om_pi->target); + om_pi->target = NULL; + } + + AXIS2_FREE(env->allocator, om_pi); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_processing_instruction_set_value( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + om_pi->value = (axis2_char_t *)axutil_strdup(env, value); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_processing_instruction_set_target( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env, + const axis2_char_t * target) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE); + om_pi->target = (axis2_char_t *)axutil_strdup(env, target); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_processing_instruction_get_value( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env) +{ + return om_pi->value; +} +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_processing_instruction_get_target( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env) +{ + return om_pi->target; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_processing_instruction_serialize( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_pi->target && om_pi->value) + { + return axiom_output_write(om_output, env, AXIOM_PROCESSING_INSTRUCTION, 2, om_pi->target, + om_pi->value); + } + else if(om_pi->target) + { + return axiom_output_write(om_output, env, AXIOM_PROCESSING_INSTRUCTION, 2, om_pi->target, + om_pi->value); + } + return AXIS2_FAILURE; +} diff --git a/axiom/src/om/om_stax_builder.c b/axiom/src/om/om_stax_builder.c new file mode 100644 index 0000000..399a711 --- /dev/null +++ b/axiom/src/om/om_stax_builder.c @@ -0,0 +1,1072 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_stax_builder.h> +#include <axiom_element.h> +#include <axiom_text.h> +#include <axiom_processing_instruction.h> +#include <axiom_comment.h> +#include <axutil_string.h> +#include <axiom_xml_writer.h> +#include <axiom_doctype.h> +#include "axiom_node_internal.h" +#include "axiom_stax_builder_internal.h" + +struct axiom_stax_builder +{ + + /** pull parser instance used by the om_builder */ + axiom_xml_reader_t *parser; + + /** last node the om_builder found */ + axiom_node_t *lastnode; + + axiom_node_t *root_node; + + /** document associated with the om_builder */ + axiom_document_t *document; + + /** done building the document? */ + axis2_bool_t done; + + /** parser was accessed? */ + axis2_bool_t parser_accessed; + + /** caching enabled? */ + axis2_bool_t cache; + + /** current event */ + int current_event; + /** Indicate the current element level. */ + int element_level; + axutil_hash_t *declared_namespaces; +}; + +AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL +axiom_stax_builder_create( + const axutil_env_t * env, + axiom_xml_reader_t * parser) +{ + axiom_stax_builder_t *om_builder = NULL; + AXIS2_PARAM_CHECK(env->error, parser, NULL); + + om_builder = (axiom_stax_builder_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_stax_builder_t)); + if(!om_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_builder->cache = AXIS2_TRUE; + om_builder->parser_accessed = AXIS2_FALSE; + om_builder->done = AXIS2_FALSE; + om_builder->lastnode = NULL; + om_builder->document = NULL; + om_builder->parser = parser; + om_builder->current_event = -1; + om_builder->root_node = NULL; + om_builder->element_level = 0; + om_builder->declared_namespaces = axutil_hash_make(env); + om_builder->document = axiom_document_create(env, NULL, om_builder); + if(!om_builder->document) + { + AXIS2_FREE(env->allocator, om_builder); + return NULL; + } + + return om_builder; +} + +static axis2_status_t +axiom_stax_builder_process_attributes( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + int i = 0; + int attribute_count; + axiom_element_t *om_ele = NULL; + + om_ele = (axiom_element_t *)axiom_node_get_data_element(element_node, env); + attribute_count = axiom_xml_reader_get_attribute_count(om_builder->parser, env); + for(i = 1; i <= attribute_count; ++i) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + axis2_char_t *attr_name = NULL; + axis2_char_t *attr_value = NULL; + + uri = axiom_xml_reader_get_attribute_namespace_by_number(om_builder-> parser, env, i); + prefix = axiom_xml_reader_get_attribute_prefix_by_number(om_builder->parser, env, i); + if(uri && (axutil_strcmp(uri, "") != 0)) + { + ns = axiom_element_find_namespace(om_ele, env, element_node, uri, prefix); + if(!ns) + { + /* if namespace is not defined yet, create it */ + ns = axiom_namespace_create(env, uri, prefix); + } + } + if(uri) + { + axiom_xml_reader_xml_free(om_builder->parser, env, uri); + } + if(prefix) + { + axiom_xml_reader_xml_free(om_builder->parser, env, prefix); + } + + attr_name = axiom_xml_reader_get_attribute_name_by_number(om_builder->parser, env, i); + attr_value = axiom_xml_reader_get_attribute_value_by_number(om_builder->parser, env, i); + + if(attr_name) + { + axutil_string_t *attr_name_str = NULL; + axutil_string_t *attr_value_str = NULL; + axiom_attribute_t *attribute = NULL; + +#ifdef AXIS2_LIBXML2_ENABLED + attr_name_str = axutil_string_create(env, attr_name); + attr_value_str = axutil_string_create(env, attr_value); + axiom_xml_reader_xml_free(om_builder->parser, env, attr_name); + axiom_xml_reader_xml_free(om_builder->parser, env, attr_value); +#else + attr_name_str = axutil_string_create_assume_ownership(env, &attr_name); + attr_value_str = axutil_string_create_assume_ownership(env, &attr_value); +#endif + + attribute = axiom_attribute_create_str(env, attr_name_str, attr_value_str, ns); + axutil_string_free(attr_name_str, env); + axutil_string_free(attr_value_str, env); + + if(!attribute) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create attribute"); + return AXIS2_FAILURE; + } + if(axiom_element_add_attribute(om_ele, env, attribute, element_node) != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot add attribute to element"); + return AXIS2_FAILURE; + } + } + } + return AXIS2_SUCCESS; +} + +static axiom_node_t * +axiom_stax_builder_create_om_text( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + axis2_char_t *temp_value = NULL; + axutil_string_t *temp_value_str = NULL; + axiom_node_t *node = NULL; + axiom_node_t *parent = om_builder->lastnode; + + if(!parent) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_BUILDER_STATE_LAST_NODE_NULL, AXIS2_FAILURE); + return NULL; + } + + temp_value = axiom_xml_reader_get_value(om_builder->parser, env); + if(!temp_value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_XML_READER_VALUE_NULL, AXIS2_FAILURE); + return NULL; + } + +#ifdef AXIS2_LIBXML2_ENABLED + temp_value_str = axutil_string_create(env, temp_value); + axiom_xml_reader_xml_free(om_builder->parser, env, temp_value); +#else + temp_value_str = axutil_string_create_assume_ownership(env, &temp_value); +#endif + + if(!temp_value_str) + { + /* axutil_string_create will have set an error number */ + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create OM Text value"); + return NULL; + } + + if(axiom_node_is_complete(parent, env)) + { + parent = axiom_node_get_parent(om_builder->lastnode, env); + } + + axiom_text_create_str(env, parent, temp_value_str, &node); + axutil_string_free(temp_value_str, env); + + if(node) + { + axiom_node_set_complete(node, env, AXIS2_TRUE); + om_builder->lastnode = node; + } + + return node; +} + +static axis2_status_t +axiom_stax_builder_process_namespaces( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env, + axiom_node_t * node, + int is_soap_element) +{ + axis2_status_t status = AXIS2_SUCCESS; + int namespace_count = 0; + axiom_namespace_t *om_ns = NULL; + axiom_element_t *om_ele = NULL; + + /* temp values */ + axis2_char_t *tmp_prefix = NULL; + axis2_char_t *tmp_ns_prefix = NULL; + axis2_char_t *tmp_ns_uri = NULL; + axutil_string_t *tmp_ns_prefix_str = NULL; + axutil_string_t *tmp_ns_uri_str = NULL; + + int i = 0; + om_ele = (axiom_element_t *)axiom_node_get_data_element(node, env); + + namespace_count = axiom_xml_reader_get_namespace_count(om_builder->parser, env); + for(i = 1; i <= namespace_count; ++i) + { + tmp_ns_prefix = axiom_xml_reader_get_namespace_prefix_by_number(om_builder->parser, env, i); + tmp_ns_uri = axiom_xml_reader_get_namespace_uri_by_number(om_builder->parser, env, i); + +#ifdef AXIS2_LIBXML2_ENABLED + tmp_ns_prefix_str = axutil_string_create(env, tmp_ns_prefix); + tmp_ns_uri_str = axutil_string_create(env, tmp_ns_uri); +#else + tmp_ns_prefix_str = axutil_string_create_assume_ownership(env, &tmp_ns_prefix); + tmp_ns_uri_str = axutil_string_create_assume_ownership(env, &tmp_ns_uri); +#endif + + if(!tmp_ns_prefix || axutil_strcmp(tmp_ns_prefix, "xmlns") == 0) + { + /* default namespace case. !temp_ns_prefix is for guththila */ + + if(tmp_ns_prefix_str) + { + axutil_string_free(tmp_ns_prefix_str, env); + } + + tmp_ns_prefix_str = axutil_string_create(env, ""); + om_ns = axiom_namespace_create_str(env, tmp_ns_uri_str, tmp_ns_prefix_str); + if(!om_ns) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create namespace"); + return AXIS2_FAILURE; + } + + status = axiom_element_declare_namespace(om_ele, env, node, om_ns); + if(!status) + { + axiom_namespace_free(om_ns, env); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error when declaring namespace"); + return AXIS2_FAILURE; + } + } + else + { + axis2_char_t *prefix = NULL; + om_ns = axiom_namespace_create_str(env, tmp_ns_uri_str, tmp_ns_prefix_str); + if(!om_ns) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create namespace"); + return AXIS2_FAILURE; + } + + status = axiom_element_declare_namespace_assume_param_ownership(om_ele, env, om_ns); + prefix = axiom_namespace_get_prefix(om_ns, env); + axutil_hash_set(om_builder->declared_namespaces, prefix, AXIS2_HASH_KEY_STRING, om_ns); + } + + axutil_string_free(tmp_ns_uri_str, env); + axutil_string_free(tmp_ns_prefix_str, env); +#ifdef AXIS2_LIBXML2_ENABLED + axiom_xml_reader_xml_free(om_builder->parser, env, tmp_ns_uri); + axiom_xml_reader_xml_free(om_builder->parser, env, tmp_ns_prefix); +#endif + } + + /* set own namespace */ + tmp_prefix = axiom_xml_reader_get_prefix(om_builder->parser, env); + if(tmp_prefix) + { + om_ns = axutil_hash_get(om_builder->declared_namespaces, tmp_prefix, AXIS2_HASH_KEY_STRING); + + if(om_ns) + { + axiom_element_set_namespace_assume_param_ownership(om_ele, env, om_ns); + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_INVALID_DOCUMENT_STATE_UNDEFINED_NAMESPACE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error when setting namespace"); + return AXIS2_FAILURE; + } + + axiom_xml_reader_xml_free(om_builder->parser, env, tmp_prefix); + } + + return status; +} + +static axiom_node_t * +axiom_stax_builder_create_om_element( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env, + axis2_bool_t is_empty) +{ + 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; + + temp_localname = axiom_xml_reader_get_name(om_builder->parser, env); + + if(!temp_localname) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_XML_READER_ELEMENT_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find name of the 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) + { + /* since last node is null, this should be the root node */ + om_ele = axiom_element_create_str(env, NULL, temp_localname_str, NULL, &element_node); + om_builder->root_node = element_node; + if(om_builder->document) + { + axiom_document_set_root_element(om_builder->document, env, element_node); + } + } + else if(axiom_node_is_complete(om_builder->lastnode, env)) + { + /* previous node building is finished. So, this node should be a sibling of previous node */ + axiom_node_t *parent = axiom_node_get_parent(om_builder->lastnode, env); + om_ele = axiom_element_create_str(env, parent, temp_localname_str, NULL, &element_node); + if(element_node) + { + axiom_node_set_next_sibling(om_builder->lastnode, env, element_node); + axiom_node_set_previous_sibling(element_node, env, om_builder->lastnode); + } + } + else + { + /* previous node building is not finished. This should be first child of previous node */ + om_ele = axiom_element_create_str( + env, om_builder->lastnode, temp_localname_str, NULL, &element_node); + if(element_node) + { + axiom_node_set_first_child(om_builder->lastnode, env, element_node); + axiom_node_set_parent(element_node, env, om_builder->lastnode); + } + } + + axutil_string_free(temp_localname_str, env); + + if((!om_ele) || (!element_node)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create axiom element"); + return NULL; + } + + axiom_node_set_builder(element_node, env, om_builder); + axiom_node_set_document(element_node, env, om_builder->document); + axiom_element_set_is_empty(om_ele, env, is_empty); + + /* order of processing name spaces first (before processing attributes) is important */ + axiom_stax_builder_process_namespaces(om_builder, env, element_node, 0); + axiom_stax_builder_process_attributes(om_builder, env, element_node); + + om_builder->lastnode = element_node; + return element_node; +} + +static axiom_node_t * +axiom_stax_builder_create_om_comment( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + axiom_node_t *comment_node = NULL; + axis2_char_t *comment_value = NULL; + + if(!om_builder->lastnode) + { + /* if the comment is at the root level, we will omit it */ + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Top level comment is ignored"); + return NULL; + } + + comment_value = axiom_xml_reader_get_value(om_builder->parser, env); + if(!comment_value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_XML_READER_ELEMENT_NULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in reading comment"); + return NULL; + } + + if(axiom_node_is_complete(om_builder->lastnode, env)) + { + /* Last node is completed means, this node should be a sibling of last node */ + axiom_node_t *parent = axiom_node_get_parent(om_builder->lastnode, env); + axiom_comment_create(env, parent, comment_value, &comment_node); + axiom_node_set_next_sibling(om_builder->lastnode, env, comment_node); + axiom_node_set_previous_sibling(comment_node, env, om_builder->lastnode); + } + else + { + /* this node should be a child of last node */ + axiom_comment_create(env, om_builder->lastnode, comment_value, &comment_node); + axiom_node_set_first_child(om_builder->lastnode, env, comment_node); + axiom_node_set_parent(comment_node, env, om_builder->lastnode); + } + + axiom_xml_reader_xml_free(om_builder->parser,env,comment_value); + axiom_node_set_builder(comment_node, env, om_builder); + axiom_node_set_document(comment_node, env, om_builder->document); + om_builder->element_level++; + om_builder->lastnode = comment_node; + + return comment_node; +} + + +static axiom_node_t * +axiom_stax_builder_create_om_processing_instruction( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + axiom_node_t *pi_node = NULL; + axis2_char_t *target = NULL; + axis2_char_t *value = NULL; + + target = axiom_xml_reader_get_pi_target(om_builder->parser, env); + value = axiom_xml_reader_get_pi_data(om_builder->parser, env); + if(!target) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_XML_READER_ELEMENT_NULL, AXIS2_FAILURE); + return NULL; + } + if(!om_builder->lastnode) + { + /* do nothing */ + axiom_xml_reader_xml_free(om_builder->parser, env, target); + axiom_xml_reader_xml_free(om_builder->parser, env, value); + return NULL; + } + else if(axiom_node_is_complete(om_builder->lastnode, env) + || (axiom_node_get_node_type(om_builder->lastnode, env) == AXIOM_TEXT)) + { + axiom_processing_instruction_create(env, axiom_node_get_parent(om_builder-> lastnode, env), + target, value, &pi_node); + + axiom_node_set_next_sibling(om_builder->lastnode, env, pi_node); + axiom_node_set_previous_sibling(pi_node, env, om_builder->lastnode); + } + else + { + axiom_processing_instruction_create(env, om_builder->lastnode, target, value, &pi_node); + axiom_node_set_first_child(om_builder->lastnode, env, pi_node); + axiom_node_set_parent(pi_node, env, om_builder->lastnode); + } + + om_builder->element_level++; + + if(target) + { + axiom_xml_reader_xml_free(om_builder->parser, env, target); + } + if(value) + { + axiom_xml_reader_xml_free(om_builder->parser, env, value); + } + + om_builder->lastnode = pi_node; + return pi_node; +} + +static axis2_status_t +axiom_stax_builder_end_element( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + /* if last node is not set, that means end_element is called before start_element, + * which is an error */ + if(!om_builder->lastnode) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Invalid XML. End element is received before start element."); + return AXIS2_FAILURE; + } + + om_builder->element_level--; + if(axiom_node_is_complete(om_builder->lastnode, env)) + { + /* Last node completed means, this end element should be parent of the last node. */ + axiom_node_t *parent = NULL; + parent = axiom_node_get_parent(om_builder->lastnode, env); + if(parent) + { + axiom_node_set_complete(parent, env, AXIS2_TRUE); + om_builder->lastnode = parent; + } + } + else + { + axiom_node_set_complete((om_builder->lastnode), env, AXIS2_TRUE); + } + + /* if we finish building the root node, then we can set the complete status of om_builder */ + if(om_builder->root_node && axiom_node_is_complete(om_builder->root_node, env)) + { + om_builder->done = AXIS2_TRUE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_stax_builder_next( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + int token = 0; + axiom_node_t *node = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!om_builder->parser) + { + return NULL; + } + do + { + if(om_builder->done) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BUILDER_DONE_CANNOT_PULL, AXIS2_FAILURE); + return NULL; + } + + token = axiom_xml_reader_next(om_builder->parser, env); + if(token == -1) + { + return NULL; + } + + om_builder->current_event = token; + + if(!(om_builder->cache)) + { + return NULL; + } + + switch(token) + { + case AXIOM_XML_READER_START_DOCUMENT: + /*Do nothing */ + break; + + case AXIOM_XML_READER_START_ELEMENT: + node = axiom_stax_builder_create_om_element(om_builder, env, AXIS2_FALSE); + break; + + case AXIOM_XML_READER_EMPTY_ELEMENT: + +#ifdef AXIS2_LIBXML2_ENABLED + node = axiom_stax_builder_create_om_element(om_builder, env, AXIS2_FALSE); +#else + node = axiom_stax_builder_create_om_element(om_builder, env, AXIS2_TRUE); +#endif + + case AXIOM_XML_READER_END_ELEMENT: + axiom_stax_builder_end_element(om_builder, env); + break; + + case AXIOM_XML_READER_SPACE: + node = axiom_stax_builder_create_om_text(om_builder, env); + break; + + case AXIOM_XML_READER_CHARACTER: + node = axiom_stax_builder_create_om_text(om_builder, env); + break; + + case AXIOM_XML_READER_ENTITY_REFERENCE: + break; + + case AXIOM_XML_READER_COMMENT: + + node = axiom_stax_builder_create_om_comment(om_builder, env); + axiom_stax_builder_end_element(om_builder, env); + break; + + case AXIOM_XML_READER_PROCESSING_INSTRUCTION: + + node = axiom_stax_builder_create_om_processing_instruction(om_builder, env); + axiom_stax_builder_end_element(om_builder, env); + break; + + case AXIOM_XML_READER_CDATA: + break; + + case AXIOM_XML_READER_DOCUMENT_TYPE: + break; + + default: + break; + } + } + while(!node); + return node; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_stax_builder_free( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!om_builder) + { + return; + } + if(om_builder->declared_namespaces) + { + axutil_hash_free(om_builder->declared_namespaces, env); + om_builder->declared_namespaces = NULL; + } + + if(om_builder->document) + { + axiom_document_free(om_builder->document, env); + om_builder->document = NULL; + } + else + { + if(om_builder->root_node) + { + axiom_node_free_tree(om_builder->root_node, env); + om_builder->root_node = NULL; + } + } + + if(om_builder->parser) + { + axiom_xml_reader_free(om_builder->parser, env); + om_builder->parser = NULL; + } + + AXIS2_FREE(env->allocator, om_builder); + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_stax_builder_free_self( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + + axiom_node_t *temp_node = NULL; + axiom_node_t *nodes[256]; + axiom_node_t *om_node = NULL; + int count = 0; + + om_node = om_builder->root_node; + + nodes[count++] = om_node; + + if(om_node) + { + do + { + + axiom_node_set_builder(om_node, env, NULL); + axiom_node_set_document(om_node, env, NULL); + + temp_node = axiom_node_get_first_child(om_node, env); + /* serialize children of this node */ + if(temp_node) + { + om_node = temp_node; + nodes[count++] = om_node; + } + else + { + temp_node = axiom_node_get_next_sibling(om_node, env); + if(temp_node) + { + om_node = temp_node; + nodes[count - 1] = om_node; + } + else + { + while(count > 1 && !temp_node) + { + count--; + om_node = nodes[count - 1]; + temp_node = axiom_node_get_next_sibling(om_node, env); + } + if(temp_node && count > 1) + { + om_node = temp_node; + nodes[count - 1] = om_node; + } + else + { + count--; + } + } + } + } + while(count > 0); + } + if(om_builder->declared_namespaces) + { + axutil_hash_free(om_builder->declared_namespaces, env); + om_builder->declared_namespaces = NULL; + } + + if(om_builder->parser) + { + axiom_xml_reader_free(om_builder->parser, env); + om_builder->parser = NULL; + } + if(om_builder->document) + { + axiom_document_free_self(om_builder->document, env); + om_builder->document = NULL; + } + AXIS2_FREE(env->allocator, om_builder); + return; +} + +AXIS2_EXTERN axiom_document_t *AXIS2_CALL +axiom_stax_builder_get_document( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + return om_builder->document; +} + +/** + * moves the reader to next event and returns the token returned by the xml_reader , + * @param builder pointer to STAX builder struct to be used + * @param environment Environment. MUST NOT be NULL. + * @return next event axiom_xml_reader_event_types. Returns -1 on error + */ +AXIS2_EXTERN int AXIS2_CALL +axiom_stax_builder_next_with_token( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + int token = 0; + + if((!om_builder) || (!om_builder->parser)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid OM builder"); + return -1; + } + + if(om_builder->done) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BUILDER_DONE_CANNOT_PULL, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "OM is fully built. Nothing more to build"); + return -1; + } + + token = axiom_xml_reader_next(om_builder->parser, env); + om_builder->current_event = token; + + if(token == -1) + { + om_builder->done = AXIS2_TRUE; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error when reading xml"); + return -1; + } + + if(!om_builder->cache) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Caching disabled"); + return -1; + } + + switch(token) + { + case AXIOM_XML_READER_START_DOCUMENT: + { + /*Do nothing */ + break; + } + case AXIOM_XML_READER_START_ELEMENT: + { + if(!axiom_stax_builder_create_om_element(om_builder, env, AXIS2_FALSE)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in creating start element"); + return -1; + } + break; + } + case AXIOM_XML_READER_EMPTY_ELEMENT: + { + axis2_bool_t is_empty = AXIS2_TRUE; +#ifdef AXIS2_LIBXML2_ENABLED + is_empty = AXIS2_FALSE; +#endif + if(!axiom_stax_builder_create_om_element(om_builder, env, is_empty)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in creating empty element"); + return -1; + } + /* Let this to fall to AXIOM_XML_READER_END_ELEMENT case as well, since empty element + * = start element logic + end element logic */ + } + case AXIOM_XML_READER_END_ELEMENT: + { + if(axiom_stax_builder_end_element(om_builder, env) != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in processing end element"); + return -1; + } + break; + } + case AXIOM_XML_READER_SPACE: + { + /* ignore white space before the root element */ + if(om_builder->lastnode) + { + if(!axiom_stax_builder_create_om_text(om_builder, env)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in creating axiom text"); + return -1; + } + } + break; + } + case AXIOM_XML_READER_CHARACTER: + { + if(!axiom_stax_builder_create_om_text(om_builder, env)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in creating axiom text"); + return -1; + } + break; + } + case AXIOM_XML_READER_ENTITY_REFERENCE: + { + break; + } + case AXIOM_XML_READER_COMMENT: + { + if(axiom_stax_builder_create_om_comment(om_builder, env)) + { + axiom_stax_builder_end_element(om_builder, env); + } + break; + } + case AXIOM_XML_READER_PROCESSING_INSTRUCTION: + { + if(axiom_stax_builder_create_om_processing_instruction(om_builder, env)) + { + axiom_stax_builder_end_element(om_builder, env); + } + break; + } + case AXIOM_XML_READER_CDATA: + case AXIOM_XML_READER_DOCUMENT_TYPE: + default: + break; + } + return token; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_stax_builder_discard_current_element( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + axiom_node_t *element = NULL; + axiom_node_t *prev_node = NULL; + axiom_node_t *parent = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + element = om_builder->lastnode; + + if(axiom_node_is_complete(element, env) || !(om_builder->cache)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_BUILDER_STATE_CANNOT_DISCARD, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + om_builder->cache = AXIS2_FALSE; + do + { + while(axiom_xml_reader_next(om_builder->parser, env) != AXIOM_XML_READER_END_ELEMENT) + ; + } + while(!(axiom_node_is_complete(element, env))); + + /*All children of this element is pulled now */ + + prev_node = axiom_node_get_previous_sibling(element, env); + if(prev_node) + { + axiom_node_free_tree(axiom_node_get_next_sibling(prev_node, env), env); + axiom_node_set_next_sibling(prev_node, env, NULL); + } + else + { + parent = axiom_node_get_parent(element, env); + axiom_node_free_tree(axiom_node_get_first_child(parent, env), env); + axiom_node_set_first_child(parent, env, NULL); + om_builder->lastnode = parent; + } + om_builder->cache = AXIS2_TRUE; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL +axiom_stax_builder_get_parser( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + return om_builder->parser; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_stax_builder_set_cache( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env, + axis2_bool_t enable_cache) +{ + om_builder->cache = enable_cache; +} + +/** + internal function for soap om_builder only + */ +AXIS2_EXTERN int AXIS2_CALL +axiom_stax_builder_get_current_event( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + return om_builder->current_event; +} + +/** + internal function for soap om_builder only + */ +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_stax_builder_get_lastnode( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + return om_builder->lastnode; +} + +/** + internal function for soap om_builder only + */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_stax_builder_is_complete( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + return om_builder->done; +} + +/** + internal function for soap om_builder only + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_stax_builder_set_lastnode( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env, + axiom_node_t * om_node) +{ + om_builder->lastnode = om_node; + return AXIS2_SUCCESS; +} + +/** + internal function for soap om_builder only + */ +AXIS2_EXTERN int AXIS2_CALL +axiom_stax_builder_get_element_level( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + return om_builder->element_level; +} + +/** + internal function for soap om_builder only + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_stax_builder_set_element_level( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env, + int element_level) +{ + om_builder->element_level = element_level; + return AXIS2_SUCCESS; +} + +#if 0 +static axiom_node_t * +axiom_stax_builder_create_om_doctype( + axiom_stax_builder_t * om_builder, + const axutil_env_t * env) +{ + axiom_node_t *doctype_node = NULL; + axis2_char_t *doc_value = NULL; + + doc_value = axiom_xml_reader_get_dtd(om_builder->parser, env); + if(!doc_value) + { + return NULL; + } + if(!(om_builder->lastnode)) + { + axiom_doctype_create(env, NULL, doc_value, &doctype_node); + if(om_builder->document) + { + axiom_document_set_root_element(om_builder->document, env, doctype_node); + } + } + om_builder->lastnode = doctype_node; + axiom_xml_reader_xml_free(om_builder->parser, env, doc_value); + return doctype_node; +} +#endif diff --git a/axiom/src/om/om_text.c b/axiom/src/om/om_text.c new file mode 100644 index 0000000..453c395 --- /dev/null +++ b/axiom/src/om/om_text.c @@ -0,0 +1,637 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_text.h> +#include <axiom_output.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" +#include <axiom_xml_writer.h> +#include <axiom_output.h> +#include <axiom_attribute.h> +#include <axiom_namespace.h> +#include <axutil_base64.h> + +static axis2_bool_t AXIS2_CALL axiom_text_get_is_binary( + axiom_text_t * om_text, + const axutil_env_t * env); + +static axis2_status_t AXIS2_CALL axiom_text_serialize_start_part( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output); + +struct axiom_text +{ + + /** Text value */ + axutil_string_t *value; + + /** The following fields are for MTOM */ + axis2_char_t *mime_type; + axis2_bool_t optimize; + const axis2_char_t *localname; + axis2_bool_t is_binary; + axis2_bool_t is_swa; + axis2_char_t *content_id; + axiom_attribute_t *om_attribute; + axiom_namespace_t *ns; + axiom_data_handler_t *data_handler; +}; + +AXIS2_EXTERN axiom_text_t *AXIS2_CALL +axiom_text_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + om_text = (axiom_text_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_text_t)); + if(!om_text) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_text->mime_type = NULL; + om_text->optimize = AXIS2_FALSE; + om_text->localname = "Include"; + om_text->is_binary = AXIS2_FALSE; + om_text->is_swa = AXIS2_FALSE; + om_text->content_id = NULL; + om_text->om_attribute = NULL; + om_text->value = NULL; + om_text->ns = NULL; + om_text->data_handler = NULL; + om_text->mime_type = NULL; + + if(value) + { + om_text->value = axutil_string_create(env, value); + } + + axiom_node_set_data_element((*node), env, om_text); + axiom_node_set_node_type((*node), env, AXIOM_TEXT); + axiom_node_set_complete((*node), env, AXIS2_FALSE); + + if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_node_add_child(parent, env, (*node)); + } + + return om_text; +} + +AXIS2_EXTERN axiom_text_t *AXIS2_CALL +axiom_text_create_with_data_handler( + const axutil_env_t * env, + axiom_node_t * parent, + axiom_data_handler_t * data_handler, + axiom_node_t ** node) +{ + + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, data_handler, NULL); + + om_text = (axiom_text_t *)axiom_text_create(env, parent, NULL, node); + if(!om_text) + { + return NULL; + } + om_text->optimize = AXIS2_TRUE; + om_text->is_binary = AXIS2_TRUE; + om_text->data_handler = data_handler; + om_text->mime_type = axiom_data_handler_get_content_type(data_handler, env); + return om_text; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_text_free( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(om_text->value) + { + axutil_string_free(om_text->value, env); + } + + if(om_text->ns) + { + axiom_namespace_free(om_text->ns, env); + } + + if(om_text->content_id) + { + AXIS2_FREE(env->allocator, om_text->content_id); + } + + if(om_text->om_attribute) + { + axiom_attribute_free(om_text->om_attribute, env); + } + + if(om_text->data_handler) + { + axiom_data_handler_free(om_text->data_handler, env); + } + + AXIS2_FREE(env->allocator, om_text); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_serialize( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + axis2_char_t *attribute_value = NULL; + const axis2_char_t *text = NULL; + axiom_xml_writer_t *om_output_xml_writer = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(!axiom_text_get_is_binary(om_text, env)) + { + if(om_text->value) + { + status = axiom_output_write(om_output, env, AXIOM_TEXT, 1, axutil_string_get_buffer( + om_text->value, env)); + } + } + else + { + om_output_xml_writer = axiom_output_get_xml_writer(om_output, env); + if(axiom_output_is_optimized(om_output, env) && om_text->optimize) + { + if(!(axiom_text_get_content_id(om_text, env))) + { + axis2_char_t *content_id = axiom_output_get_next_content_id(om_output, env); + if(content_id) + { + om_text->content_id = axutil_strdup(env, content_id); + } + } + + attribute_value = axutil_stracat(env, "cid:", om_text->content_id); + + /*send binary as MTOM optimised */ + if(om_text->om_attribute) + { + axiom_attribute_free(om_text->om_attribute, env); + om_text->om_attribute = NULL; + } + + om_text->om_attribute = axiom_attribute_create(env, "href", attribute_value, NULL); + + AXIS2_FREE(env->allocator, attribute_value); + attribute_value = NULL; + + if(!om_text->is_swa) /* This is a hack to get SwA working */ + { + axiom_text_serialize_start_part(om_text, env, om_output); + } + else + { + status = axiom_output_write(om_output, env, AXIOM_TEXT, 1, om_text->content_id); + } + + axiom_output_write_optimized(om_output, env, om_text); + + axiom_output_write(om_output, env, AXIOM_ELEMENT, 0); + } + else + { + text = axiom_text_get_text(om_text, env); + axiom_xml_writer_write_characters(om_output_xml_writer, env, (axis2_char_t *)text); + } + } + return status; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_text_get_value( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + if(om_text->value) + { + return axutil_string_get_buffer(om_text->value, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_value( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + + if(om_text->value) + { + axutil_string_free(om_text->value, env); + om_text->value = NULL; + } + + om_text->value = axutil_string_create(env, value); + if(!om_text->value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +/*Following has been implemented for the MTOM support*/ + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_text_get_mime_type( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->mime_type; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_mime_type( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_char_t * mime_type) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + if(om_text->mime_type) + { + AXIS2_FREE(env->allocator, om_text->mime_type); + } + om_text->mime_type = (axis2_char_t *)axutil_strdup(env, mime_type); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_text_get_optimize( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->optimize; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_optimize( + axiom_text_t * om_text, + const axutil_env_t * env, + axis2_bool_t optimize) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + om_text->optimize = optimize; + return AXIS2_SUCCESS; +} + +static axis2_bool_t AXIS2_CALL +axiom_text_get_is_binary( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->is_binary; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_is_binary( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_bool_t is_binary) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + om_text->is_binary = is_binary; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_text_get_localname( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->localname; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_text_get_content_id( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->content_id; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_content_id( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_char_t * content_id) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + if(om_text->content_id) + { + AXIS2_FREE(env->allocator, om_text->content_id); + } + om_text->content_id = (axis2_char_t *)axutil_strdup(env, content_id); + return AXIS2_SUCCESS; +} + +static axis2_status_t AXIS2_CALL +axiom_text_serialize_start_part( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + axis2_char_t *namespace_uri = NULL; + axis2_char_t *prefix = NULL; + const axis2_char_t *local_name = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + local_name = axiom_text_get_localname(om_text, env); + + om_text->ns = axiom_namespace_create(env, "http://www.w3.org/2004/08/xop/include", "xop"); + + if(om_text->ns) + { + namespace_uri = axiom_namespace_get_uri(om_text->ns, env); + if(namespace_uri) + { + prefix = axiom_namespace_get_prefix(om_text->ns, env); + + if(prefix) + { + axiom_output_write(om_output, env, AXIOM_ELEMENT, 3, local_name, namespace_uri, + prefix); + } + else + { + axiom_output_write(om_output, env, AXIOM_ELEMENT, 2, local_name, namespace_uri); + } + } + else + { + axiom_output_write(om_output, env, AXIOM_ELEMENT, 1, local_name); + } + } + else + { + axiom_output_write(om_output, env, AXIOM_TEXT, 1, local_name); + } + if(om_text->om_attribute) + { + axiom_attribute_serialize(om_text->om_attribute, env, om_output); + } + if(om_text->ns) + { + axiom_namespace_serialize(om_text->ns, env, om_output); + axiom_namespace_free(om_text->ns, env); + om_text->ns = NULL; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_serialize_attribute( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output, + axiom_attribute_t * om_attribute) +{ + axiom_xml_writer_t *xml_writer = NULL; + axiom_namespace_t *om_namespace = NULL; + + axis2_char_t *namespace_uri = NULL; + axis2_char_t *prefix = NULL; + axis2_char_t *attribute_local_name = NULL; + axis2_char_t *attribute_value = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + om_namespace = axiom_namespace_create(env, "", ""); + + namespace_uri = axiom_namespace_get_uri(om_text->ns, env); + attribute_local_name = axiom_attribute_get_localname(om_attribute, env); + + if(om_namespace) + { + prefix = axiom_namespace_get_prefix(om_text->ns, env); + attribute_value = axiom_attribute_get_value(om_attribute, env); + if(prefix) + { + axiom_xml_writer_write_attribute(xml_writer, env, attribute_local_name, attribute_value); + } + else + { + axiom_xml_writer_write_attribute_with_namespace(xml_writer, env, attribute_local_name, + attribute_value, namespace_uri); + } + } + else + { + axiom_xml_writer_write_attribute(xml_writer, env, attribute_local_name, attribute_value); + } + axiom_namespace_free(om_namespace, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_serialize_namespace( + axiom_text_t * om_text, + const axutil_env_t * env, + const axiom_namespace_t * om_namespace, + axiom_output_t * om_output) +{ + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *namespace_uri = NULL; + axis2_char_t *namespace_prefix = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + om_namespace = axiom_namespace_create(env, "", ""); + + if(om_namespace) + { + namespace_uri = axiom_namespace_get_uri(om_text->ns, env); + namespace_prefix = axiom_namespace_get_prefix(om_text->ns, env); + axiom_xml_writer_write_namespace(xml_writer, env, namespace_prefix, namespace_uri); + axiom_xml_writer_set_prefix(xml_writer, env, namespace_prefix, namespace_uri); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_text_get_text( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + if(om_text->value) + { + return axutil_string_get_buffer(om_text->value, env); + } + else + { + axis2_char_t *data_handler_stream = NULL; + size_t data_handler_stream_size = 0; + if(om_text->data_handler) + { + int encoded_len = 0; + axis2_char_t *encoded_str = NULL; + axiom_data_handler_read_from(om_text->data_handler, env, &data_handler_stream, + &data_handler_stream_size); + if(data_handler_stream) + { + encoded_len = axutil_base64_encode_len((int)data_handler_stream_size); + encoded_str = AXIS2_MALLOC(env->allocator, encoded_len + 2); + if(encoded_str) + { + encoded_len = axutil_base64_encode(encoded_str, data_handler_stream, + (int)data_handler_stream_size); + encoded_str[encoded_len] = '\0'; + return encoded_str; + } + } + } + } + return NULL; +} + +AXIS2_EXTERN axiom_data_handler_t *AXIS2_CALL +axiom_text_get_data_handler( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->data_handler; +} + +AXIS2_EXTERN axiom_text_t *AXIS2_CALL +axiom_text_create_str( + const axutil_env_t * env, + axiom_node_t * parent, + axutil_string_t * value, + axiom_node_t ** node) +{ + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + om_text = (axiom_text_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_text_t)); + if(!om_text) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_text->mime_type = NULL; + om_text->optimize = AXIS2_FALSE; + om_text->localname = "Include"; + om_text->is_binary = AXIS2_FALSE; + om_text->content_id = NULL; + om_text->om_attribute = NULL; + om_text->value = NULL; + om_text->ns = NULL; + om_text->data_handler = NULL; + om_text->mime_type = NULL; + + if(value) + { + om_text->value = axutil_string_clone(value, env); + } + + axiom_node_set_data_element((*node), env, om_text); + axiom_node_set_node_type((*node), env, AXIOM_TEXT); + axiom_node_set_complete((*node), env, AXIS2_FALSE); + + if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_node_add_child(parent, env, (*node)); + } + + return om_text; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_value_str( + struct axiom_text * om_text, + const axutil_env_t * env, + axutil_string_t * value) +{ + if(om_text->value) + { + axutil_string_free(om_text->value, env); + om_text->value = NULL; + } + if(value) + { + om_text->value = axutil_string_clone(value, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_text_get_value_str( + struct axiom_text * om_text, + const axutil_env_t * env) +{ + return om_text->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_is_swa( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_bool_t is_swa) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + om_text->is_swa = is_swa; + return AXIS2_SUCCESS; +} |