You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by sh...@apache.org on 2010/03/23 14:22:10 UTC

svn commit: r926564 - in /axis/axis2/c/core/trunk/axiom: include/axiom_node.h include/axiom_stax_builder.h src/om/axiom_node_internal.h src/om/axiom_stax_builder_internal.h src/om/om_node.c src/om/om_stax_builder.c

Author: shankar
Date: Tue Mar 23 13:22:09 2010
New Revision: 926564

URL: http://svn.apache.org/viewvc?rev=926564&view=rev
Log:
Refactor to increase performace

Modified:
    axis/axis2/c/core/trunk/axiom/include/axiom_node.h
    axis/axis2/c/core/trunk/axiom/include/axiom_stax_builder.h
    axis/axis2/c/core/trunk/axiom/src/om/axiom_node_internal.h
    axis/axis2/c/core/trunk/axiom/src/om/axiom_stax_builder_internal.h
    axis/axis2/c/core/trunk/axiom/src/om/om_node.c
    axis/axis2/c/core/trunk/axiom/src/om/om_stax_builder.c

Modified: axis/axis2/c/core/trunk/axiom/include/axiom_node.h
URL: http://svn.apache.org/viewvc/axis/axis2/c/core/trunk/axiom/include/axiom_node.h?rev=926564&r1=926563&r2=926564&view=diff
==============================================================================
--- axis/axis2/c/core/trunk/axiom/include/axiom_node.h (original)
+++ axis/axis2/c/core/trunk/axiom/include/axiom_node.h Tue Mar 23 13:22:09 2010
@@ -141,11 +141,11 @@ extern "C"
         axiom_node_t * child);
 
     /**
-    * Detaches given node from the parent and reset the links
+    * Detaches given node from the parent and reset the links. Will recreate "namespace defined in
+    * the parent and used in detached node" within detached node itself
     * @param om_node node to be detached, cannot be NULL.
     * @param env Environment. MUST NOT be NULL, .
-    * @return a pointer to detached node,returns NULL on error with error
-    *           code set to environment's error struct
+    * @return a pointer to detached node,returns NULL on error
     */
     AXIS2_EXTERN axiom_node_t *AXIS2_CALL
     axiom_node_detach(
@@ -153,6 +153,18 @@ extern "C"
         const axutil_env_t * env);
 
     /**
+     * Detaches given node from the parent and reset the links. will not adjust the namespace as
+     * in the case of axiom_node_detach.
+     * @param om_node node to be detached, cannot be NULL.
+     * @param env Environment. MUST NOT be NULL, .
+     * @return a pointer to detached node,returns NULL on error
+     */
+    AXIS2_EXTERN axiom_node_t *AXIS2_CALL
+    axiom_node_detach_without_namespaces(
+        axiom_node_t * om_node,
+        const axutil_env_t * env);
+
+    /**
     * Inserts a sibling node after the given node
     * @param om_node node to whom the sibling to be inserted. , cannot be NULL.
     * @param env Environment. MUST NOT be NULL, .
@@ -366,10 +378,7 @@ extern "C"
         axiom_node_t * om_node,
         const axutil_env_t * env);
     
-    AXIS2_EXTERN struct axiom_stax_builder *AXIS2_CALL
-                axiom_node_get_builder(
-                    axiom_node_t * om_node,
-                    const axutil_env_t * env);
+
     /** @} */
 
 #ifdef __cplusplus

