summaryrefslogtreecommitdiffstats
path: root/axiom/src/om/om_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'axiom/src/om/om_output.c')
-rw-r--r--axiom/src/om/om_output.c638
1 files changed, 638 insertions, 0 deletions
diff --git a/axiom/src/om/om_output.c b/axiom/src/om/om_output.c
new file mode 100644
index 0000000..893f426
--- /dev/null
+++ b/axiom/src/om/om_output.c
@@ -0,0 +1,638 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <axiom_output.h>
+#include <stdarg.h>
+#include <axutil_string.h>
+#include <axiom_xml_writer.h>
+#include <axiom_text.h>
+#include <axiom_soap_const.h>
+#include <axutil_array_list.h>
+#include <axutil_uuid_gen.h>
+#include <axiom_mime_part.h>
+
+#define AXIS2_DEFAULT_CHAR_SET_ENCODING "UTF-8"
+
+/** also defined in axiom_soap.h */
+
+/** max args for om_output_write function */
+#define MAX_ARGS 4
+
+struct axiom_output
+{
+
+ /** axiom_xml_writer. any xml writer which
+ implemet axiom_xml_writer.h interface */
+ axiom_xml_writer_t *xml_writer;
+
+ axis2_bool_t do_optimize;
+
+ axis2_char_t *mime_boundary;
+
+ axis2_char_t *root_content_id;
+
+ int next_id;
+
+ axis2_char_t *next_content_id;
+
+ axis2_bool_t is_soap11;
+
+ axis2_char_t *char_set_encoding;
+
+ axis2_char_t *xml_version;
+
+ axis2_bool_t ignore_xml_declaration;
+
+ axutil_array_list_t *binary_node_list;
+
+ axis2_char_t *mime_boundry;
+
+ axis2_char_t *content_type;
+
+ axutil_array_list_t *mime_parts;
+
+};
+
+AXIS2_EXTERN axiom_output_t *AXIS2_CALL
+axiom_output_create(
+ const axutil_env_t * env,
+ axiom_xml_writer_t * xml_writer)
+{
+ axiom_output_t *om_output = NULL;
+ AXIS2_ENV_CHECK(env, NULL);
+
+ om_output = (axiom_output_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_output_t));
+
+ if(!om_output)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ return NULL;
+ }
+
+ om_output->xml_writer = xml_writer;
+ om_output->do_optimize = AXIS2_TRUE;
+ om_output->mime_boundary = NULL;
+ om_output->root_content_id = NULL;
+ om_output->next_content_id = NULL;
+ om_output->next_id = 0;
+ om_output->is_soap11 = AXIS2_TRUE;
+ om_output->char_set_encoding = AXIS2_DEFAULT_CHAR_SET_ENCODING;
+ om_output->xml_version = NULL;
+ om_output->ignore_xml_declaration = AXIS2_TRUE;
+ om_output->binary_node_list = NULL;
+ om_output->mime_boundry = NULL;
+ om_output->content_type = NULL;
+ om_output->mime_parts = NULL;
+
+ return om_output;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_output_free(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, void);
+
+ if(om_output->xml_version)
+ {
+ AXIS2_FREE(env->allocator, om_output->xml_version);
+ }
+ if(om_output->mime_boundary)
+ {
+ AXIS2_FREE(env->allocator, om_output->mime_boundary);
+ }
+ if(om_output->next_content_id)
+ {
+ AXIS2_FREE(env->allocator, om_output->next_content_id);
+ }
+ if(om_output->root_content_id)
+ {
+ AXIS2_FREE(env->allocator, om_output->root_content_id);
+ }
+
+ if(om_output->xml_writer)
+ {
+ axiom_xml_writer_free(om_output->xml_writer, env);
+ }
+
+ if(om_output->binary_node_list)
+ {
+ axutil_array_list_free(om_output->binary_node_list, env);
+ }
+
+ if(om_output->content_type)
+ {
+ AXIS2_FREE(env->allocator, om_output->content_type);
+ }
+
+ AXIS2_FREE(env->allocator, om_output);
+ return;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axiom_output_is_soap11(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ return om_output->is_soap11;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axiom_output_is_ignore_xml_declaration(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ return om_output->ignore_xml_declaration;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_set_ignore_xml_declaration(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_bool_t ignore_xml_dec)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ om_output->ignore_xml_declaration = ignore_xml_dec;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_set_soap11(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_bool_t soap11)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ om_output->is_soap11 = soap11;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_set_xml_version(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_char_t * xml_version)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ AXIS2_PARAM_CHECK(env->error, xml_version, AXIS2_FAILURE);
+
+ if(om_output->xml_version)
+ {
+ AXIS2_FREE(env->allocator, om_output->xml_version);
+ om_output->xml_version = NULL;
+ }
+
+ om_output->xml_version = axutil_strdup(env, xml_version);
+ if(!om_output->xml_version)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_output_get_xml_version(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ return om_output->xml_version;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_set_char_set_encoding(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_char_t * char_set_encoding)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ om_output->char_set_encoding = char_set_encoding;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_output_get_char_set_encoding(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ return om_output->char_set_encoding;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_set_do_optimize(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axis2_bool_t optimize)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ om_output->do_optimize = optimize;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL
+axiom_output_get_xml_writer(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ return om_output->xml_writer;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axiom_output_is_optimized(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ return om_output->do_optimize;
+}
+
+AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
+axiom_output_get_content_type(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ const axis2_char_t *soap_content_type = NULL;
+ if(AXIS2_TRUE == om_output->do_optimize)
+ {
+ if(AXIS2_TRUE == om_output->is_soap11)
+ {
+ soap_content_type = AXIOM_SOAP11_CONTENT_TYPE;
+ }
+ else
+ {
+ soap_content_type = AXIOM_SOAP12_CONTENT_TYPE;
+ }
+ if(om_output->content_type)
+ {
+ AXIS2_FREE(env->allocator, om_output->content_type);
+ om_output->content_type = NULL;
+ }
+
+ om_output->content_type = (axis2_char_t *)axiom_mime_part_get_content_type_for_mime(env,
+ om_output->mime_boundry, om_output->root_content_id, om_output->char_set_encoding,
+ soap_content_type);
+ return om_output->content_type;
+ }
+ else if(AXIS2_TRUE == om_output->is_soap11)
+ {
+ return AXIOM_SOAP11_CONTENT_TYPE;
+ }
+ return AXIOM_SOAP12_CONTENT_TYPE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_write_optimized(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axiom_text_t * om_text)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ if(om_output->binary_node_list)
+ {
+ axutil_array_list_add(om_output->binary_node_list, env, om_text);
+ }
+ else
+ {
+ om_output->binary_node_list = axutil_array_list_create(env, 5);
+ if(!(om_output->binary_node_list))
+ {
+ return AXIS2_FAILURE;
+ }
+ axutil_array_list_add(om_output->binary_node_list, env, om_text);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_output_get_next_content_id(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ axis2_char_t *uuid = NULL;
+ axis2_char_t *temp_str = NULL;
+ axis2_char_t *temp_str1 = NULL;
+ axis2_char_t id[256];
+ om_output->next_id++;
+
+ /** free existing id */
+ if(om_output->next_content_id)
+ {
+ AXIS2_FREE(env->allocator, om_output->next_content_id);
+ om_output->next_content_id = NULL;
+ }
+
+ uuid = axutil_uuid_gen(env);
+ if(!uuid)
+ {
+ return NULL;
+ }
+
+ sprintf(id, "%d", om_output->next_id);
+
+ temp_str = axutil_stracat(env, id, ".");
+ temp_str1 = axutil_stracat(env, temp_str, uuid);
+ om_output->next_content_id = axutil_stracat(env, temp_str1, "@apache.org");
+ if(temp_str)
+ {
+ AXIS2_FREE(env->allocator, temp_str);
+ temp_str = NULL;
+ }
+ if(temp_str1)
+ {
+ AXIS2_FREE(env->allocator, temp_str1);
+ temp_str1 = NULL;
+ }
+ if(uuid)
+ {
+ AXIS2_FREE(env->allocator, uuid);
+ uuid = NULL;
+ }
+ return om_output->next_content_id;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_output_get_root_content_id(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ axis2_char_t *temp_str = NULL;
+ axis2_char_t *uuid = NULL;
+
+ if(!om_output->root_content_id)
+ {
+ uuid = axutil_uuid_gen(env);
+
+ temp_str = axutil_stracat(env, "0.", uuid);
+
+ om_output->root_content_id = axutil_stracat(env, temp_str, "@apache.org");
+
+ if(temp_str)
+ {
+ AXIS2_FREE(env->allocator, temp_str);
+ temp_str = NULL;
+ }
+ if(uuid)
+ {
+ AXIS2_FREE(env->allocator, uuid);
+ uuid = NULL;
+ }
+ }
+
+ return om_output->root_content_id;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_output_get_mime_boundry(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ axis2_char_t *uuid = NULL;
+ if(!om_output->mime_boundary)
+ {
+ uuid = axutil_uuid_gen(env);
+
+ om_output->mime_boundary = axutil_stracat(env, "MIMEBoundary", uuid);
+ if(uuid)
+ {
+ AXIS2_FREE(env->allocator, uuid);
+ uuid = NULL;
+ }
+ }
+ return om_output->mime_boundary;
+}
+
+/******************************************************************************/
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_write(
+ axiom_output_t * om_output,
+ const axutil_env_t * env,
+ axiom_types_t type,
+ int no_of_args,
+ ...)
+{
+ int status = AXIS2_SUCCESS;
+ axis2_char_t *args_list[MAX_ARGS];
+ int i = 0;
+ va_list ap;
+
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+
+ va_start(ap, no_of_args);
+ for(i = 0; i < no_of_args; i++)
+ {
+ args_list[i] = va_arg(ap, axis2_char_t *);
+ }
+ va_end(ap);
+
+ if(type == AXIOM_ELEMENT)
+ {
+ if(no_of_args == 0)
+ {
+ status = axiom_xml_writer_write_end_element(om_output->xml_writer, env);
+ }
+ else if(no_of_args == 1)
+ {
+ status = axiom_xml_writer_write_start_element(om_output->xml_writer, env, args_list[0]);
+ }
+ else if(no_of_args == 2)
+ {
+ status = axiom_xml_writer_write_start_element_with_namespace(
+ om_output->xml_writer, env, args_list[0], args_list[1]);
+ }
+ else if(no_of_args == 3)
+ {
+ status = axiom_xml_writer_write_start_element_with_namespace_prefix(
+ om_output->xml_writer, env, args_list[0], args_list[1], args_list[2]);
+ }
+ else if(no_of_args == 4)
+ {
+ if(!args_list[0])
+ {
+ status = AXIS2_FAILURE;
+ }
+ else if(!args_list[1])
+ {
+ status = axiom_xml_writer_write_empty_element(
+ om_output->xml_writer, env,args_list[0]);
+ }
+ else if(!args_list[2])
+ {
+ status = axiom_xml_writer_write_empty_element_with_namespace(
+ om_output->xml_writer, env, args_list[0], args_list[1]);
+ }
+ else
+ {
+ status = axiom_xml_writer_write_empty_element_with_namespace_prefix(
+ om_output->xml_writer, env, args_list[0], args_list[1], args_list[2]);
+ }
+ }
+ }
+ else if(type == AXIOM_DATA_SOURCE)
+ {
+ status = axiom_xml_writer_write_raw(om_output->xml_writer, env, args_list[0]);
+ }
+ else if(type == AXIOM_ATTRIBUTE)
+ {
+ if(no_of_args == 2)
+ {
+ status = axiom_xml_writer_write_attribute(
+ om_output->xml_writer, env, args_list[0], args_list[1]);
+ }
+ else if(no_of_args == 3)
+ {
+ status = axiom_xml_writer_write_attribute_with_namespace(
+ om_output-> xml_writer, env, args_list[0], args_list[1], args_list[2]);
+ }
+ else if(no_of_args == 4)
+ {
+ status = axiom_xml_writer_write_attribute_with_namespace_prefix(
+ om_output->xml_writer, env, args_list[0], args_list[1], args_list[2], args_list[3]);
+ }
+ }
+ else if(type == AXIOM_NAMESPACE)
+ {
+ /* If the namespace prefix is xml, it must be the pre-defined xml
+ namespace. Although the XML spec allows it to be declared
+ explicitly, this is superfluous and not accepted by all xml
+ parsers. */
+ if((!args_list[0]) || (strcmp(args_list[0], "xml") != 0))
+ {
+ status = axiom_xml_writer_write_namespace(
+ om_output->xml_writer, env, args_list[0], args_list[1]);
+ }
+ }
+ else if(type == AXIOM_TEXT)
+ {
+ status = axiom_xml_writer_write_characters(om_output->xml_writer, env, args_list[0]);
+ }
+ else if(type == AXIOM_COMMENT)
+ {
+ status = axiom_xml_writer_write_comment(om_output->xml_writer, env, args_list[0]);
+ }
+ else if(type == AXIOM_PROCESSING_INSTRUCTION)
+ {
+ if(no_of_args == 1)
+ {
+ status = axiom_xml_writer_write_processing_instruction(
+ om_output-> xml_writer, env, args_list[0]);
+ }
+ else if(no_of_args == 2)
+ {
+ status = axiom_xml_writer_write_processing_instruction_data(
+ om_output-> xml_writer, env, args_list[0], args_list[1]);
+ }
+ }
+ else if(type == AXIOM_DOCTYPE)
+ {
+ status = axiom_xml_writer_write_dtd(om_output->xml_writer, env, args_list[0]);
+ }
+
+ if(status == AXIS2_SUCCESS)
+ {
+ return AXIS2_SUCCESS;
+ }
+ else
+ return AXIS2_FAILURE;
+}
+
+axis2_status_t AXIS2_CALL
+axiom_output_write_xml_version_encoding(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ if(!om_output->xml_version)
+ {
+ axiom_output_set_xml_version(om_output, env, "1.0");
+ }
+ if(!om_output->char_set_encoding)
+ {
+ axiom_output_set_char_set_encoding(om_output, env, "UTF-8");
+ }
+ return axiom_xml_writer_write_start_document_with_version_encoding(om_output-> xml_writer, env,
+ om_output-> xml_version, om_output-> char_set_encoding);
+
+}
+
+/* This method will be called from transport. After this method each and every
+ * message part needs to be send are stored in an arraylits. So the transport
+ * sender should correctly figure out how to send from the given information.
+ */
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axiom_output_flush(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ const axis2_char_t *soap_content_type = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ if(om_output->do_optimize)
+ {
+ axis2_char_t *root_content_id = NULL;
+ axis2_char_t *buffer = NULL;
+
+ /* Extracting the soap part */
+
+ buffer = axiom_xml_writer_get_xml(om_output->xml_writer, env);
+ if(om_output->is_soap11)
+ {
+ soap_content_type = AXIOM_SOAP11_CONTENT_TYPE;
+ }
+ else
+ {
+ soap_content_type = AXIOM_SOAP12_CONTENT_TYPE;
+ }
+
+ /* The created mime_boundary for this soap message */
+
+ om_output->mime_boundry = axiom_output_get_mime_boundry(om_output, env);
+
+ /* This is also created for attachments*/
+ root_content_id = axiom_output_get_root_content_id(om_output, env);
+
+ /* different parts of the message is added according to their order
+ * to an arraylist */
+ om_output->mime_parts = axiom_mime_part_create_part_list(env, buffer,
+ om_output->binary_node_list, om_output->mime_boundry, om_output->root_content_id,
+ om_output->char_set_encoding, soap_content_type);
+
+ if(om_output->mime_parts)
+ {
+ return AXIS2_SUCCESS;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axiom_output_get_mime_parts(
+ axiom_output_t * om_output,
+ const axutil_env_t * env)
+{
+ AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+ return om_output->mime_parts;
+}
+