summaryrefslogtreecommitdiffstats
path: root/axiom/src/om/om_stax_builder.c
diff options
context:
space:
mode:
Diffstat (limited to 'axiom/src/om/om_stax_builder.c')
-rw-r--r--axiom/src/om/om_stax_builder.c1072
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