diff options
author | gmcdonald | 2010-02-13 01:32:03 +0000 |
---|---|---|
committer | gmcdonald | 2010-02-13 01:32:03 +0000 |
commit | 0425aadc78680e53000fd0108b540d6eca048516 (patch) | |
tree | 8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /axiom/src/om/om_stax_builder.c | |
download | axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2 |
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'axiom/src/om/om_stax_builder.c')
-rw-r--r-- | axiom/src/om/om_stax_builder.c | 1072 |
1 files changed, 1072 insertions, 0 deletions
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 |