/* * 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 #include #include #include #include #include #include #include #include #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; }