Modified: axis/axis2/c/core/trunk/axiom/include/axiom_stax_builder.h
URL: http://svn.apache.org/viewvc/axis/axis2/c/core/trunk/axiom/include/axiom_stax_builder.h?rev=926564&r1=926563&r2=926564&view=diff
==============================================================================
--- axis/axis2/c/core/trunk/axiom/include/axiom_stax_builder.h (original)
+++ axis/axis2/c/core/trunk/axiom/include/axiom_stax_builder.h Tue Mar 23 13:22:09 2010
@@ -37,52 +37,47 @@ extern "C"
     typedef struct axiom_stax_builder axiom_stax_builder_t;
 
     /**
-      * 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. 
-      */
+     * 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);
 
     /**
-      * 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 op AXIS2_SUCCESS on success,
-      *     AXIS2_FAILURE on error.
-      */
+     * 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(
-        struct axiom_stax_builder *builder,
+        axiom_stax_builder_t *builder,
         const axutil_env_t * env);
 
     /**
      * Free the build struct instance and its associated document.
-    does not free the associated axiom tree.
+     * Will not free the associated axiom tree.
      * @param builder pointer to builder struct
      * @param env environment, MUST NOT be NULL
-     * @return status of the op AXIS2_SUCCESS on success,
-     *     AXIS2_FAILURE on error.
+     * @return status of the operation AXIS2_SUCCESS on success, AXIS2_FAILURE on error.
      */
     AXIS2_EXTERN void AXIS2_CALL
     axiom_stax_builder_free_self(
-        struct axiom_stax_builder *builder,
+        axiom_stax_builder_t *builder,
         const axutil_env_t * 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 there is no document associated with the builder,
-      *     NULL if an error occured.
-      */
+     * @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(
-        struct axiom_stax_builder *builder,
+        axiom_stax_builder_t *builder,
         const axutil_env_t * env);
 
     /** @} */

Modified: axis/axis2/c/core/trunk/axiom/src/om/axiom_node_internal.h
URL: http://svn.apache.org/viewvc/axis/axis2/c/core/trunk/axiom/src/om/axiom_node_internal.h?rev=926564&r1=926563&r2=926564&view=diff
==============================================================================
--- axis/axis2/c/core/trunk/axiom/src/om/axiom_node_internal.h (original)
+++ axis/axis2/c/core/trunk/axiom/src/om/axiom_node_internal.h Tue Mar 23 13:22:09 2010
@@ -49,7 +49,7 @@ extern "C"
      * @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
+    axis2_status_t AXIS2_CALL
     axiom_node_set_parent(
         axiom_node_t * om_node,
         const axutil_env_t * env,
@@ -61,7 +61,7 @@ extern "C"
      * @param env environment, MUST NOT be NULL.
      * @param first_child child to be set as first child
      */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_status_t AXIS2_CALL
     axiom_node_set_first_child(
         axiom_node_t * om_node,
         const axutil_env_t * env,
@@ -75,7 +75,7 @@ extern "C"
      * @return status of the op, AXIS2_SUCCESS on success
      *     AXIS2_FAILURE on error
      */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_status_t AXIS2_CALL
     axiom_node_set_previous_sibling(
         axiom_node_t * om_node,
         const axutil_env_t * env,
@@ -89,7 +89,7 @@ extern "C"
      * @return status of the op, AXIS2_SUCCESS on success,
      *     AXIS2_FAILURE on error
      */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_status_t AXIS2_CALL
     axiom_node_set_next_sibling(
         axiom_node_t * om_node,
         const axutil_env_t * env,
@@ -103,7 +103,7 @@ extern "C"
      * @return status code of the op AXIS2_SUCCESS on success,
      *     AXIS2_FAILURE on error
      */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_status_t AXIS2_CALL
     axiom_node_set_node_type(
         axiom_node_t * om_node,
         const axutil_env_t * env,
@@ -117,7 +117,7 @@ extern "C"
      * @return status code of the op AXIS2_SUCCESS on success,
      *     AXIS2_FAILURE on error
      */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_status_t AXIS2_CALL
     axiom_node_set_data_element(
         axiom_node_t * om_node,
         const axutil_env_t * env,
@@ -130,13 +130,30 @@ extern "C"
      * @param env environment, MUST NOT be NULL.
      * @param done
      */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_status_t AXIS2_CALL
     axiom_node_set_complete(
         axiom_node_t * om_node,
         const axutil_env_t * env,
         axis2_bool_t done);
 
     /**
+     * Sets the builder
+     */
+    axis2_status_t AXIS2_CALL
+    axiom_node_set_builder(
+        axiom_node_t * om_node,
+        const axutil_env_t * env,
+        struct axiom_stax_builder *builder);
+
+    void AXIS2_CALL
+    axiom_node_assume_builder_ownership(
+        axiom_node_t *om_node,
+        const axutil_env_t * env);
+
+
+
+#if 0
+    /**
      * This functions is only to be used by builder
      * do not use this function
      */
@@ -146,14 +163,12 @@ extern "C"
         const axutil_env_t * env,
         struct axiom_document *om_doc);
 
-    /**
-     * Sets the builder
-     */
-    AXIS2_EXTERN axis2_status_t AXIS2_CALL
-    axiom_node_set_builder(
+    AXIS2_EXTERN struct axiom_stax_builder *AXIS2_CALL
+    axiom_node_get_builder(
         axiom_node_t * om_node,
-        const axutil_env_t * env,
-        struct axiom_stax_builder *builder);
+        const axutil_env_t * env);
+
+#endif
 
 
     /** @} */

Modified: axis/axis2/c/core/trunk/axiom/src/om/axiom_stax_builder_internal.h
URL: http://svn.apache.org/viewvc/axis/axis2/c/core/trunk/axiom/src/om/axiom_stax_builder_internal.h?rev=926564&r1=926563&r2=926564&view=diff
==============================================================================
--- axis/axis2/c/core/trunk/axiom/src/om/axiom_stax_builder_internal.h (original)
+++ axis/axis2/c/core/trunk/axiom/src/om/axiom_stax_builder_internal.h Tue Mar 23 13:22:09 2010
@@ -66,6 +66,11 @@ extern "C"
         axiom_stax_builder_t * builder,
         const axutil_env_t * env);
 
+    /* this will be called from root node to free the stax builder */
+    void AXIS2_CALL
+    axiom_stax_builder_free_internal(
+        axiom_stax_builder_t * builder,
+        const axutil_env_t * env);
 
 
     /**

Modified: axis/axis2/c/core/trunk/axiom/src/om/om_node.c
URL: http://svn.apache.org/viewvc/axis/axis2/c/core/trunk/axiom/src/om/om_node.c?rev=926564&r1=926563&r2=926564&view=diff
==============================================================================
--- axis/axis2/c/core/trunk/axiom/src/om/om_node.c (original)
+++ axis/axis2/c/core/trunk/axiom/src/om/om_node.c Tue Mar 23 13:22:09 2010
@@ -28,12 +28,12 @@
 
 struct axiom_node
 {
-
-    /** document only available if build through builder */
-    struct axiom_document *om_doc;
-
+    /* stax builder */
     axiom_stax_builder_t *builder;
 
+    /* whether current node is the owner of stax builder. If so, it has to free it */
+    axis2_bool_t own_builder;
+
     /** parent node */
     axiom_node_t *parent;
 
@@ -60,11 +60,6 @@ struct axiom_node
 
 };
 
-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)
@@ -86,8 +81,8 @@ axiom_node_create(
     node->node_type = AXIOM_INVALID;
     node->done = AXIS2_FALSE;
     node->data_element = NULL;
-    node->om_doc = NULL;
     node->builder = NULL;
+    node->own_builder = AXIS2_FALSE;
     return node;
 }
 
@@ -195,8 +190,6 @@ axiom_node_free_detached_subtree(
     }
 
     AXIS2_FREE(env->allocator, om_node);
-
-    return;
 }
 
 /**
@@ -217,10 +210,14 @@ axiom_node_free_tree(
     /* Detach this node before freeing it and its subtree. */
     axiom_node_detach_without_namespaces(om_node, env);
 
+    /* if the owner of the builder, then free the builder */
+    if(om_node->own_builder)
+    {
+        axiom_stax_builder_free_internal(om_node->builder, env);
+    }
+
     /* Free this node and its subtree */
     axiom_node_free_detached_subtree(om_node, env);
-
-    return;
 }
 
 AXIS2_EXTERN axis2_status_t AXIS2_CALL
@@ -259,10 +256,13 @@ axiom_node_add_child(
 }
 
 /**
- * Detach the node without regard to any namespace references in the node or
- * its children.
+ * Detaches given node from the parent and reset the links. will not adjust the namespace as
+ * in the case of axiom_node_detach.
+ * @param om_node node to be detached, cannot be NULL.
+ * @param env Environment. MUST NOT be NULL, .
+ * @return a pointer to detached node,returns NULL on error
  */
-static axiom_node_t *
+AXIS2_EXTERN axiom_node_t *AXIS2_CALL
 axiom_node_detach_without_namespaces(
     axiom_node_t * om_node,
     const axutil_env_t * env)
@@ -273,7 +273,6 @@ axiom_node_detach_without_namespaces(
     if(!parent)
     {
         /* Node is already detached */
-        om_node->builder = NULL;
         return om_node;
     }
 
@@ -326,6 +325,13 @@ axiom_node_detach_without_namespaces(
     return om_node;
 }
 
+/**
+ * Detaches given node from the parent and reset the links. Will recreate "namespace defined in
+ * the parent and used in detached node" within detached node itself
+ * @param om_node node to be detached, cannot be NULL.
+ * @param env Environment. MUST NOT be NULL, .
+ * @return a pointer to detached node,returns NULL on error
+ */
 AXIS2_EXTERN axiom_node_t *AXIS2_CALL
 axiom_node_detach(
     axiom_node_t * om_node,
@@ -370,7 +376,7 @@ axiom_node_detach(
  Internal function , only used in om and soap
  not to be used by users
  */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_status_t AXIS2_CALL
 axiom_node_set_parent(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1182,7 +1188,12 @@ axiom_node_get_document(
     axiom_node_t * om_node,
     const axutil_env_t * env)
 {
-    return om_node->om_doc;
+    if(om_node->builder)
+    {
+        return axiom_stax_builder_get_document(om_node->builder, env);
+    }
+
+    return NULL;
 }
 
 AXIS2_EXTERN void *AXIS2_CALL
@@ -1197,7 +1208,7 @@ axiom_node_get_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
+axis2_status_t AXIS2_CALL
 axiom_node_set_first_child(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1219,7 +1230,7 @@ axiom_node_set_first_child(
  only sets the previous sibling link as it is needed by builders
 
  */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_status_t AXIS2_CALL
 axiom_node_set_previous_sibling(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1238,7 +1249,7 @@ axiom_node_set_previous_sibling(
  internal function, not to be used by users
  only sets the next sibling link;
  */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_status_t AXIS2_CALL
 axiom_node_set_next_sibling(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1256,7 +1267,7 @@ axiom_node_set_next_sibling(
  sets the node type only used in soap and om
  */
 
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_status_t AXIS2_CALL
 axiom_node_set_node_type(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1273,7 +1284,7 @@ axiom_node_set_node_type(
  internal function , not to be used by users
  only used in om and soap
  */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_status_t AXIS2_CALL
 axiom_node_set_data_element(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1291,7 +1302,7 @@ axiom_node_set_data_element(
  only sets the build status
 
  */
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_status_t AXIS2_CALL
 axiom_node_set_complete(
     axiom_node_t * om_node,
     const axutil_env_t * env,
@@ -1304,49 +1315,26 @@ axiom_node_set_complete(
 }
 
 /**
- 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
+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);
+    /* builder == NULL is a valid case */
     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,
+void AXIS2_CALL
+axiom_node_assume_builder_ownership(
+    axiom_node_t *om_node,
     const axutil_env_t * env)
 {
-    if(!om_node)
-    {
-        return NULL;
-    }
-    return om_node->builder;
+    om_node->own_builder = AXIS2_TRUE;
 }
 
 AXIS2_EXTERN axis2_char_t *AXIS2_CALL
@@ -1453,3 +1441,36 @@ axiom_node_to_string_non_optimized(
     return xml;
 }
     
+#if 0
+
+/**
+ 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)
+{
+    /* om_doc == NULL is a valid case */
+    om_node->om_doc = om_doc;
+    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;
+}
+
+#endif

Modified: axis/axis2/c/core/trunk/axiom/src/om/om_stax_builder.c
URL: http://svn.apache.org/viewvc/axis/axis2/c/core/trunk/axiom/src/om/om_stax_builder.c?rev=926564&r1=926563&r2=926564&view=diff
==============================================================================
--- axis/axis2/c/core/trunk/axiom/src/om/om_stax_builder.c (original)
+++ axis/axis2/c/core/trunk/axiom/src/om/om_stax_builder.c Tue Mar 23 13:22:09 2010
@@ -53,13 +53,25 @@ struct axiom_stax_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;
-    AXIS2_PARAM_CHECK(env->error, parser, 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)
@@ -69,144 +81,85 @@ axiom_stax_builder_create(
         return NULL;
     }
 
-    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);
+        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;
     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)
 {
-    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;
-    }
-
+    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);
+}
 
-    return;
+/* 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)
+{
+    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)
 {
-
-    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)
+    if(om_builder->root_node)
     {
-        axiom_xml_reader_free(om_builder->parser, env);
-        om_builder->parser = NULL;
+        axiom_node_assume_builder_ownership(om_builder->root_node, env);
     }
-    if(om_builder->document)
-    {
-        axiom_document_free_self(om_builder->document, env);
-        om_builder->document = NULL;
-    }
-    AXIS2_FREE(env->allocator, om_builder);
-    return;
 }
 
+/** 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,
@@ -531,7 +484,6 @@ axiom_stax_builder_create_om_element(
     }
 
     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 */
@@ -583,7 +535,6 @@ axiom_stax_builder_create_om_comment(
 
     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;
 
@@ -1053,4 +1004,73 @@ axiom_stax_builder_next(
     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