blob: 2dd767a9e52737be61486980fb96e1c2d628745e [file] [log] [blame]
/*
* 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_internal.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"
#include <axiom_soap_builder_internal.h>
#include "axiom_document_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;
/** root node of the xml document */
axiom_node_t *root_node;
/** document associated with the om_builder */
axiom_document_t *document;
/** done building the document? */
axis2_bool_t done;
/** current event */
int current_event;
/** Indicate the current element level. */
int element_level;
/** reference to the soap builder, to build soap releated elements */
axiom_soap_builder_t *soap_builder;
axutil_hash_t *declared_namespaces;
};
/**
* Creates an stax builder
* @param environment Environment. MUST NOT be NULL.
* @param parser parser to be used with builder. The builder will take ownership of the parser.
* @return a pointer to the newly created builder struct.
*/
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;
if(!parser)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid xml parser given for stax builder");
return 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);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create stax builder");
return NULL;
}
om_builder->document = axiom_document_create(env, NULL, om_builder);
if(!om_builder->document)
{
AXIS2_FREE(env->allocator, om_builder);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create axiom document");
return NULL;
}
om_builder->declared_namespaces = axutil_hash_make(env);
if(!om_builder->declared_namespaces)
{
AXIS2_FREE(env->allocator, om_builder);
axiom_document_free(om_builder->document, env);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create namespace hashmap");
return NULL;
}
om_builder->done = AXIS2_FALSE;
om_builder->lastnode = NULL;
om_builder->parser = parser;
om_builder->current_event = -1;
om_builder->root_node = NULL;
om_builder->element_level = 0;
om_builder->soap_builder = NULL;
return om_builder;
}
/**
* Free the build struct instance and its associated document,axiom tree.
* @param builder pointer to builder struct
* @param env environment, MUST NOT be NULL
* @return status of the operation AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
*/
AXIS2_EXTERN void AXIS2_CALL
axiom_stax_builder_free(
axiom_stax_builder_t * om_builder,
const axutil_env_t * env)
{
axutil_hash_free(om_builder->declared_namespaces, env);
axiom_document_free(om_builder->document, env);
axiom_xml_reader_free(om_builder->parser, env);
AXIS2_FREE(env->allocator, om_builder);
}
/* this will be called from root node to free the stax builder */
void AXIS2_CALL
axiom_stax_builder_free_internal(
axiom_stax_builder_t * om_builder,
const axutil_env_t * env)
{
if(om_builder)
{
axutil_hash_free(om_builder->declared_namespaces, env);
axiom_xml_reader_free(om_builder->parser, env);
axiom_document_free_self(om_builder->document, env);
AXIS2_FREE(env->allocator, om_builder);
}
}
/**
* Give the responsibility of freeing the stax builder to the root node. This method will not
* free anything. When the root node is freed, it will call axiom_stax_builder_free_internal
* which will free the stax builder, document and xml reader.
* @param builder pointer to builder struct
* @param env environment, MUST NOT be NULL
* @return status of the operation AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
*/
AXIS2_EXTERN void AXIS2_CALL
axiom_stax_builder_free_self(
axiom_stax_builder_t * om_builder,
const axutil_env_t * env)
{
if(om_builder->root_node)
{
axiom_node_assume_builder_ownership(om_builder->root_node, env);
}
else
{
axiom_stax_builder_free_internal(om_builder, env);
}
}
/**
* Gets the document associated with the builder
* @param builder axiom_stax_builder
* @param env environment
* @return pointer to document struct associated with builder NULL if an error occurred.
*/
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;
}
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);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create OM Text without a node");
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);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid OM Text value");
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)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create axiom_text");
return NULL;
}
axiom_node_set_builder(node, env, om_builder);
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(om_ele, env, node, om_ns);
prefix = axiom_namespace_get_prefix(om_ns, env);
axutil_hash_set(om_builder->declared_namespaces, prefix, AXIS2_HASH_KEY_STRING, om_ns);
}
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(om_ele, env, om_ns, node);
}
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;
axiom_node_t *parent = 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;
}
om_builder->element_level++;
if(om_builder->lastnode)
{
if(axiom_node_is_complete(om_builder->lastnode, env))
{
/*previous node building is finished. This node should be a sibling of previous node */
parent = axiom_node_get_parent(om_builder->lastnode, env);
}
else
{
/*previous node building is not finished. This should be child of previous node */
parent = om_builder->lastnode;
}
}
om_ele = axiom_element_create(env, parent, temp_localname, NULL, &element_node);
axiom_xml_reader_xml_free(om_builder->parser, env, temp_localname);
if((!om_ele) || (!element_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create axiom element");
return NULL;
}
axiom_node_set_builder(element_node, env, om_builder);
axiom_element_set_is_empty(om_ele, env, is_empty);
if(!om_builder->lastnode)
{
/* since last node is null, this should be the root node */
om_builder->root_node = element_node;
axiom_document_set_root_element(om_builder->document, env, element_node);
}
/* 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;
axiom_node_t *parent = 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 */
parent = axiom_node_get_parent(om_builder->lastnode, env);
}
else
{
/* this node should be a child of last node */
parent = om_builder->lastnode;
}
axiom_comment_create(env, parent, comment_value, &comment_node);
axiom_xml_reader_xml_free(om_builder->parser,env,comment_value);
if(!comment_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to create axiom element");
return NULL;
}
axiom_node_set_builder(comment_node, env, om_builder);
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);
}
axiom_node_set_builder(pi_node, env, om_builder);
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 = 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(axiom_node_is_complete(om_builder->root_node, env))
{
om_builder->done = AXIS2_TRUE;
}
return AXIS2_SUCCESS;
}
/**
* 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
*/
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->done)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BUILDER_DONE_CANNOT_PULL, AXIS2_FAILURE);
AXIS2_LOG_DEBUG(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_ERROR_SET(env->error, AXIS2_ERROR_BUILDER_DONE_CANNOT_PULL, AXIS2_FAILURE);
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "-1 returned from the xml reader when reading xml");
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;
}
/* Note that we don't have a break here.
* 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 the comment is at the root level, we will omit it */
if(om_builder->lastnode)
{
axis2_status_t status = AXIS2_FAILURE;
if(axiom_stax_builder_create_om_comment(om_builder, env))
{
status = axiom_stax_builder_end_element(om_builder, env);
}
if(status != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in creating axiom comment");
return -1;
}
}
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;
}
/* if stax builder is also a soap builder, build soap related elements */
if(om_builder->soap_builder &&
(token == AXIOM_XML_READER_START_ELEMENT || token == AXIOM_XML_READER_EMPTY_ELEMENT))
{
AXIS2_ASSERT(om_builder->lastnode != NULL);
if(axiom_soap_builder_construct_node(om_builder->soap_builder, env, om_builder->lastnode)
!= AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occurred when building soap node");
om_builder->done = AXIS2_TRUE;
return -1;
}
}
return token;
}
/**
internal function for soap om_builder only
*/
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
*/
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_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
*/
void 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;
}
/**
internal function for soap om_builder only
*/
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
*/
void 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;
}
void AXIS2_CALL
axiom_stax_builder_set_soap_builder(
axiom_stax_builder_t *om_builder,
const axutil_env_t *env,
axiom_soap_builder_t *soap_builder)
{
om_builder->soap_builder = soap_builder;
}
axiom_node_t *AXIS2_CALL
axiom_stax_builder_get_root_node(
axiom_stax_builder_t *om_builder,
const axutil_env_t * env)
{
return om_builder->root_node;
}
#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;
}
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;
}
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;
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;
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 && !axiom_node_is_complete(om_builder->root_node, env));
return node;
}
AXIS2_EXTERN void AXIS2_CALL
axiom_stax_builder_free_self_original(
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);
temp_node = axiom_node_get_first_child(om_node, env);
if(temp_node)
{
/* process the child node */
om_node = temp_node;
nodes[count++] = om_node;
}
else
{
/* no child node. check whether current node has any siblings */
temp_node = axiom_node_get_next_sibling(om_node, env);
if(temp_node)
{
/* process sibling nodes */
om_node = temp_node;
nodes[count - 1] = om_node;
}
else
{
/* no siblings. so fallback to parent of current node and process */
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);
}
axutil_hash_free(om_builder->declared_namespaces, env);
axiom_xml_reader_free(om_builder->parser, env);
axiom_document_free_self(om_builder->document, env);
AXIS2_FREE(env->allocator, om_builder);
}
#endif