diff options
Diffstat (limited to 'axiom/src')
85 files changed, 31517 insertions, 0 deletions
diff --git a/axiom/src/Makefile.am b/axiom/src/Makefile.am new file mode 100644 index 0000000..a3e9472 --- /dev/null +++ b/axiom/src/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = parser attachments soap util ${XPATH_DIR} om + diff --git a/axiom/src/attachments/Makefile.am b/axiom/src/attachments/Makefile.am new file mode 100644 index 0000000..e4ec8fd --- /dev/null +++ b/axiom/src/attachments/Makefile.am @@ -0,0 +1,15 @@ +noinst_LTLIBRARIES = libaxis2_attachments.la +AM_CPPFLAGS = $(CPPFLAGS) +libaxis2_attachments_la_SOURCES = mime_part.c \ + data_handler.c \ + mime_body_part.c \ + mime_parser.c + +libaxis2_attachments_la_LIBADD = ../../../util/src/libaxutil.la + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/parser \ + -I ../../../util/include + +EXTRA_DIST = axiom_mime_body_part.h + diff --git a/axiom/src/attachments/axiom_mime_body_part.h b/axiom/src/attachments/axiom_mime_body_part.h new file mode 100644 index 0000000..a925679 --- /dev/null +++ b/axiom/src/attachments/axiom_mime_body_part.h @@ -0,0 +1,121 @@ + +/* + * 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. + */ + +#ifndef AXIOM_MIME_BODY_PART_H +#define AXIOM_MIME_BODY_PART_H + +/** + * @file axiom_mime_body_part.h + * @brief axis2 mime_body_part interface + */ + +#include <axutil_utils.h> +#include <axutil_error.h> +#include <axutil_utils_defines.h> +#include <axutil_env.h> +#include <axutil_allocator.h> +#include <axutil_string.h> +#include <axutil_array_list.h> +#include <axiom_data_handler.h> +#include <axiom_text.h> +#include <axiom_mime_const.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axiom_mime_body_part axiom_mime_body_part_t; + + /** @defgroup axiom_mime_body_part + * @ingroup axiom_mime_body_part + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_mime_body_part_add_header( + axiom_mime_body_part_t * mime_body_part, + const axutil_env_t * env, + const axis2_char_t * name, + const axis2_char_t * value); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_mime_body_part_set_data_handler( + axiom_mime_body_part_t * mime_body_part, + const axutil_env_t * env, + axiom_data_handler_t * data_handler); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_mime_body_part_write_to( + axiom_mime_body_part_t * mime_body_part, + const axutil_env_t * env, + axis2_byte_t ** output_stream, + int *output_stream_size); + + /** Deallocate memory + * @return status code + */ + AXIS2_EXTERN void AXIS2_CALL + axiom_mime_body_part_free( + axiom_mime_body_part_t * mime_body_part, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_mime_body_part_write_to_list( + axiom_mime_body_part_t *mime_body_part, + const axutil_env_t *env, + axutil_array_list_t *list); + + /** + * Creates mime_body_part struct + * @return pointer to newly created mime_body_part + */ + AXIS2_EXTERN axiom_mime_body_part_t *AXIS2_CALL + axiom_mime_body_part_create( + const axutil_env_t * env); + + /** + * Creates mime_body_part struct from a om_text + * @return pointer to newly created mime_body_part + */ + + AXIS2_EXTERN axiom_mime_body_part_t *AXIS2_CALL + axiom_mime_body_part_create_from_om_text( + const axutil_env_t *env, + axiom_text_t *text); + + +#define AXIOM_MIME_BODY_PART_FREE(mime_body_part, env) \ + axiom_mime_body_part_free (mime_body_part, env) + +#define AXIOM_MIME_BODY_PART_ADD_HEADER(mime_body_part, env, name, value) \ + axiom_mime_body_part_add_header (mime_body_part, env, name, value) + +#define AXIOM_MIME_BODY_PART_SET_DATA_HANDLER(mime_body_part, env, data_handler) \ + axiom_mime_body_part_set_data_handler (mime_body_part, env, data_handler) + +#define AXIOM_MIME_BODY_PART_WRITE_TO(mime_body_part, env, output_stream, output_stream_size) \ + axiom_mime_body_part_write_to (mime_body_part, env, output_stream, output_stream_size) + + /** @} */ + +#ifdef __cplusplus +} +#endif +#endif /* AXIOM_MIME_BODY_PART_H */ diff --git a/axiom/src/attachments/data_handler.c b/axiom/src/attachments/data_handler.c new file mode 100644 index 0000000..3be8a9d --- /dev/null +++ b/axiom/src/attachments/data_handler.c @@ -0,0 +1,572 @@ +/* + * 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_data_handler.h> +#include <stdio.h> +#include <sys/stat.h> +#include <axiom_mime_part.h> + +struct axiom_data_handler +{ + /* The content type */ + axis2_char_t *mime_type; + + /* If in a file then the file name*/ + axis2_char_t *file_name; + + /* If it is in a buffer then the buffer */ + axis2_byte_t *buffer; + + /* The length of the buffer */ + size_t buffer_len; + + /* Is this a data_handler with a file name or a buffer*/ + axiom_data_handler_type_t data_handler_type; + + /* When parsing whether we have cached it or not */ + axis2_bool_t cached; + + /* The Content Id */ + axis2_char_t *mime_id; + + /* In the case of sending callback this is required */ + void *user_param; + +}; + +/* Creates the data_handler. The file name is not mandatory */ + +AXIS2_EXTERN axiom_data_handler_t *AXIS2_CALL +axiom_data_handler_create( + const axutil_env_t *env, + const axis2_char_t *file_name, + const axis2_char_t *mime_type) +{ + axiom_data_handler_t *data_handler = NULL; + + AXIS2_ENV_CHECK(env, NULL); + data_handler = (axiom_data_handler_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_data_handler_t)); + + if(!data_handler) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create data handler"); + return NULL; + } + + data_handler->mime_type = NULL; + data_handler->file_name = NULL; + data_handler->buffer = NULL; + data_handler->buffer_len = 0; + /* By default, a Data Handler is of type Buffer */ + data_handler->data_handler_type = AXIOM_DATA_HANDLER_TYPE_BUFFER; + data_handler->cached = AXIS2_FALSE; + data_handler->mime_id = NULL; + data_handler->user_param = NULL; + + if(mime_type) + { + data_handler->mime_type = axutil_strdup(env, mime_type); + if(!(data_handler->mime_type)) + { + axiom_data_handler_free(data_handler, env); + return NULL; + } + } + if(file_name) + { + data_handler->file_name = axutil_strdup(env, file_name); + if(!(data_handler->file_name)) + { + axiom_data_handler_free(data_handler, env); + return NULL; + } + data_handler->data_handler_type = AXIOM_DATA_HANDLER_TYPE_FILE; + } + + return data_handler; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_data_handler_free( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + if(data_handler->file_name) + { + AXIS2_FREE(env->allocator, data_handler->file_name); + } + + if(data_handler->mime_type) + { + AXIS2_FREE(env->allocator, data_handler->mime_type); + } + + if(data_handler->buffer) + { + AXIS2_FREE(env->allocator, data_handler->buffer); + } + + if(data_handler->mime_id) + { + AXIS2_FREE(env->allocator, data_handler->mime_id); + } + + if(data_handler) + { + AXIS2_FREE(env->allocator, data_handler); + } + + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_data_handler_get_content_type( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->mime_type; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_set_content_type( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + const axis2_char_t *mime_type) +{ + if(data_handler->mime_type) + { + AXIS2_FREE(env->allocator, data_handler->mime_type); + } + data_handler->mime_type = axutil_strdup(env, mime_type); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_data_handler_get_cached( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->cached; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_data_handler_set_cached( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + axis2_bool_t cached) +{ + data_handler->cached = cached; +} + +AXIS2_EXTERN axis2_byte_t *AXIS2_CALL +axiom_data_handler_get_input_stream( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->buffer; +} + +AXIS2_EXTERN size_t AXIS2_CALL +axiom_data_handler_get_input_stream_len( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->buffer_len; +} + +/* With MTOM caching support this function is no longer used + * Because this will load whole file in to buffer. So for large + * attachment this is not wise */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_read_from( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + axis2_byte_t **output_stream, + size_t *output_stream_size) +{ + if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_BUFFER) + { + *output_stream = data_handler->buffer; + *output_stream_size = data_handler->buffer_len; + } + else if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_FILE + && data_handler->file_name) + { + FILE *f = NULL; + axis2_byte_t *byte_stream = NULL; + axis2_byte_t *temp_byte_stream = NULL; + axis2_byte_t *read_stream = NULL; + int byte_stream_size = 0; + int temp_byte_stream_size = 0; + int read_stream_size = 0; + int count = 0; + struct stat stat_p; + + f = fopen(data_handler->file_name, "rb"); + if(!f) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for reading", + data_handler->file_name); + return AXIS2_FAILURE; + } + + if(stat(data_handler->file_name, &stat_p) == -1) + { + fclose(f); + return AXIS2_FAILURE; + } + else if(stat_p.st_size == 0) + { + fclose(f); + *output_stream = NULL; + *output_stream_size = 0; + return AXIS2_SUCCESS; + } + + do + { + read_stream_size = stat_p.st_size; + read_stream = AXIS2_MALLOC(env->allocator, (read_stream_size) * sizeof(axis2_byte_t)); + if(!read_stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create binary stream"); + if(byte_stream) + { + AXIS2_FREE(env->allocator, byte_stream); + } + fclose(f); + return AXIS2_FAILURE; + } + count = (int)fread(read_stream, 1, read_stream_size, f); + /* The count lies within the int range */ + if(ferror(f)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in reading file %s", + data_handler->file_name); + if(byte_stream) + { + AXIS2_FREE(env->allocator, byte_stream); + } + if(read_stream) + { + AXIS2_FREE(env->allocator, read_stream); + } + fclose(f); + return AXIS2_FAILURE; + } + + /* copy the read bytes */ + if(count > 0) + { + if(byte_stream) + { + temp_byte_stream = byte_stream; + temp_byte_stream_size = byte_stream_size; + byte_stream_size = temp_byte_stream_size + count; + byte_stream = AXIS2_MALLOC(env->allocator, (byte_stream_size) + * sizeof(axis2_byte_t)); + if(!byte_stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create binary stream"); + if(read_stream) + { + AXIS2_FREE(env->allocator, read_stream); + } + if(temp_byte_stream) + { + AXIS2_FREE(env->allocator, temp_byte_stream); + } + fclose(f); + return AXIS2_FAILURE; + } + + memcpy(byte_stream, temp_byte_stream, temp_byte_stream_size); + memcpy(byte_stream + temp_byte_stream_size, read_stream, count); + + if(read_stream) + { + AXIS2_FREE(env->allocator, read_stream); + read_stream_size = 0; + } + if(temp_byte_stream) + { + AXIS2_FREE(env->allocator, temp_byte_stream); + temp_byte_stream = NULL; + temp_byte_stream_size = 0; + } + } + else + { + byte_stream = read_stream; + byte_stream_size = read_stream_size; + read_stream = NULL; + read_stream_size = 0; + } + } + else if(read_stream) + { + AXIS2_FREE(env->allocator, read_stream); + } + } + while(!feof(f)); + + fclose(f); + data_handler->buffer = byte_stream; + data_handler->buffer_len = byte_stream_size; + *output_stream = byte_stream; + *output_stream_size = byte_stream_size; + } + else + { + /* Data Handler File Name is missing */ + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_set_binary_data( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + axis2_byte_t *input_stream, + size_t input_stream_len) +{ + data_handler->buffer = input_stream; + data_handler->buffer_len = input_stream_len; + return AXIS2_SUCCESS; +} + +/* This function will write the data in the buffer + * to a file. When caching is being used this will + * not be called , because the parser it self cache + * the attachment while parsing */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_write_to( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + if(data_handler->file_name) + { + FILE *f = NULL; + int count = 0; + + f = fopen(data_handler->file_name, "wb"); + if(!f) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error opening file %s for writing", + data_handler->file_name); + return AXIS2_FAILURE; + } + + count = (int)fwrite(data_handler->buffer, 1, data_handler->buffer_len, f); + /* The count lies within the int range */ + + if(ferror(f)) + { + fclose(f); + return AXIS2_FAILURE; + } + fflush(f); + fclose(f); + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_set_file_name( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + axis2_char_t *file_name) +{ + if(data_handler->file_name) + { + AXIS2_FREE(env->allocator, data_handler->file_name); + data_handler->file_name = NULL; + } + + if(file_name) + { + data_handler->file_name = axutil_strdup(env, file_name); + if(!(data_handler->file_name)) + { + return AXIS2_FAILURE; + } + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_data_handler_get_file_name( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + if(data_handler->file_name) + { + return data_handler->file_name; + } + else + { + return NULL; + } +} + +/* This method will add the data_handler binary data to the array_list. + * If it is a buffer the part type is buffer. otherwise it is a file. In the + * case of file the array_list have just the file name and the size. The content + * is not loaded to the memory. + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_add_binary_data( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + axutil_array_list_t *list) + +{ + axiom_mime_part_t *binary_part = NULL; + + binary_part = axiom_mime_part_create(env); + + if(!binary_part) + { + return AXIS2_FAILURE; + } + + if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_BUFFER) + { + binary_part->part = (axis2_byte_t *)AXIS2_MALLOC(env->allocator, (data_handler->buffer_len) + * sizeof(axis2_byte_t)); + memcpy(binary_part->part, data_handler->buffer, data_handler->buffer_len); + + binary_part->part_size = data_handler->buffer_len; + binary_part->type = AXIOM_MIME_PART_BUFFER; + } + + /* In the case of file we first calculate the file size + * and then add the file name */ + + else if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_FILE + && data_handler->file_name) + { + struct stat stat_p; + + if(stat(data_handler->file_name, &stat_p) == -1) + { + return AXIS2_FAILURE; + } + else if(stat_p.st_size == 0) + { + return AXIS2_SUCCESS; + } + else + { + binary_part->file_name = (axis2_char_t *)axutil_strdup(env, data_handler->file_name); + binary_part->part_size = stat_p.st_size; + binary_part->type = AXIOM_MIME_PART_FILE; + } + } + /* In the case of Callback the user should specify the callback name in the + * configuration file. We just set the correct type. Inside the transport + * it will load the callback and send the attachment appropriately */ + + else if(data_handler->data_handler_type == AXIOM_DATA_HANDLER_TYPE_CALLBACK) + { + binary_part->type = AXIOM_MIME_PART_CALLBACK; + binary_part->user_param = data_handler->user_param; + } + + else + { + /* Data Handler File Name is missing */ + return AXIS2_FAILURE; + } + + /* Finaly we add the binary details to the list */ + + axutil_array_list_add(list, env, binary_part); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_data_handler_get_mime_id( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->mime_id; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_handler_set_mime_id( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + const axis2_char_t *mime_id) +{ + if(data_handler->mime_id) + { + AXIS2_FREE(env->allocator, data_handler->mime_id); + } + data_handler->mime_id = axutil_strdup(env, mime_id); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_data_handler_type_t AXIS2_CALL +axiom_data_handler_get_data_handler_type( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->data_handler_type; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_data_handler_set_data_handler_type( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + axiom_data_handler_type_t data_handler_type) +{ + data_handler->data_handler_type = data_handler_type; + return; +} + +AXIS2_EXTERN void *AXIS2_CALL +axiom_data_handler_get_user_param( + axiom_data_handler_t *data_handler, + const axutil_env_t *env) +{ + return data_handler->user_param; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_data_handler_set_user_param( + axiom_data_handler_t *data_handler, + const axutil_env_t *env, + void *user_param) +{ + data_handler->user_param = user_param; + return; +} + diff --git a/axiom/src/attachments/mime_body_part.c b/axiom/src/attachments/mime_body_part.c new file mode 100644 index 0000000..186acdb --- /dev/null +++ b/axiom/src/attachments/mime_body_part.c @@ -0,0 +1,284 @@ +/* + * 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_mime_body_part.h" +#include <axiom_mime_part.h> +#include <axiom_data_handler.h> +#include <axutil_hash.h> + +struct axiom_mime_body_part +{ + /* hash map to hold header name, value pairs */ + axutil_hash_t *header_map; + axiom_data_handler_t *data_handler; +}; + +/* This method just create a mime_body_part. It does not + * fill the header map. + */ + +AXIS2_EXTERN axiom_mime_body_part_t *AXIS2_CALL +axiom_mime_body_part_create( + const axutil_env_t *env) +{ + axiom_mime_body_part_t *mime_body_part = NULL; + + AXIS2_ENV_CHECK(env, NULL); + mime_body_part = (axiom_mime_body_part_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_mime_body_part_t)); + + if(!mime_body_part) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create MIME body part"); + return NULL; + } + + mime_body_part->header_map = NULL; + mime_body_part->data_handler = NULL; + + mime_body_part->header_map = axutil_hash_make(env); + if(!(mime_body_part->header_map)) + { + axiom_mime_body_part_free(mime_body_part, env); + return NULL; + } + + return mime_body_part; +} + +/* This method will create the mime_body_part and fill the header map with + * default information. Default information are for binary attachments. + * Attachment information is taken from the information in data_handler in passed + * om_text. + */ + +AXIS2_EXTERN axiom_mime_body_part_t *AXIS2_CALL +axiom_mime_body_part_create_from_om_text( + const axutil_env_t *env, + axiom_text_t *text) +{ + axiom_data_handler_t *data_handler = NULL; + axiom_mime_body_part_t *mime_body_part = NULL; + axis2_char_t *content_id = NULL; + axis2_char_t *temp_content_id = NULL; + const axis2_char_t *content_type = AXIOM_MIME_TYPE_OCTET_STREAM; + + mime_body_part = axiom_mime_body_part_create(env); + if(!mime_body_part) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "MIME body part creation failed"); + return NULL; + } + + /* Take the data_handler which is set by the sending applocation. */ + + data_handler = axiom_text_get_data_handler(text, env); + + if(data_handler) + { + content_type = axiom_data_handler_get_content_type(data_handler, env); + } + + AXIOM_MIME_BODY_PART_SET_DATA_HANDLER(mime_body_part, env, data_handler); + content_id = (axis2_char_t *)"<"; + content_id = axutil_stracat(env, content_id, axiom_text_get_content_id(text, env)); + temp_content_id = axutil_stracat(env, content_id, ">"); + + AXIS2_FREE(env->allocator, content_id); + content_id = temp_content_id; + + /* Adding the content-id */ + AXIOM_MIME_BODY_PART_ADD_HEADER(mime_body_part, env, AXIOM_MIME_HEADER_CONTENT_ID, content_id); + + /* Adding the content-type */ + AXIOM_MIME_BODY_PART_ADD_HEADER(mime_body_part, env, AXIOM_MIME_HEADER_CONTENT_TYPE, + axutil_strdup(env, content_type)); + + /* Adding the content-transfer encoding */ + AXIOM_MIME_BODY_PART_ADD_HEADER(mime_body_part, env, + AXIOM_MIME_HEADER_CONTENT_TRANSFER_ENCODING, axutil_strdup(env, + AXIOM_MIME_CONTENT_TRANSFER_ENCODING_BINARY)); + + return mime_body_part; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_body_part_free( + axiom_mime_body_part_t *mime_body_part, + const axutil_env_t *env) +{ + if(mime_body_part->header_map) + { + axutil_hash_index_t *hash_index = NULL; + const void *key = NULL; + void *value = NULL; + for(hash_index = axutil_hash_first(mime_body_part->header_map, env); hash_index; hash_index + = axutil_hash_next(env, hash_index)) + { + axutil_hash_this(hash_index, &key, NULL, &value); + if(value) + { + AXIS2_FREE(env->allocator, value); + } + } + + axutil_hash_free(mime_body_part->header_map, env); + mime_body_part->header_map = NULL; + } + + if(mime_body_part) + { + AXIS2_FREE(env->allocator, mime_body_part); + } + + return; +} + +/* This method will add a mime_header to the hash */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_mime_body_part_add_header( + axiom_mime_body_part_t *mime_body_part, + const axutil_env_t *env, + const axis2_char_t *name, + const axis2_char_t *value) +{ + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + + if(!mime_body_part->header_map) + { + return AXIS2_FAILURE; + } + axutil_hash_set(mime_body_part->header_map, name, AXIS2_HASH_KEY_STRING, value); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_mime_body_part_set_data_handler( + axiom_mime_body_part_t *mime_body_part, + const axutil_env_t *env, + axiom_data_handler_t *data_handler) +{ + mime_body_part->data_handler = data_handler; + return AXIS2_SUCCESS; +} + +/* This method will fill the array_list with binary and binary_beader information. + * If the binary is in a file this will not load the file to the memory. Because + * that will cause performance degradation when the file size is large. Instead + * this will add file information to the list so that when writing the message + * through transport_sender it can send the file by chunk. + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_mime_body_part_write_to_list( + axiom_mime_body_part_t *mime_body_part, + const axutil_env_t *env, + axutil_array_list_t *list) +{ + axutil_hash_index_t *hash_index = NULL; + const void *key = NULL; + void *value = NULL; + axis2_char_t *header_str = NULL; + axis2_char_t *temp_header_str = NULL; + int header_str_size = 0; + axis2_status_t status = AXIS2_FAILURE; + axiom_mime_part_t *mime_header_part = NULL; + + /* We have the mime headers in the hash with thier keys + * So first concatenate them to a one string */ + + for(hash_index = axutil_hash_first(mime_body_part->header_map, env); hash_index; hash_index + = axutil_hash_next(env, hash_index)) + { + axutil_hash_this(hash_index, &key, NULL, &value); + if(key && value) + { + /* First conactenate to the already conacatenated stuff */ + + temp_header_str = axutil_stracat(env, header_str, (axis2_char_t *)key); + if(header_str) + { + AXIS2_FREE(env->allocator, header_str); + } + header_str = temp_header_str; + temp_header_str = axutil_stracat(env, header_str, ": "); + AXIS2_FREE(env->allocator, header_str); + header_str = temp_header_str; + + /* Add the new stuff */ + temp_header_str = axutil_stracat(env, header_str, (axis2_char_t *)value); + AXIS2_FREE(env->allocator, header_str); + header_str = temp_header_str; + + /* Next header will be in a new line. So lets add it */ + + temp_header_str = axutil_stracat(env, header_str, AXIS2_CRLF); + AXIS2_FREE(env->allocator, header_str); + header_str = temp_header_str; + } + } + + /* If there is a data handler that's mean there is an attachment. Attachment + * will always start after an additional new line . So let's add it .*/ + + if(mime_body_part->data_handler) + { + temp_header_str = axutil_stracat(env, header_str, AXIS2_CRLF); + AXIS2_FREE(env->allocator, header_str); + header_str = temp_header_str; + } + + if(header_str) + { + header_str_size = axutil_strlen(header_str); + } + + /* Now we have the complete mime_headers string for a particular mime part. + * First wrap it as a mime_part_t .Then add it to the array list so + * later through the transport this can be written to the wire. */ + + mime_header_part = axiom_mime_part_create(env); + + if(mime_header_part) + { + mime_header_part->part = (axis2_byte_t *)header_str; + mime_header_part->part_size = header_str_size; + mime_header_part->type = AXIOM_MIME_PART_BUFFER; + } + else + { + return AXIS2_FAILURE; + } + + axutil_array_list_add(list, env, mime_header_part); + + /* Then if the data_handler is there let's add the binary data, may be + * buffer , may be file name and information. + */ + + if(mime_body_part->data_handler) + { + status = axiom_data_handler_add_binary_data(mime_body_part->data_handler, env, list); + if(status != AXIS2_SUCCESS) + { + return status; + } + } + return AXIS2_SUCCESS; +} diff --git a/axiom/src/attachments/mime_parser.c b/axiom/src/attachments/mime_parser.c new file mode 100644 index 0000000..f36286c --- /dev/null +++ b/axiom/src/attachments/mime_parser.c @@ -0,0 +1,2304 @@ +/* + * 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_mime_parser.h> +#include <axutil_string.h> +#include <axiom_data_handler.h> +#include <stdio.h> +#include <ctype.h> +#include <axutil_http_chunked_stream.h> +#include <axiom_mtom_caching_callback.h> +#include <axutil_class_loader.h> +#include <axutil_url.h> + +struct axiom_mime_parser +{ + /* This will keep the attachment and its info*/ + axutil_hash_t *mime_parts_map; + + /* This is the actual SOAP part len */ + size_t soap_body_len; + + /* The SOAP part of the message */ + axis2_char_t *soap_body_str; + + /* The size of the buffer we give to the callback to + * read data */ + size_t buffer_size; + + /* The number of buffers */ + int max_buffers; + + /* The attachment dir name, in the case of caching */ + axis2_char_t *attachment_dir; + + /*A pointer to the caching callback */ + axiom_mtom_caching_callback_t *mtom_caching_callback; + + /* The caching callback name specified */ + axis2_char_t *callback_name; + + axis2_char_t **buf_array; + + size_t *len_array; + + int current_buf_num; + + axis2_bool_t end_of_mime; + + axis2_char_t *mime_boundary; + +}; + +struct axiom_search_info +{ + /*String need to be searched*/ + const axis2_char_t *search_str; + + /*The buffers and the lengths need to be searched*/ + axis2_char_t *buffer1; + size_t len1; + axis2_char_t *buffer2; + size_t len2; + + /*Flag to keep what type of search is this buffer has done*/ + axis2_bool_t primary_search; + + /*The offset where we found the pattern entirely in one buffer*/ + size_t match_len1; + + /*when pattern contains in two buffers the length of partial pattern + in buffer2 */ + size_t match_len2; + + /*Whether we need caching or not*/ + axis2_bool_t cached; + + /*A pointer to a user provided storage to which we cache the attachment*/ + void *handler; + + /* Size of the binary when writing to the buffer*/ + size_t binary_size; +}; + +typedef struct axiom_search_info axiom_search_info_t; + +#define AXIOM_MIME_PARSER_CONTENT_ID "content-id" +#define AXIOM_MIME_PARSER_CONTENT_TYPE "content-type" + +#define AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT 100 + +static axis2_char_t * +axiom_mime_parser_search_for_soap( + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + int *buf_num, + size_t *len_array, + axis2_char_t **buf_array, + axiom_search_info_t *search_info, + size_t size, + axis2_char_t *mime_boundary, + axiom_mime_parser_t *mime_parser); + +static axis2_char_t * +axiom_mime_parser_search_for_crlf( + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + int *buf_num, + size_t *len_array, + axis2_char_t **buf_array, + axiom_search_info_t *search_info, + size_t size, + axiom_mime_parser_t *mime_parser); + +static size_t +axiom_mime_parser_calculate_part_len( + const axutil_env_t *env, + int buf_num, + size_t *len_list, + int maker, + axis2_char_t *pos, + axis2_char_t *buf); + +static axis2_char_t * +axiom_mime_parser_create_part( + const axutil_env_t *env, + size_t part_len, + int buf_num, + size_t *len_list, + int marker, + axis2_char_t *pos, + axis2_char_t **buf_list, + axiom_mime_parser_t *mime_parser); + +static axis2_char_t * +axiom_mime_parser_search_string( + axiom_search_info_t *search_info, + const axutil_env_t *env); + +static axis2_char_t * +axiom_mime_parser_search_for_attachment( + axiom_mime_parser_t *mime_parser, + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + int *buf_num, + size_t *len_array, + axis2_char_t **buf_array, + axiom_search_info_t *search_info, + size_t size, + axis2_char_t *mime_boundary, + axis2_char_t *mime_id, + void *user_param); + +static axis2_status_t +axiom_mime_parser_store_attachment( + const axutil_env_t *env, + axiom_mime_parser_t *mime_parser, + axis2_char_t *mime_id, + axis2_char_t *mime_type, + axis2_char_t *mime_binary, + size_t mime_binary_len, + axis2_bool_t cached); + +static void +axiom_mime_parser_clear_buffers( + const axutil_env_t *env, + axis2_char_t **buf_list, + int free_from, + int free_to); + +static axis2_status_t +axiom_mime_parser_cache_to_buffer( + const axutil_env_t *env, + axis2_char_t *buf, + size_t buf_len, + axiom_search_info_t *search_info, + axiom_mime_parser_t *mime_parser); + +static axis2_bool_t +axiom_mime_parser_is_more_data( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_callback_info_t *callback_info); + +static axis2_char_t * +axiom_mime_parser_process_mime_headers( + const axutil_env_t *env, + axiom_mime_parser_t *mime_parser, + axis2_char_t **mime_id, + axis2_char_t *mime_headers); + +static axis2_status_t +axiom_mime_parser_cache_to_file( + const axutil_env_t* env, + axis2_char_t *buf, + size_t buf_len, + void *handler); + +static void* +axiom_mime_parser_initiate_callback( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_char_t *mime_id, + void *user_param); + +AXIS2_EXTERN axiom_mime_parser_t *AXIS2_CALL +axiom_mime_parser_create( + const axutil_env_t * env) +{ + axiom_mime_parser_t *mime_parser = NULL; + + AXIS2_ENV_CHECK(env, NULL); + mime_parser = (axiom_mime_parser_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_mime_parser_t)); + + if(!mime_parser) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + mime_parser->mime_parts_map = NULL; + mime_parser->soap_body_len = 0; + mime_parser->soap_body_str = NULL; /* shallow copy */ + mime_parser->buffer_size = 1; + mime_parser->max_buffers = AXIOM_MIME_PARSER_MAX_BUFFERS; + mime_parser->attachment_dir = NULL; + mime_parser->mtom_caching_callback = NULL; + mime_parser->callback_name = NULL; + mime_parser->buf_array = NULL; + mime_parser->len_array = NULL; + mime_parser->current_buf_num = 0; + mime_parser->end_of_mime = AXIS2_FALSE; + mime_parser->mime_boundary = NULL; + + mime_parser->mime_parts_map = axutil_hash_make(env); + if(!(mime_parser->mime_parts_map)) + { + axiom_mime_parser_free(mime_parser, env); + return NULL; + } + + return mime_parser; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_parser_free( + axiom_mime_parser_t * mime_parser, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + /* The map is passed on to SOAP builder, and SOAP builder take over the + ownership of the map */ + + /* We will unload the callback at the end */ + + if(mime_parser->mtom_caching_callback) + { + axutil_param_t *param = NULL; + param = mime_parser->mtom_caching_callback->param; + + AXIOM_MTOM_CACHING_CALLBACK_FREE(mime_parser->mtom_caching_callback, env); + mime_parser->mtom_caching_callback = NULL; + + if(param) + { + axutil_param_free(param, env); + param = NULL; + } + } + + if(mime_parser->buf_array) + { + AXIS2_FREE(env->allocator, mime_parser->buf_array); + mime_parser->buf_array = NULL; + } + + if(mime_parser->len_array) + { + AXIS2_FREE(env->allocator, mime_parser->len_array); + mime_parser->len_array = NULL; + } + + if(mime_parser) + { + AXIS2_FREE(env->allocator, mime_parser); + } + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_mime_parser_parse_for_soap( + axiom_mime_parser_t * mime_parser, + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + axis2_char_t * mime_boundary) +{ + size_t size = 0; + axis2_char_t *soap_str = NULL; + size_t soap_len = 0; + size_t temp_mime_boundary_size = 0; + axis2_char_t *temp_mime_boundary = NULL; + axis2_char_t **buf_array = NULL; + size_t *len_array = NULL; + int buf_num = 0; + axis2_char_t *pos = NULL; + axiom_search_info_t *search_info = NULL; + int part_start = 0; + axis2_bool_t end_of_mime = AXIS2_FALSE; + size_t len = 0; + axis2_char_t *buffer = NULL; + size_t malloc_len = 0; + axis2_callback_info_t *callback_info = NULL; + + callback_info = (axis2_callback_info_t *)callback_ctx; + + /* The user will specify the mime_parser->buffer_size */ + + size = AXIOM_MIME_PARSER_BUFFER_SIZE * (mime_parser->buffer_size); + + /*An array to keep the set of buffers*/ + + buf_array = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t *) * (mime_parser->max_buffers)); + + if(!buf_array) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Failed in creating buffer array"); + return AXIS2_FAILURE; + } + + /*Keeps the corresponding lengths of buffers in buf_array*/ + + len_array = AXIS2_MALLOC(env->allocator, sizeof(size_t) * (mime_parser->max_buffers)); + + if(!len_array) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Failed in creating length array"); + return AXIS2_FAILURE; + } + + mime_parser->buf_array = buf_array; + mime_parser->len_array = len_array; + + temp_mime_boundary = axutil_stracat(env, "--", mime_boundary); + temp_mime_boundary_size = strlen(mime_boundary) + 2; + + /*This struct keeps the pre-post search informations*/ + search_info = AXIS2_MALLOC(env->allocator, sizeof(axiom_search_info_t)); + + /* The first buffer is created */ + buf_array[buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + /* The buffer is filled from the callback */ + + if(buf_array[buf_num]) + { + len = callback(buf_array[buf_num], (int)size, (void *)callback_ctx); + } + if(len > 0) + { + len_array[buf_num] = len; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error reading from the stream"); + return AXIS2_FAILURE; + } + + /*starting buffer for the current search*/ + part_start = buf_num; + + /*We are passing the address of the buf_num , beacause that value + is changing inside the method.*/ + + /* Following call to the method will search first \r\n\r\n */ + + pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num, len_array, + buf_array, search_info, size, mime_parser); + + if(!pos) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in the message."); + return AXIS2_FAILURE; + } + + /* The patteren contains in one buffer */ + + if((search_info->match_len2 == 0)) + { + /*Readjusting the buffers for the next search and discarding the prevoius + buffers*/ + + /* We need the remaining part in the buffer after the \r\n\r\n*/ + + malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4; + if(malloc_len < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing."); + return AXIS2_FAILURE; + } + else + { + /* Here we will create a new buffer of predefined size fill the + * first portion from the remaining part after previous search + * and then fill the remaining from the callback */ + + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(malloc_len > 0) + { + memcpy(buffer, pos + 4, malloc_len); + } + + /* Here we need to check for more data, because if the message is too small + * comapred to the reading size there may be no data in the stream , instead + * all the remaining data may be in the buffer.And if there are no more data + * we will set the len to be 0. Otherwise len_array will contain wrong lenghts. + */ + + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + /* There is more data so fill the remaining from the stream*/ + + len = callback(buffer + malloc_len, (int)(size - malloc_len), (void *)callback_ctx); + } + else + { + len = 0; + } + + /* We do not need the data in the previous buffers once we found a particular + * string and after worked with those buffers */ + + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + + /* Adding the new buffer to the buffer list */ + + if(len >= 0) + { + buf_array[buf_num] = buffer; + len_array[buf_num] = malloc_len + len; + } + } + } + + /*The pattern divides among two buffers*/ + + else if(search_info->match_len2 > 0) + { + malloc_len = len_array[buf_num] - search_info->match_len2; + if(malloc_len < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing."); + return AXIS2_FAILURE; + } + else + { + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + /* Here the buf_num is the second buffer. We will copy the remaining data + * after the partial string in the second buffer */ + + if(malloc_len > 0) + { + memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len); + } + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len, (int)(size - malloc_len), (void *)callback_ctx); + } + else + { + len = 0; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + if(len >= 0) + { + buf_array[buf_num] = buffer; + len_array[buf_num] = malloc_len + len; + } + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing."); + return AXIS2_FAILURE; + } + + /*Resetting the previous search data and getting ready + for the next search */ + + part_start = buf_num; + pos = NULL; + malloc_len = 0; + + search_info->match_len1 = 0; + search_info->match_len2 = 0; + + /*In order to extract the soap envelope we need to search for the first + --MIMEBOUNDARY */ + + pos = axiom_mime_parser_search_for_soap(env, callback, callback_ctx, &buf_num, len_array, + buf_array, search_info, size, temp_mime_boundary, mime_parser); + + if(!pos) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error while searching for the SOAP part "); + return AXIS2_FAILURE; + } + + if(search_info->match_len2 == 0) + { + /*Calculating the length of the SOAP str*/ + + soap_len = axiom_mime_parser_calculate_part_len(env, buf_num, len_array, part_start, pos, + buf_array[buf_num]); + if(soap_len > 0) + { + /* Get the SOAP string from the starting and end buffers containing + * the SOAP part */ + + soap_str = axiom_mime_parser_create_part(env, soap_len, buf_num, len_array, part_start, + pos, buf_array, mime_parser); + if(!soap_str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error while creating the SOAP part from the message "); + return AXIS2_FAILURE; + } + + malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size; + if(malloc_len < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime."); + return AXIS2_FAILURE; + } + else + { + /* This will fill the new buffer with remaining data after the + * SOAP */ + + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + memset(buffer, 0, size + 1); + if(malloc_len > 0) + { + memcpy(buffer, pos + temp_mime_boundary_size, malloc_len); + } + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx); + } + else + { + len = 0; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + if(len >= 0) + { + buf_array[buf_num] = buffer; + len_array[buf_num] = malloc_len + len; + } + } + } + else + { + return AXIS2_FAILURE; + } + } + + /* This is the condition where the --MIMEBOUNDARY is divided among two + * buffers */ + + else if(search_info->match_len2 > 0) + { + soap_len = axiom_mime_parser_calculate_part_len(env, buf_num - 1, len_array, part_start, + pos, buf_array[buf_num - 1]); + + if(soap_len > 0) + { + /* Here we pass buf_num-1 because buf_num does not have any thing we want to + * for this particular part. It begins with the latter part of the search string */ + + soap_str = axiom_mime_parser_create_part(env, soap_len, buf_num - 1, len_array, + part_start, pos, buf_array, mime_parser); + if(!soap_str) + { + return AXIS2_FAILURE; + } + + malloc_len = len_array[buf_num] - search_info->match_len2; + if(malloc_len < 0) + { + return AXIS2_FAILURE; + } + else + { + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(malloc_len > 0) + { + memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len); + } + + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx); + } + else + { + len = 0; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + if(len >= 0) + { + buf_array[buf_num] = buffer; + len_array[buf_num] = malloc_len + len; + } + } + } + else + { + return AXIS2_FAILURE; + } + } + + mime_parser->soap_body_str = soap_str; + mime_parser->soap_body_len = soap_len; + mime_parser->current_buf_num = buf_num; + + /* There are multipart/related messages which does not contain attachments + * The only mime_part is the soap envelope. So for those messages the mime + * boundary after the soap will end up with -- + * So we will check that here and if we found then the logic inside the + * while loop will not be executed */ + + end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num])) && (AXIOM_MIME_BOUNDARY_BYTE + == *(buf_array[buf_num] + 1)); + if(end_of_mime) + { + AXIS2_FREE(env->allocator, buf_array[buf_num]); + buf_array[buf_num] = NULL; + } + + if(temp_mime_boundary) + { + AXIS2_FREE(env->allocator, temp_mime_boundary); + temp_mime_boundary = NULL; + } + + if(search_info) + { + AXIS2_FREE(env->allocator, search_info); + search_info = NULL; + } + + mime_parser->end_of_mime = end_of_mime; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_mime_parser_parse_for_attachments( + axiom_mime_parser_t * mime_parser, + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + axis2_char_t * mime_boundary, + void *user_param) +{ + int count = 0; + axiom_search_info_t *search_info = NULL; + axis2_char_t *pos = NULL; + int part_start = 0; + axis2_char_t **buf_array = NULL; + size_t *len_array = NULL; + int buf_num = 0; + size_t size = 0; + size_t malloc_len = 0; + axis2_callback_info_t *callback_info = NULL; + axis2_char_t *temp_mime_boundary = NULL; + size_t temp_mime_boundary_size = 0; + axis2_bool_t end_of_mime = AXIS2_FALSE; + + callback_info = (axis2_callback_info_t *)callback_ctx; + + search_info = AXIS2_MALLOC(env->allocator, sizeof(axiom_search_info_t)); + + size = AXIOM_MIME_PARSER_BUFFER_SIZE * (mime_parser->buffer_size); + + buf_array = mime_parser->buf_array; + len_array = mime_parser->len_array; + buf_num = mime_parser->current_buf_num; + + /*<SOAP></SOAP>--MIMEBOUNDARY + mime_headr1:....... + mime_headr2:.... + + Binarstart................. + ...............--MIMEBOUNDARY + */ + + /* This loop will extract all the attachments in the message. The condition + * with the count is needed because if the sender not marked the end of the + * attachment wiht -- then this loop may run infinitely. To prevent that + * this additional condition has been put */ + + temp_mime_boundary = axutil_stracat(env, "--", mime_boundary); + temp_mime_boundary_size = strlen(mime_boundary) + 2; + + while((!(mime_parser->end_of_mime)) && count < AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT) + { + /*First we will search for \r\n\r\n*/ + axis2_char_t *mime_id = NULL; + axis2_char_t *mime_type = NULL; + size_t mime_headers_len = 0; + size_t mime_binary_len = 0; + axis2_char_t *mime_binary = NULL; + axis2_char_t *mime_headers = NULL; + axis2_char_t *buffer = NULL; + int len = 0; + axis2_status_t status = AXIS2_FAILURE; + + search_info->match_len1 = 0; + search_info->match_len2 = 0; + pos = NULL; + part_start = buf_num; + + malloc_len = 0; + + count++; + + pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num, len_array, + buf_array, search_info, size, mime_parser); + + if(!pos) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime."); + return NULL; + } + + /*The pattern contains in one buffer*/ + if(search_info->match_len2 == 0) + { + /*We found it . so lets seperates the details of this binary into + mime headers.*/ + + mime_headers_len = axiom_mime_parser_calculate_part_len(env, buf_num, len_array, + part_start, pos, buf_array[buf_num]); + if(mime_headers_len > 0) + { + mime_headers = axiom_mime_parser_create_part(env, mime_headers_len, buf_num, + len_array, part_start, pos, buf_array, mime_parser); + + if(!mime_headers) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime headers."); + return NULL; + } + malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4; + + /*This should be > 0 , > 0 means there is some part to copy = 0 means + there is nothing to copy*/ + if(malloc_len < 0) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime headers"); + return NULL; + } + + else + { + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(malloc_len > 0) + { + memcpy(buffer, pos + 4, malloc_len); + } + + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx); + } + else + { + len = 0; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + if(len >= 0) + { + buf_array[buf_num] = buffer; + len_array[buf_num] = malloc_len + len; + } + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error in parsing for mime headers."); + return NULL; + } + } + + else if(search_info->match_len2 > 0) + { + /*Now we extract the mime headers */ + + mime_headers_len = axiom_mime_parser_calculate_part_len(env, buf_num - 1, len_array, + part_start, pos, buf_array[buf_num - 1]); + + if(mime_headers_len > 0) + { + mime_headers = axiom_mime_parser_create_part(env, mime_headers_len, buf_num - 1, + len_array, part_start, pos, buf_array, mime_parser); + if(!mime_headers) + { + return NULL; + } + + malloc_len = len_array[buf_num] - search_info->match_len2; + if(malloc_len < 0) + { + return NULL; + } + else + { + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(malloc_len > 0) + { + memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len); + } + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len,(int)(size - malloc_len),(void*)callback_ctx); + } + else + { + len = 0; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + if(len >= 0) + { + buf_array[buf_num] = buffer; + len_array[buf_num] = malloc_len + len; + } + } + } + else + { + return NULL; + } + } + else + { + return NULL; + } + + pos = NULL; + + search_info->match_len1 = 0; + search_info->match_len2 = 0; + + part_start = buf_num; + malloc_len = 0; + + mime_type + = axiom_mime_parser_process_mime_headers(env, mime_parser, &mime_id, mime_headers); + + if(!mime_id) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Error in parsing for mime headers.Mime id did not find"); + return NULL; + } + + if(!mime_type) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Mime type did not find"); + } + + /*We extract the mime headers. So lets search for the attachment.*/ + + pos = axiom_mime_parser_search_for_attachment(mime_parser, env, callback, callback_ctx, + &buf_num, len_array, buf_array, search_info, size, temp_mime_boundary, mime_id, + user_param); + + if(pos) + { + /*If it is small we are not caching. Hence the attachment + is in memory. So store it in a buffer. */ + + if(!search_info->cached) + { + if(search_info->match_len2 == 0) + { + /* mime_binary contains the attachment when it does not + * cached */ + + mime_binary_len = axiom_mime_parser_calculate_part_len(env, buf_num, len_array, + part_start, pos, buf_array[buf_num]); + if(mime_binary_len > 0) + { + mime_binary = axiom_mime_parser_create_part(env, mime_binary_len, buf_num, + len_array, part_start, pos, buf_array, mime_parser); + if(!mime_binary) + { + return NULL; + } + } + else + { + return NULL; + } + } + + else if(search_info->match_len2 > 0) + { + mime_binary_len = axiom_mime_parser_calculate_part_len(env, buf_num - 1, + len_array, part_start, pos, buf_array[buf_num - 1]); + + if(mime_binary_len > 0) + { + mime_binary = axiom_mime_parser_create_part(env, mime_binary_len, buf_num + - 1, len_array, part_start, pos, buf_array, mime_parser); + if(!mime_binary) + { + return NULL; + } + } + else + { + return NULL; + } + } + } + + /* The functionality below is common when it is cached or not. It deals with remaining + * after a particualr attachment, Those may be related to a end of mime_boundary or + * another attachment */ + + if(search_info->match_len2 == 0) + { + malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size; + if(malloc_len < 0) + { + return NULL; + } + else + { + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(malloc_len > 0) + { + memcpy(buffer, pos + temp_mime_boundary_size, malloc_len); + } + + /*When the last buffer only containing -- we know this is the end + of the attachments. Hence we don't need to read again*/ + + if(malloc_len != 2) + { + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len,(int)(size - malloc_len),(void*)callback_ctx); + } + else + { + len = 0; + } + if(len >= 0) + { + len_array[buf_num] = malloc_len + len; + } + } + + /* This means there is another attachment */ + else + { + len_array[buf_num] = malloc_len; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + buf_array[buf_num] = buffer; + } + } + else if(search_info->match_len2 > 0) + { + malloc_len = len_array[buf_num] - search_info->match_len2; + + if(malloc_len < 0) + { + return NULL; + } + else + { + buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(malloc_len > 0) + { + memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len); + } + if(malloc_len != 2) + { + if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info)) + { + len = callback(buffer + malloc_len,(int)(size - malloc_len),(void *)callback_ctx); + } + else + { + len = 0; + } + if(len >= 0) + { + len_array[buf_num] = malloc_len + len; + } + } + else + { + len_array[buf_num] = malloc_len; + } + axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num); + buf_array[buf_num] = buffer; + } + } + } + else + { + return NULL; + } + + /*We have the attachment now either cached or not. So lets put it in the mime_parts + * hash map with the mime_id. Remember at this moment we have already processed the + * mime_headers and mime_id is already there */ + + /* In the case user has not specified the callback or the attachment dir . So we cached it to a memory + * buffer. Hence the data_handler type we need to create is different */ + + if((search_info->cached) && (!mime_parser->attachment_dir) && (!mime_parser->callback_name)) + { + mime_binary = (axis2_char_t *)search_info->handler; + mime_binary_len = search_info->binary_size; + } + + /* Storing the attachment in the hash map with the id*/ + + status = axiom_mime_parser_store_attachment(env, mime_parser, mime_id, mime_type, + mime_binary, mime_binary_len, search_info->cached); + + /*Check wether we encounter --MIMEBOUNDARY-- to find the end of mime*/ + + if(buf_array[buf_num]) + { + /* Here we check for the end of mime */ + + end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num])) + && (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num] + 1)); + if(end_of_mime) + { + AXIS2_FREE(env->allocator, buf_array[buf_num]); + buf_array[buf_num] = NULL; + } + mime_parser->end_of_mime = end_of_mime; + } + + if(mime_headers) + { + AXIS2_FREE(env->allocator, mime_headers); + mime_headers = NULL; + } + + if(status != AXIS2_SUCCESS) + { + return NULL; + } + } + + /*Do the necessary cleaning */ + + /*if (buf_array) + { + AXIS2_FREE(env->allocator, buf_array); + buf_array = NULL; + } + + if (len_array) + { + AXIS2_FREE(env->allocator, len_array); + len_array = NULL; + }*/ + + if(temp_mime_boundary) + { + AXIS2_FREE(env->allocator, temp_mime_boundary); + temp_mime_boundary = NULL; + } + + if(search_info) + { + AXIS2_FREE(env->allocator, search_info); + search_info = NULL; + } + + return mime_parser->mime_parts_map; + +} + +/*This method will search for \r\n\r\n */ + +static axis2_char_t * +axiom_mime_parser_search_for_crlf( + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + int *buf_num, + size_t *len_array, + axis2_char_t **buf_array, + axiom_search_info_t *search_info, + size_t size, + axiom_mime_parser_t *mime_parser) +{ + axis2_char_t *found = NULL; + int len = 0; + + search_info->search_str = "\r\n\r\n"; + search_info->buffer1 = NULL; + search_info->buffer2 = NULL; + search_info->len1 = 0; + search_info->len2 = 0; + search_info->match_len1 = 0; + search_info->match_len2 = 0; + search_info->primary_search = AXIS2_FALSE; + search_info->cached = AXIS2_FALSE; + search_info->handler = NULL; + search_info->binary_size = 0; + + /*First do a search in the first buffer*/ + + if(buf_array[*buf_num]) + { + search_info->buffer1 = buf_array[*buf_num]; + search_info->len1 = len_array[*buf_num]; + found = axiom_mime_parser_search_string(search_info, env); + } + + while(!found) + { + /*Let's read another buffer and do a boundary search in both*/ + + *buf_num = *buf_num + 1; + buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(buf_array[*buf_num]) + { + len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx); + } + if(len > 0) + { + len_array[*buf_num] = len; + search_info->buffer2 = buf_array[*buf_num]; + search_info->len2 = len; + found = axiom_mime_parser_search_string(search_info, env); + } + else + { + break; + } + if(!found) + { + /*Let's do a full search in the second buffer*/ + + search_info->buffer1 = buf_array[*buf_num]; + search_info->len1 = len_array[*buf_num]; + search_info->primary_search = AXIS2_FALSE; + search_info->buffer2 = NULL; + search_info->len2 = 0; + found = axiom_mime_parser_search_string(search_info, env); + } + } + + return found; +} + +/* This method will search for the mime_boundary after the SOAP part + * of the message */ + +static axis2_char_t * +axiom_mime_parser_search_for_soap( + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + int *buf_num, + size_t *len_array, + axis2_char_t **buf_array, + axiom_search_info_t *search_info, + size_t size, + axis2_char_t *mime_boundary, + axiom_mime_parser_t *mime_parser) +{ + axis2_char_t *found = NULL; + int len = 0; + + /* What we need to search is the mime_boundary */ + + search_info->search_str = mime_boundary; + search_info->buffer1 = NULL; + search_info->buffer2 = NULL; + search_info->len1 = 0; + search_info->len2 = 0; + search_info->match_len1 = 0; + search_info->match_len2 = 0; + search_info->primary_search = AXIS2_FALSE; + + if(buf_array[*buf_num]) + { + search_info->buffer1 = buf_array[*buf_num]; + search_info->len1 = len_array[*buf_num]; + found = axiom_mime_parser_search_string(search_info, env); + + /* Inside this search primary_search flag will be set to TRUE */ + } + + while(!found) + { + /* We need to create the second buffer and do the search for the + * mime_boundary in the both the buffers */ + + *buf_num = *buf_num + 1; + buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(buf_array[*buf_num]) + { + len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx); + } + if(len > 0) + { + /* In this search we are matching end part of the first + * buffer and starting part of the previous buffer */ + len_array[*buf_num] = len; + search_info->buffer2 = buf_array[*buf_num]; + search_info->len2 = len; + found = axiom_mime_parser_search_string(search_info, env); + } + else + { + break; + } + if(!found) + { + search_info->buffer1 = buf_array[*buf_num]; + search_info->len1 = len_array[*buf_num]; + search_info->primary_search = AXIS2_FALSE; + search_info->buffer2 = NULL; + search_info->len2 = 0; + found = axiom_mime_parser_search_string(search_info, env); + } + } + + return found; +} + +/*The caching is done in this function. Caching happens when we did not + find the mime_boundary in initial two buffers. So the maximum size + that we are keeping in memory is 2 * size. This size can be configurable from + the aixs.xml. The caching may starts when the search failed with the + second buffer. + In this logic first we will search for a callback to cache. If it is not + there then we will search for a directory to save the file. If it is also + not there then the attachment will be in memory. + */ + +static axis2_char_t * +axiom_mime_parser_search_for_attachment( + axiom_mime_parser_t *mime_parser, + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback, + void *callback_ctx, + int *buf_num, + size_t *len_array, + axis2_char_t **buf_array, + axiom_search_info_t *search_info, + size_t size, + axis2_char_t *mime_boundary, + axis2_char_t *mime_id, + void *user_param) +{ + axis2_char_t *found = NULL; + int len = 0; + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *temp = NULL; + size_t temp_length = 0; + axis2_char_t *file_name = NULL; + + search_info->search_str = mime_boundary; + search_info->buffer1 = NULL; + search_info->buffer2 = NULL; + search_info->len1 = 0; + search_info->len2 = 0; + search_info->match_len1 = 0; + search_info->match_len2 = 0; + search_info->primary_search = AXIS2_FALSE; + search_info->cached = AXIS2_FALSE; + search_info->handler = NULL; + + /*First search in the incoming buffer*/ + + if(buf_array[*buf_num]) + { + search_info->buffer1 = buf_array[*buf_num]; + search_info->len1 = len_array[*buf_num]; + found = axiom_mime_parser_search_string(search_info, env); + } + + while(!found) + { + if(search_info->cached) + { + if(mime_parser->callback_name) + { + if(!(search_info->handler)) + { + /* If the callback is not loaded yet then we load it*/ + if(!mime_parser->mtom_caching_callback) + { + search_info->handler = axiom_mime_parser_initiate_callback(mime_parser, + env, mime_id, user_param); + if(!(search_info->handler)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Caching Callback is not loaded"); + return NULL; + } + } + } + /*So lets cache the previous buffer which has undergone the + full search and the partial search. */ + + if(mime_parser->mtom_caching_callback) + { + /* Caching callback is loaded. So we can cache the previous buffer */ + status + = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback, + env, buf_array[*buf_num - 1], (int)len_array[*buf_num - 1], + search_info->handler); + } + } + + else if(mime_parser->attachment_dir) + { + if(!(search_info->handler)) + { + /* If the File is not opened yet we will open it*/ + + axis2_char_t *encoded_mime_id = NULL; + + /* Some times content-ids urls, hence we need to encode them + * becasue we can't create files with / */ + + encoded_mime_id = AXIS2_MALLOC(env->allocator, (sizeof(axis2_char_t)) + * (strlen(mime_id))); + memset(encoded_mime_id, 0, strlen(mime_id)); + encoded_mime_id = axutil_url_encode(env, encoded_mime_id, mime_id, (int)strlen( + mime_id)); + if(!encoded_mime_id) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Mime Id encoding failed"); + return NULL; + } + + file_name = axutil_stracat(env, mime_parser->attachment_dir, encoded_mime_id); + AXIS2_FREE(env->allocator, encoded_mime_id); + encoded_mime_id = NULL; + + if(!file_name) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Caching file name creation error"); + return NULL; + } + search_info->handler = (void *)fopen(file_name, "ab+"); + if(!(search_info->handler)) + { + return NULL; + } + } + + /*So lets cache the previous buffer which has undergone the + full search and the partial search. */ + + status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1], + len_array[*buf_num - 1], search_info->handler); + } + + else + { + /* Here the user has not specified the caching File location. So we are + * not going to cache. Instead we store the attachment in the buffer */ + status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1], + len_array[*buf_num - 1], search_info, mime_parser); + } + + if(status == AXIS2_FAILURE) + { + return NULL; + } + /*Here we interchange the buffers.*/ + + temp = buf_array[*buf_num - 1]; + buf_array[*buf_num - 1] = buf_array[*buf_num]; + buf_array[*buf_num] = temp; + temp_length = len_array[*buf_num - 1]; + len_array[*buf_num - 1] = len_array[*buf_num]; + len_array[*buf_num] = temp_length; + if(buf_array[*buf_num]) + { + /*The cached buffer is the one which get filled.*/ + len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx); + } + } + + /*Size of the data in memory not yet risen to the caching threasold + *So we can create the second buffer */ + else + { + *buf_num = *buf_num + 1; + buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1)); + + if(buf_array[*buf_num]) + { + len = callback(buf_array[*buf_num], (int)size, (void *)callback_ctx); + } + } + + /*Doing a complete search in newly cretaed buffer*/ + + if(len > 0) + { + len_array[*buf_num] = len; + search_info->buffer2 = buf_array[*buf_num]; + search_info->len2 = len; + found = axiom_mime_parser_search_string(search_info, env); + } + else + { + break; + } + + /* Now there are two buffers. If the searching string is not + * here then we must cache the first buffer */ + + if(!found) + { + /*So now we must start caching*/ + search_info->buffer1 = buf_array[*buf_num]; + search_info->len1 = len_array[*buf_num]; + search_info->primary_search = AXIS2_FALSE; + search_info->buffer2 = NULL; + search_info->len2 = 0; + found = axiom_mime_parser_search_string(search_info, env); + if(!found) + { + /* So at the begining of the next search we start + * that only after caching this data */ + search_info->cached = AXIS2_TRUE; + } + } + } + + /* Here we are out of the loop. If there is no error then this means + * the searching string is found */ + if(search_info->cached && found) + { + /* If the attachment is cached then we need to cache the + * final buffer */ + + if(search_info->match_len2 == 0) + { + /* This is the case where we found the whole string in one buffer + * So we need to cache previous buffer and the data up to the starting + * point of the search string in the current buffer */ + + /* deduct last 2 CRLF character. + * For buffering case, it will be done when creating datahandler.*/ + + if(mime_parser->mtom_caching_callback) + { + status = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback, env, + buf_array[*buf_num - 1], (int)len_array[*buf_num - 1], search_info->handler); + if(status == AXIS2_SUCCESS) + { + status + = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback, + env, buf_array[*buf_num], (int)(found - buf_array[*buf_num] - 2), + search_info->handler); + } + } + + else if(mime_parser->attachment_dir) + { + status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1], + len_array[*buf_num - 1], search_info->handler); + if(status == AXIS2_SUCCESS) + { + status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num], found + - buf_array[*buf_num] - 2, search_info->handler); + } + } + + /* If the callback or a file is not there then the data is appended to the buffer */ + + else + { + status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1], + len_array[*buf_num - 1], search_info, mime_parser); + if(status == AXIS2_SUCCESS) + { + status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num], found + - buf_array[*buf_num], search_info, mime_parser); + } + } + } + else if(search_info->match_len2 > 0) + { + /*Here the curent buffer has partial mime boundary. So we need + to cache only the previous buffer. */ + + if(mime_parser->mtom_caching_callback) + { + status = AXIOM_MTOM_CACHING_CALLBACK_CACHE(mime_parser->mtom_caching_callback, env, + buf_array[*buf_num - 1], (int)(search_info->match_len1 - 2), search_info->handler); + } + + else if(mime_parser->attachment_dir) + { + status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1], + search_info->match_len1 - 2, search_info->handler); + } + else + { + status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1], + search_info->match_len1, search_info, mime_parser); + } + } + else + { + return NULL; + } + + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + + /* Parsing is done so lets close the relative handlers */ + + if(search_info->handler) + { + if(mime_parser->mtom_caching_callback) + { + status = AXIOM_MTOM_CACHING_CALLBACK_CLOSE_HANDLER(mime_parser->mtom_caching_callback, + env, search_info->handler); + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + + else if(mime_parser->attachment_dir) + { + if(fclose((FILE *)(search_info->handler)) == 0) + { + status = AXIS2_SUCCESS; + } + else + { + status = AXIS2_FAILURE; + } + + AXIS2_FREE(env->allocator, file_name); + file_name = NULL; + + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + } + return found; +} + +/*following two functions are used to extract important information + from the buffer list. eg: SOAP, MIME_HEADERS*/ + +/*marker is the starting buffer of the required + part and pos is the end point of that part */ + +static size_t +axiom_mime_parser_calculate_part_len( + const axutil_env_t *env, + int buf_num, + size_t *len_list, + int marker, + axis2_char_t *pos, + axis2_char_t *buf) +{ + size_t part_len = 0; + int i = 0; + + for(i = marker; i < buf_num; i++) + { + part_len += len_list[i]; + } + + part_len = part_len + (pos - buf); + + return part_len; +} + +static axis2_char_t * +axiom_mime_parser_create_part( + const axutil_env_t *env, + size_t part_len, + int buf_num, + size_t *len_list, + int marker, + axis2_char_t *pos, + axis2_char_t **buf_list, + axiom_mime_parser_t *mime_parser) +{ + /*We will copy the set of buffers which contains the required part. + This part can be the SOAP message , mime headers or the mime + binary in the case of none cahced.*/ + + axis2_char_t *part_str = NULL; + int i = 0; + size_t temp = 0; + + part_str = AXIS2_MALLOC(env->allocator, sizeof(char) * (part_len + 1)); + + if(!part_str) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Failed in creating buffer"); + return NULL; + } + + /* Copy from the part starting buffer to the + * curent buffer */ + + for(i = marker; i < buf_num; i++) + { + if(buf_list[i]) + { + memcpy(part_str + temp, buf_list[i], len_list[i]); + temp += len_list[i]; + } + } + /* Finally we are copying from the final portion */ + + memcpy(part_str + temp, buf_list[i], pos - buf_list[i]); + + part_str[part_len] = '\0'; + + return part_str; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_mime_parser_get_mime_parts_map( + axiom_mime_parser_t * mime_parser, + const axutil_env_t * env) +{ + return mime_parser->mime_parts_map; +} + +AXIS2_EXTERN size_t AXIS2_CALL +axiom_mime_parser_get_soap_body_len( + axiom_mime_parser_t * mime_parser, + const axutil_env_t * env) +{ + return mime_parser->soap_body_len; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_mime_parser_get_soap_body_str( + axiom_mime_parser_t * mime_parser, + const axutil_env_t * env) +{ + return mime_parser->soap_body_str; +} + +/*This is the new search function. This will first do a + search for the entire search string.Then will do a search + for the partial string which can be divided among two buffers.*/ + +static axis2_char_t * +axiom_mime_parser_search_string( + axiom_search_info_t *search_info, + const axutil_env_t *env) +{ + axis2_char_t *pos = NULL; + axis2_char_t *old_pos = NULL; + axis2_char_t *found = NULL; + size_t str_length = 0; + size_t search_length = 0; + + str_length = strlen(search_info->search_str); + + /*First lets search the entire buffer*/ + if(!search_info->primary_search) + { + old_pos = search_info->buffer1; + + do + { + /*find the first byte. We need to adhere to this + approach rather than straightaway using strstr + because the buffer1 can be containg binary data*/ + + pos = NULL; + + search_length = search_info->buffer1 + search_info->len1 - old_pos - str_length + 1; + + if(search_length < 0) + { + break; + } + + if(old_pos) + { + pos = memchr(old_pos, *(search_info->search_str), search_length); + } + + /* found it so lets check the remaining */ + + if(pos) + { + found = axutil_strstr(pos, search_info->search_str); + if(found) + { + search_info->match_len1 = found - search_info->buffer1; + break; + } + else + { + old_pos = pos + 1; + } + } + } + while(pos); + } + + search_info->primary_search = AXIS2_TRUE; + + if(found) + { + return found; + } + + /*So we didn't find the string in the buffer + lets check whether it is divided in two buffers*/ + + else + { + size_t offset = 0; + pos = NULL; + old_pos = NULL; + found = NULL; + search_length = 0; + + if(search_info->buffer2) + { + old_pos = search_info->buffer1 + search_info->len1 - str_length + 1; + do + { + /*First check the starting byte*/ + pos = NULL; + found = NULL; + + search_length = search_info->buffer1 + search_info->len1 - old_pos; + + if(search_length < 0) + { + break; + } + + pos = memchr(old_pos, *(search_info->search_str), search_length); + + if(pos) + { + offset = search_info->buffer1 + search_info->len1 - pos; + + /*First match the beginng to offset in buffer1*/ + + if(offset > 0) + { + if(memcmp(pos, search_info->search_str, offset) == 0) + { + found = pos; + } + + /*We found something in buffer1 so lets match the + remaining in buffer2*/ + + if(found) + { + if(memcmp(search_info->buffer2, search_info->search_str + offset, + str_length - offset) == 0) + { + search_info->match_len2 = str_length - offset; + search_info->match_len1 = found - search_info->buffer1; + break; + } + else + { + old_pos = pos + 1; + } + } + else + { + old_pos = pos + 1; + } + } + } + } + while(pos); + + /* We will set this to AXIS2_FALSE so when the next time this + * search method is called it will do a full search first for buffer1 */ + search_info->primary_search = AXIS2_FALSE; + + return found; + } + else + { + return NULL; + } + } +} + +/* This method creates a data_handler out of the attachment + * and store the data_handler in the mime_parts map */ + +static axis2_status_t +axiom_mime_parser_store_attachment( + const axutil_env_t *env, + axiom_mime_parser_t *mime_parser, + axis2_char_t *mime_id, + axis2_char_t *mime_type, + axis2_char_t *mime_binary, + size_t mime_binary_len, + axis2_bool_t cached) +{ + if(mime_parser->mime_parts_map) + { + if(mime_id) + { + axiom_data_handler_t *data_handler = NULL; + + /* Handling the case where attachment is cached using a callback */ + + if(mime_parser->callback_name && cached) + { + data_handler = axiom_data_handler_create(env, NULL, mime_type); + if(data_handler) + { + axiom_data_handler_set_cached(data_handler, env, AXIS2_TRUE); + axiom_data_handler_set_data_handler_type(data_handler, env, + AXIOM_DATA_HANDLER_TYPE_CALLBACK); + } + } + + /* Handling the case where attachment is cached to a file*/ + + else if(mime_parser->attachment_dir && cached) + { + axis2_char_t *attachment_location = NULL; + axis2_char_t *encoded_mime_id = NULL; + + /* Some times content-ids urls, hence we need to encode them + * becasue we can't create files with / */ + + encoded_mime_id = AXIS2_MALLOC(env->allocator, (sizeof(axis2_char_t)) * (strlen( + mime_id))); + memset(encoded_mime_id, 0, strlen(mime_id)); + encoded_mime_id = axutil_url_encode( + env, encoded_mime_id, mime_id, (int)strlen(mime_id)); + if(!encoded_mime_id) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Mime Id encoding failed"); + return AXIS2_FAILURE; + } + + attachment_location = axutil_stracat(env, mime_parser->attachment_dir, + encoded_mime_id); + + AXIS2_FREE(env->allocator, encoded_mime_id); + encoded_mime_id = NULL; + + if(attachment_location) + { + + data_handler = axiom_data_handler_create(env, attachment_location, mime_type); + if(data_handler) + { + axiom_data_handler_set_cached(data_handler, env, AXIS2_TRUE); + + } + AXIS2_FREE(env->allocator, attachment_location); + attachment_location = NULL; + } + } + + /* Attachment is in memory, either it is small to be cached or + * user does not provided the attachment cached directory */ + + else if(mime_binary) + { + data_handler = axiom_data_handler_create(env, NULL, mime_type); + if(data_handler) + { + axiom_data_handler_set_binary_data(data_handler, env, mime_binary, + mime_binary_len - 2); + } + } + axiom_data_handler_set_mime_id(data_handler, env, mime_id); + + axutil_hash_set(mime_parser->mime_parts_map, mime_id, AXIS2_HASH_KEY_STRING, + data_handler); + if(mime_type) + { + AXIS2_FREE(env->allocator, mime_type); + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Mime Id or Mime rype not found"); + return AXIS2_FAILURE; + /*axis2_char_t temp_boundry[1024]; + sprintf(temp_boundry, "--%s--", mime_boundary); + if (body_mime && axutil_strstr(body_mime, temp_boundry)) + { + break; + }*/ + } + return AXIS2_SUCCESS; + } + else + { + return AXIS2_FAILURE; + } +} + +/* This method will process the mime_headers for a particualr + attacment and return the mime_id */ + +static axis2_char_t * +axiom_mime_parser_process_mime_headers( + const axutil_env_t *env, + axiom_mime_parser_t *mime_parser, + axis2_char_t **mime_id, + axis2_char_t *mime_headers) +{ + axis2_char_t *id = NULL; + axis2_char_t *type = NULL; + axis2_char_t *pos = NULL; + + /* Get the MIME ID */ + if(mime_headers) + { + id = axutil_strcasestr(mime_headers, AXIOM_MIME_HEADER_CONTENT_ID); + type = axutil_strcasestr(mime_headers, AXIOM_MIME_HEADER_CONTENT_TYPE); + if(type) + { + axis2_char_t *end = NULL; + axis2_char_t *temp_type = NULL; + type += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_TYPE); + while(type && *type && *type != ':') + { + type++; + } + type++; + while(type && *type && *type == ' ') + { + type++; + } + end = type; + while(end && *end && !isspace((int)*end)) + { + end++; + } + if((end - type) > 0) + { + temp_type = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * ((end - type) + 1)); + if(!temp_type) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Failed in creating Content-Type"); + return NULL; + } + memcpy(temp_type, type, (end - type)); + temp_type[end - type] = '\0'; + type = temp_type; + } + } + if(id) + { + id += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_ID); + while(id && *id && *id != ':') + { + id++; + } + if(id) + { + while(id && *id && *id != '<') + { + id++; + } + id++; + pos = axutil_strstr(id, ">"); + if(pos) + { + int mime_id_len = 0; + mime_id_len = (int)(pos - id); + *mime_id = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * mime_id_len + 1); + /* The MIME ID will be freed by the SOAP builder */ + if(*mime_id) + { + memcpy(*mime_id, id, mime_id_len); + (*mime_id)[mime_id_len] = '\0'; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Failed in creating MIME ID"); + return NULL; + } + } + } + } + else + { + /*axis2_char_t temp_boundry[1024]; + sprintf(temp_boundry, "--%s--", mime_boundary); + if (body_mime && axutil_strstr(body_mime, temp_boundry)) + { + break; + }*/ + return NULL; + } + return type; + } + else + { + return NULL; + } +} + +/*This is used to free some unwanted buffers. For example we did + not want the buffers which contains the data before the soap + envelope starts. */ + +static void +axiom_mime_parser_clear_buffers( + const axutil_env_t *env, + axis2_char_t **buf_list, + int free_from, + int free_to) +{ + int i = 0; + + for(i = free_from; i <= free_to; i++) + { + if(buf_list[i]) + { + AXIS2_FREE(env->allocator, buf_list[i]); + buf_list[i] = NULL; + } + } + return; +} + +/* Instead of caching to a file this method will cache it + * to a buffer */ + +static axis2_status_t +axiom_mime_parser_cache_to_buffer( + const axutil_env_t *env, + axis2_char_t *buf, + size_t buf_len, + axiom_search_info_t *search_info, + axiom_mime_parser_t *mime_parser) +{ + axis2_char_t *data_buffer = NULL; + axis2_char_t *temp_buf = NULL; + size_t mime_binary_len = 0; + + temp_buf = (axis2_char_t *)search_info->handler; + mime_binary_len = search_info->binary_size + buf_len; + + if(mime_binary_len > 0) + { + data_buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (mime_binary_len)); + + if(data_buffer) + { + if(temp_buf && search_info->binary_size > 0) + { + memcpy(data_buffer, temp_buf, search_info->binary_size); + AXIS2_FREE(env->allocator, temp_buf); + temp_buf = NULL; + } + memcpy(data_buffer + (search_info->binary_size), buf, buf_len); + search_info->binary_size = mime_binary_len; + search_info->handler = (void *)data_buffer; + + return AXIS2_SUCCESS; + } + else + { + return AXIS2_FAILURE; + } + } + else + { + return AXIS2_FAILURE; + } +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_parser_set_buffer_size( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + int size) +{ + mime_parser->buffer_size = size; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_parser_set_max_buffers( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + int num) +{ + mime_parser->max_buffers = num; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_parser_set_attachment_dir( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_char_t *attachment_dir) +{ + mime_parser->attachment_dir = attachment_dir; +} + +/* Set the path of the caching callnack to be loaded */ + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_parser_set_caching_callback_name( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_char_t *callback_name) +{ + mime_parser->callback_name = callback_name; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_parser_set_mime_boundary( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_char_t *mime_boundary) +{ + mime_parser->mime_boundary = mime_boundary; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_mime_parser_get_mime_boundary( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env) +{ + return mime_parser->mime_boundary; +} + +/* Load the caching callback dll */ + +static void* +axiom_mime_parser_initiate_callback( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_char_t *mime_id, + void *user_param) +{ + axutil_dll_desc_t *dll_desc = NULL; + axutil_param_t *impl_info_param = NULL; + void *ptr = NULL; + + if(mime_parser->callback_name) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Trying to load module = %s", + mime_parser->callback_name); + dll_desc = axutil_dll_desc_create(env); + axutil_dll_desc_set_name(dll_desc, env, mime_parser->callback_name); + impl_info_param = axutil_param_create(env, NULL, dll_desc); + /*Set the free function*/ + axutil_param_set_value_free(impl_info_param, env, axutil_dll_desc_free_void_arg); + axutil_class_loader_init(env); + ptr = axutil_class_loader_create_dll(env, impl_info_param); + + if(!ptr) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to load the module %s. ERROR", + mime_parser->callback_name); + return NULL; + } + + mime_parser->mtom_caching_callback = (axiom_mtom_caching_callback_t *)ptr; + mime_parser->mtom_caching_callback->param = impl_info_param; + mime_parser->mtom_caching_callback->user_param = user_param; + + return AXIOM_MTOM_CACHING_CALLBACK_INIT_HANDLER(mime_parser->mtom_caching_callback, env, + mime_id); + } + + else + { + return NULL; + } + +} + +/* This method will tell whether there are more data in the + * stream */ + +static axis2_bool_t +axiom_mime_parser_is_more_data( + axiom_mime_parser_t *mime_parser, + const axutil_env_t *env, + axis2_callback_info_t *callback_info) +{ + /* In the case of axutil_http_chunked stream it is the + * end of chunk */ + + if(callback_info->chunked_stream) + { + if(axutil_http_chunked_stream_get_end_of_chunks(callback_info->chunked_stream, env)) + { + return AXIS2_FALSE; + } + else + { + return AXIS2_TRUE; + } + } + + /* When we are using content length or any wrapped + * stream it will be the unread_length */ + + else if(callback_info->unread_len == 0) + { + return AXIS2_FALSE; + } + else + { + return AXIS2_TRUE; + } +} + +static axis2_status_t +axiom_mime_parser_cache_to_file( + const axutil_env_t* env, + axis2_char_t *buf, + size_t buf_len, + void *handler) +{ + size_t len = 0; + FILE *fp = NULL; + + fp = (FILE *)handler; + + len = fwrite(buf, 1, buf_len, fp); + if(len < 0) + { + return AXIS2_FAILURE; + } + else + { + return AXIS2_SUCCESS; + } +} + diff --git a/axiom/src/attachments/mime_part.c b/axiom/src/attachments/mime_part.c new file mode 100644 index 0000000..8343327 --- /dev/null +++ b/axiom/src/attachments/mime_part.c @@ -0,0 +1,535 @@ +/* + * 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_mime_part.h> +#include <axiom_data_handler.h> +#include "axiom_mime_body_part.h" +#include <axutil_string.h> +#include <axiom_text.h> +#include <axiom_mime_const.h> + + +static axis2_status_t +axiom_mime_part_write_body_part_to_list( + const axutil_env_t *env, + axutil_array_list_t *list, + axiom_mime_body_part_t *part, + axis2_char_t *boundary); + +static axis2_status_t +axiom_mime_part_write_mime_boundary( + const axutil_env_t *env, + axutil_array_list_t *list, + axis2_char_t *boundary); + +static axis2_status_t +axiom_mime_part_finish_adding_parts( + const axutil_env_t *env, + axutil_array_list_t *list, + axis2_char_t *boundary); + +/* This method will create a mime_part + * A mime part will encapsulate a buffer + * a file or a callback to load the attachment + which needs to be send */ + +AXIS2_EXTERN axiom_mime_part_t *AXIS2_CALL +axiom_mime_part_create( + const axutil_env_t *env) +{ + axiom_mime_part_t *mime_part = NULL; + mime_part = AXIS2_MALLOC(env->allocator, sizeof(axiom_mime_part_t)); + + if(mime_part) + { + mime_part->part = NULL; + mime_part->file_name = NULL; + mime_part->part_size = 0; + mime_part->type = AXIOM_MIME_PART_UNKNOWN; + mime_part->user_param = NULL; + + return mime_part; + } + else + { + return NULL; + } +} + +/* Frees the mime_part */ + +AXIS2_EXTERN void AXIS2_CALL +axiom_mime_part_free( + axiom_mime_part_t *mime_part, + const axutil_env_t *env) +{ + if(mime_part) + { + if(mime_part->type == AXIOM_MIME_PART_BUFFER) + { + if(mime_part->part) + { + AXIS2_FREE(env->allocator, mime_part->part); + mime_part->part = NULL; + } + } + else if(mime_part->type == AXIOM_MIME_PART_FILE) + { + if(mime_part->file_name) + { + AXIS2_FREE(env->allocator, mime_part->file_name); + mime_part->file_name = NULL; + } + } + + AXIS2_FREE(env->allocator, mime_part); + mime_part = NULL; + } + return; +} + +/* This method will create a mime_boundary buffer + * and based on the buffer creates a mime_part. + * This will be added to the array_list so later in the trasnport + * this can be put to the wire. */ + +static axis2_status_t +axiom_mime_part_write_mime_boundary( + const axutil_env_t *env, + axutil_array_list_t *list, + axis2_char_t *boundary) +{ + axis2_byte_t *byte_buffer = NULL; + axis2_byte_t *byte_stream = NULL; + int size = 0; + axiom_mime_part_t *boundary_part = NULL; + + boundary_part = axiom_mime_part_create(env); + + byte_buffer = (axis2_byte_t *)boundary; + size = axutil_strlen(boundary); + + byte_stream = AXIS2_MALLOC(env->allocator, (size + 2) * sizeof(axis2_byte_t)); + if(!byte_stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create byte stream"); + return AXIS2_FAILURE; + } + + /* Mime boundary is always in the following form + --MimeBoundary */ + + byte_stream[0] = AXIOM_MIME_BOUNDARY_BYTE; + byte_stream[1] = AXIOM_MIME_BOUNDARY_BYTE; + + memcpy(byte_stream + 2, byte_buffer, size); + + boundary_part->part = byte_stream; + boundary_part->part_size = size + 2; + boundary_part->type = AXIOM_MIME_PART_BUFFER; + + axutil_array_list_add(list, env, boundary_part); + + return AXIS2_SUCCESS; +} + +/* This method will add the attachment file related information + to the list. It will create a mime_part from those information + and add to the list. If there are not data_handlers in the mime_body + then this method just add the headers. */ + +static axis2_status_t +axiom_mime_part_write_body_part_to_list( + const axutil_env_t *env, + axutil_array_list_t *list, + axiom_mime_body_part_t *part, + axis2_char_t *boundary) +{ + axiom_mime_part_t *crlf1 = NULL; + axiom_mime_part_t *crlf2 = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + /* We are adding accoarding to the following format here. + * --MimeBoundary + * mime_header1 + * mime_header2 + * mime_header3 */ + + status = axiom_mime_part_write_mime_boundary(env, list, boundary); + + if(status != AXIS2_SUCCESS) + { + return status; + } + + /* Then we will add the new line charator after + * the mime_boundary */ + + crlf1 = axiom_mime_part_create(env); + + crlf1->part = (axis2_byte_t *)axutil_strdup(env, AXIS2_CRLF); + crlf1->part_size = 2; + crlf1->type = AXIOM_MIME_PART_BUFFER; + + axutil_array_list_add(list, env, crlf1); + + /*This method will fill the list with mime_headers and + *if there is an attachment with attachment details*/ + + axiom_mime_body_part_write_to_list(part, env, list); + + /* Then add the next \r\n after the attachment */ + + crlf2 = axiom_mime_part_create(env); + + crlf2->part = (axis2_byte_t *)axutil_strdup(env, AXIS2_CRLF); + crlf2->part_size = 2; + crlf2->type = AXIOM_MIME_PART_BUFFER; + + axutil_array_list_add(list, env, crlf2); + + return AXIS2_SUCCESS; +} + +/* This methos will add the final mime_boundary + * It is in --MimeBoundary-- format */ + +static axis2_status_t +axiom_mime_part_finish_adding_parts( + const axutil_env_t *env, + axutil_array_list_t *list, + axis2_char_t *boundary) +{ + axis2_byte_t *byte_buffer = NULL; + axis2_byte_t *byte_stream = NULL; + int size = 0; + axiom_mime_part_t *final_part = NULL; + + size = axutil_strlen(boundary); + byte_buffer = (axis2_byte_t *)boundary; + + /* There is -- before and after so the length of the + * actual part is mime_boundary_len + 4 */ + + byte_stream = AXIS2_MALLOC(env->allocator, (size + 4) * sizeof(axis2_byte_t)); + if(!byte_stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create byte stream"); + return AXIS2_FAILURE; + } + + /* Adding the starting -- */ + + byte_stream[0] = AXIOM_MIME_BOUNDARY_BYTE; + byte_stream[1] = AXIOM_MIME_BOUNDARY_BYTE; + if(byte_buffer) + { + memcpy(byte_stream + 2, byte_buffer, size); + } + else + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "Byte buffer not available for writing"); + } + + /* Adding the final -- */ + + byte_stream[size + 2] = AXIOM_MIME_BOUNDARY_BYTE; + byte_stream[size + 3] = AXIOM_MIME_BOUNDARY_BYTE; + + /* Now we add this as an mime_part to + * the list. */ + + final_part = axiom_mime_part_create(env); + + if(!final_part) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create final_part"); + return AXIS2_FAILURE; + } + + final_part->part = byte_stream; + final_part->part_size = size + 4; + final_part->type = AXIOM_MIME_PART_BUFFER; + + axutil_array_list_add(list, env, final_part); + + return AXIS2_SUCCESS; +} + +/* This is the method which creates the content-type string + which is in the HTTP header or in mime_headers*/ + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_mime_part_get_content_type_for_mime( + const axutil_env_t *env, + axis2_char_t *boundary, + axis2_char_t *content_id, + axis2_char_t *char_set_encoding, + const axis2_char_t *soap_content_type) +{ + axis2_char_t *content_type_string = NULL; + axis2_char_t *temp_content_type_string = NULL; + + content_type_string = axutil_strdup(env, AXIOM_MIME_TYPE_MULTIPART_RELATED); + if(!content_type_string) + { + AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "Creation of Content-Type string failed"); + return NULL; + } + temp_content_type_string = axutil_stracat(env, content_type_string, "; "); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + if(boundary) + { + temp_content_type_string = + axutil_stracat(env, content_type_string, + AXIOM_MIME_HEADER_FIELD_BOUNDARY "="); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, boundary); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, "; "); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + } temp_content_type_string = + axutil_stracat(env, content_type_string, + AXIOM_MIME_HEADER_FIELD_TYPE "=\"" AXIOM_MIME_TYPE_XOP_XML "\""); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, "; "); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + if(content_id) + { + temp_content_type_string = + axutil_stracat(env, content_type_string, + AXIOM_MIME_HEADER_FIELD_START "=\"<"); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, content_id); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, ">\""); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, "; "); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + } + if(soap_content_type) + { + temp_content_type_string = + axutil_stracat(env, content_type_string, + AXIOM_MIME_HEADER_FIELD_START_INFO "=\""); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, soap_content_type); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, "\"; "); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + } + if(char_set_encoding) + { + temp_content_type_string = + axutil_stracat(env, content_type_string, + AXIOM_MIME_HEADER_FIELD_CHARSET "=\""); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, char_set_encoding); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + temp_content_type_string = axutil_stracat(env, content_type_string, "\""); + AXIS2_FREE(env->allocator, content_type_string); + content_type_string = temp_content_type_string; + } + + return content_type_string; +} + +/* This method is the core of attachment sending + * part. It will build each and every part and put them in + * an array_list. Instead of a big buffer we pass the array_list + * with small buffers and attachment locations. */ + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axiom_mime_part_create_part_list( + const axutil_env_t *env, + axis2_char_t *soap_body, + axutil_array_list_t *binary_node_list, + axis2_char_t *boundary, + axis2_char_t *content_id, + axis2_char_t *char_set_encoding, + const axis2_char_t *soap_content_type) +{ + axis2_status_t status = AXIS2_FAILURE; + axis2_char_t *header_value = NULL; + axis2_char_t *temp_header_value = NULL; + axis2_char_t *content_id_string = NULL; + axis2_char_t *temp_content_id_string = NULL; + axiom_mime_body_part_t *root_mime_body_part = NULL; + axis2_char_t *soap_body_buffer = NULL; + axutil_array_list_t *part_list = NULL; + axiom_mime_part_t *soap_part = NULL; + + part_list = axutil_array_list_create(env, 0); + + if(!part_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create part list array"); + return NULL; + } + + /* This mime_body part just keeps the mime_headers of the + * SOAP part. Since it is not created from an axiom_text + * this will not contain an attachment*/ + + root_mime_body_part = axiom_mime_body_part_create(env); + + if(!root_mime_body_part) + { + return NULL; + } + + /* In order to understand the following code which creates + * mime_headers go through the code with a sample mtom message */ + + /* Adding Content-Type Header */ + header_value = axutil_strdup(env, AXIOM_MIME_TYPE_XOP_XML + ";" AXIOM_MIME_HEADER_FIELD_CHARSET "="); + temp_header_value = axutil_stracat(env, header_value, char_set_encoding); + AXIS2_FREE(env->allocator, header_value); + header_value = temp_header_value; + temp_header_value = axutil_stracat(env, header_value, ";" + AXIOM_MIME_HEADER_FIELD_TYPE "=\""); + AXIS2_FREE(env->allocator, header_value); + header_value = temp_header_value; + temp_header_value = axutil_stracat(env, header_value, soap_content_type); + AXIS2_FREE(env->allocator, header_value); + header_value = temp_header_value; + temp_header_value = axutil_stracat(env, header_value, "\";"); + AXIS2_FREE(env->allocator, header_value); + header_value = temp_header_value; + AXIOM_MIME_BODY_PART_ADD_HEADER(root_mime_body_part, env, AXIOM_MIME_HEADER_CONTENT_TYPE, + header_value); + + /* Adding Content Transfer Encoding header */ + + AXIOM_MIME_BODY_PART_ADD_HEADER(root_mime_body_part, env, + AXIOM_MIME_HEADER_CONTENT_TRANSFER_ENCODING, axutil_strdup(env, + AXIOM_MIME_CONTENT_TRANSFER_ENCODING_BINARY)); + + /* Adding Content ID header */ + + content_id_string = (axis2_char_t *)"<"; + content_id_string = axutil_stracat(env, content_id_string, content_id); + temp_content_id_string = axutil_stracat(env, content_id_string, ">"); + AXIS2_FREE(env->allocator, content_id_string); + content_id_string = temp_content_id_string; + AXIOM_MIME_BODY_PART_ADD_HEADER(root_mime_body_part, env, AXIOM_MIME_HEADER_CONTENT_ID, + content_id_string); + + /* Now first insert the headers needed for SOAP */ + + /* After calling this method we have mime_headers of the SOAP envelope + * as a mime_part in the array_list */ + + status = axiom_mime_part_write_body_part_to_list(env, part_list, root_mime_body_part, boundary); + + if(status == AXIS2_FAILURE) + { + return NULL; + } + + /* Now add the SOAP body */ + + AXIOM_MIME_BODY_PART_FREE(root_mime_body_part, env); + root_mime_body_part = NULL; + + soap_part = axiom_mime_part_create(env); + + if(!soap_part) + { + return NULL; + } + + /* The atachment's mime_boundary will start after a new line charator */ + + soap_body_buffer = axutil_stracat(env, soap_body, AXIS2_CRLF); + + soap_part->part = (axis2_byte_t *)soap_body_buffer; + soap_part->part_size = (int)axutil_strlen(soap_body_buffer); + soap_part->type = AXIOM_MIME_PART_BUFFER; + + axutil_array_list_add(part_list, env, soap_part); + + /* Now we need to add each binary attachment to the array_list */ + + if(binary_node_list) + { + int j = 0; + for(j = 0; j < axutil_array_list_size(binary_node_list, env); j++) + { + /* Getting each attachment text node from the node list */ + + axiom_text_t *text = (axiom_text_t *)axutil_array_list_get(binary_node_list, env, j); + if(text) + { + axiom_mime_body_part_t *mime_body_part = NULL; + mime_body_part = axiom_mime_body_part_create_from_om_text(env, text); + + /* Let's fill the mime_part arraylist with attachment data*/ + if(!mime_body_part) + { + return NULL; + } + + /* This call will create mime_headers for the attachment and put + * them to the array_list. Then put the attachment file_name to the + * list */ + + status = axiom_mime_part_write_body_part_to_list(env, part_list, mime_body_part, + boundary); + + if(status == AXIS2_FAILURE) + { + return NULL; + } + + AXIOM_MIME_BODY_PART_FREE(mime_body_part, env); + mime_body_part = NULL; + } + } + } + + /* Now we have the SOAP message, all the attachments and headers are added to the list. + * So let's add the final mime_boundary with -- at the end */ + + status = axiom_mime_part_finish_adding_parts(env, part_list, boundary); + if(status == AXIS2_FAILURE) + { + return NULL; + } + return part_list; +} + diff --git a/axiom/src/om/Makefile.am b/axiom/src/om/Makefile.am new file mode 100644 index 0000000..40db6c5 --- /dev/null +++ b/axiom/src/om/Makefile.am @@ -0,0 +1,35 @@ +lib_LTLIBRARIES = libaxis2_axiom.la +libaxis2_axiom_la_SOURCES = om_attribute.c \ + om_document.c \ + om_node.c \ + om_text.c \ + om_data_source.c \ + om_comment.c \ + om_element.c \ + om_output.c \ + om_doctype.c \ + om_namespace.c \ + om_processing_instruction.c \ + om_stax_builder.c \ + om_children_iterator.c \ + om_children_qname_iterator.c \ + om_child_element_iterator.c \ + om_children_with_specific_attribute_iterator.c \ + om_navigator.c + +libaxis2_axiom_la_LIBADD = $(top_builddir)/src/soap/libaxis2_soap.la \ + $(top_builddir)/src/attachments/libaxis2_attachments.la \ + $(top_builddir)/src/util/libaxis2_axiom_util.la \ + ../parser/${WRAPPER_DIR}/libaxis2_parser.la \ + ../../../util/src/libaxutil.la + +libaxis2_axiom_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/parser \ + -I$(top_builddir)/src/om \ + -I$(top_builddir)/src/attachments \ + -I ../../../util/include + +EXTRA_DIST = axiom_namespace_internal.h axiom_node_internal.h axiom_stax_builder_internal.h + diff --git a/axiom/src/om/axiom_namespace_internal.h b/axiom/src/om/axiom_namespace_internal.h new file mode 100644 index 0000000..833de7f --- /dev/null +++ b/axiom/src/om/axiom_namespace_internal.h @@ -0,0 +1,46 @@ + +/* + * 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. + */ + +#ifndef AXIOM_NAMESPACE_INTERNAL_H +#define AXIOM_NAMESPACE_INTERNAL_H + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_namespace.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_namespace_set_uri( + axiom_namespace_t * ns, + const axutil_env_t * env, + const axis2_char_t * ns_uri); + +#ifdef __cplusplus +} +#endif + +#endif /** AXIOM_NAMESPACE_H */ diff --git a/axiom/src/om/axiom_node_internal.h b/axiom/src/om/axiom_node_internal.h new file mode 100644 index 0000000..6e9adb4 --- /dev/null +++ b/axiom/src/om/axiom_node_internal.h @@ -0,0 +1,165 @@ + +/* + * 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. + */ + +#ifndef AXIOM_NODE_INTERNAL_H +#define AXIOM_NODE_INTERNAL_H + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_node.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_node OM Node + * @ingroup axiom + * @{ + */ + struct axiom_document; + struct axiom_stax_builder; + + /** + * Sets a parent node to a given node, if a parent already exist for this node + * then it is detached before seting the parent internal function; + * @param om_node child node to whom a parent to be added. , cannot be NULL. + * @param env Environment. MUST NOT be NULL, . + * @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 + axiom_node_set_parent( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * parent); + + /** + * Sets a node as first child of om_node + * @param om_node om_node + * @param env environment, MUST NOT be NULL. + * @param first_child child to be set as first child + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_first_child( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * first_child); + + /** + * Sets previous sibling + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param prev_sibling + * @return status of the op, AXIS2_SUCCESS on success + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_previous_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * prev_sibling); + + /** + * Sets next sibling + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param last_sibling + * @return status of the op, AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_next_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * next_sibling); + + /** + * Sets node type + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param type type of the node + * @return status code of the op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_node_type( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_types_t type); + + /** + * Sets data element + * @param om_node node struct + * @param env environment, MUST NOT be NULL. + * @param data_element + * @return status code of the op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_data_element( + axiom_node_t * om_node, + const axutil_env_t * env, + void *data_element); + + /** + * Sets the build status , if the node if completety build, this attribute is + * set to AXIS2_TRUE , otherwise AXIS2_FALSE + * @param om_node + * @param env environment, MUST NOT be NULL. + * @param done + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_complete( + axiom_node_t * om_node, + const axutil_env_t * env, + axis2_bool_t done); + + /** + * This functions is only to be used by builder + * do not use this function + */ + 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); + + /** + * Sets the builder + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_node_set_builder( + axiom_node_t * om_node, + const axutil_env_t * env, + struct axiom_stax_builder *builder); + + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** AXIOM_NODE_INTERNAL_H */ diff --git a/axiom/src/om/axiom_stax_builder_internal.h b/axiom/src/om/axiom_stax_builder_internal.h new file mode 100644 index 0000000..788ecf6 --- /dev/null +++ b/axiom/src/om/axiom_stax_builder_internal.h @@ -0,0 +1,75 @@ + +/* + * 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. + */ + +#ifndef AXIOM_STAX_BUILDER_INTERNAL_H +#define AXIOM_STAX_BUILDER_INTERNAL_H + +/** @defgroup axiom AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_stax_builder.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_stax builder + * @ingroup axiom + * @{ + */ + + AXIS2_EXTERN int AXIS2_CALL + axiom_stax_builder_get_current_event( + axiom_stax_builder_t * builder, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_stax_builder_set_lastnode( + axiom_stax_builder_t * builder, + const axutil_env_t * env, + axiom_node_t * om_node); + + AXIS2_EXTERN axiom_node_t *AXIS2_CALL + axiom_stax_builder_get_lastnode( + axiom_stax_builder_t * builder, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_stax_builder_set_element_level( + axiom_stax_builder_t * builder, + const axutil_env_t * env, + int element_level); + + AXIS2_EXTERN int AXIS2_CALL + axiom_stax_builder_get_element_level( + axiom_stax_builder_t * builder, + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** AXIOM_STAX_BUILDER_INTERNAL_H */ diff --git a/axiom/src/om/om_attribute.c b/axiom/src/om/om_attribute.c new file mode 100644 index 0000000..9d2a81e --- /dev/null +++ b/axiom/src/om/om_attribute.c @@ -0,0 +1,433 @@ +/* + * 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_attribute.h> +#include <string.h> +#include <axutil_utils_defines.h> + +struct axiom_attribute +{ + + /** localname of this attribute */ + axutil_string_t *localname; + + /** value of this attribute */ + axutil_string_t *value; + + /** attribute namespace */ + axiom_namespace_t *ns; + + /** store qname here */ + axutil_qname_t *qname; + int ref; +}; + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_attribute_create( + const axutil_env_t * env, + const axis2_char_t * localname, + const axis2_char_t * value, + axiom_namespace_t * ns) +{ + axiom_attribute_t *attribute = NULL; + + AXIS2_ENV_CHECK(env, NULL); + /* localname is mandatory */ + AXIS2_PARAM_CHECK(env->error, localname, NULL); + + attribute = (axiom_attribute_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_attribute_t)); + if(!attribute) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /** initialize fields */ + attribute->localname = NULL; + attribute->value = NULL; + attribute->ns = NULL; + attribute->qname = NULL; + + attribute->localname = axutil_string_create(env, localname); + if(!(attribute->localname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + if(value) + { + attribute->value = axutil_string_create(env, value); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axutil_string_free(attribute->localname, env); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + } + attribute->ns = ns; + + attribute->ref = 0; + + return attribute; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_attribute_free( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + if(--attribute->ref > 0) + { + return; + } + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(attribute->localname) + { + axutil_string_free(attribute->localname, env); + } + if(attribute->value) + { + axutil_string_free(attribute->value, env); + } + if(attribute->qname) + { + axutil_qname_free(attribute->qname, env); + } + + AXIS2_FREE(env->allocator, attribute); + + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_attribute_free_void_arg( + void *attribute, + const axutil_env_t * env) +{ + axiom_attribute_t *om_attribute_l = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_attribute_l = (axiom_attribute_t *)attribute; + axiom_attribute_free(om_attribute_l, env); + return; +} + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axiom_attribute_get_qname( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + axutil_qname_t *qname = NULL; + AXIS2_ENV_CHECK(env, NULL); + if(!(attribute->qname)) + { + if(attribute->ns) + { + qname = axutil_qname_create(env, axutil_string_get_buffer(attribute-> localname, env), + axiom_namespace_get_uri(attribute->ns, env), axiom_namespace_get_prefix( + attribute-> ns, env)); + } + else + { + qname = axutil_qname_create(env, axutil_string_get_buffer(attribute-> localname, env), + NULL, NULL); + } + attribute->qname = qname; + return qname; + } + return attribute->qname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_serialize( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(attribute->ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(attribute->ns, env); + prefix = axiom_namespace_get_prefix(attribute->ns, env); + + if((uri) && (NULL != prefix) && (axutil_strcmp(prefix, "") != 0)) + { + status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 4, + axutil_string_get_buffer(attribute-> localname, env), axutil_string_get_buffer( + attribute-> value, env), uri, prefix); + } + else if(uri) + { + status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 3, + axutil_string_get_buffer(attribute-> localname, env), axutil_string_get_buffer( + attribute-> value, env), uri); + } + } + else + { + status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 2, axutil_string_get_buffer( + attribute-> localname, env), axutil_string_get_buffer(attribute->value, env)); + } + return status; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_attribute_get_localname( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + if(attribute->localname) + { + return (axis2_char_t *)axutil_string_get_buffer(attribute->localname, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_attribute_get_value( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + if(attribute->value) + { + return (axis2_char_t *)axutil_string_get_buffer(attribute->value, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_attribute_get_namespace( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return attribute->ns; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_localname( + axiom_attribute_t * attribute, + const axutil_env_t * env, + const axis2_char_t * localname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + + if(attribute->localname) + { + axutil_string_free(attribute->localname, env); + attribute->localname = NULL; + } + + attribute->localname = axutil_string_create(env, localname); + + if(!(attribute->localname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_value( + axiom_attribute_t * attribute, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + if(attribute->value) + { + axutil_string_free(attribute->value, env); + attribute->value = NULL; + } + + attribute->value = axutil_string_create(env, value); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_namespace( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axiom_namespace_t * om_namespace) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_FUNC_PARAM_CHECK(om_namespace, env, AXIS2_FAILURE); + attribute->ns = om_namespace; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_attribute_clone( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + axiom_attribute_t *cloned_attr = NULL; + if(!attribute) + return NULL; + AXIS2_ENV_CHECK(env, NULL); + + /** namespace is not cloned since it is a shollow copy*/ + cloned_attr = axiom_attribute_create_str(env, attribute->localname, attribute->value, + attribute->ns); + if(cloned_attr) + { + return cloned_attr; + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_increment_ref( + struct axiom_attribute * om_attribute, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_attribute->ref++; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_attribute_create_str( + const axutil_env_t * env, + axutil_string_t * localname, + axutil_string_t * value, + axiom_namespace_t * ns) +{ + axiom_attribute_t *attribute = NULL; + + AXIS2_ENV_CHECK(env, NULL); + /* localname is mandatory */ + AXIS2_PARAM_CHECK(env->error, localname, NULL); + + attribute = (axiom_attribute_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_attribute_t)); + if(!attribute) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /** initialize fields */ + attribute->localname = NULL; + attribute->value = NULL; + attribute->ns = NULL; + attribute->qname = NULL; + + attribute->localname = axutil_string_clone(localname, env); + if(!(attribute->localname)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + if(value) + { + attribute->value = axutil_string_clone(value, env); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + axutil_string_free(attribute->localname, env); + AXIS2_FREE(env->allocator, attribute); + return NULL; + } + } + attribute->ns = ns; + + attribute->ref = 0; + + return attribute; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_attribute_get_localname_str( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + return attribute->localname; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_attribute_get_value_str( + axiom_attribute_t * attribute, + const axutil_env_t * env) +{ + return attribute->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_localname_str( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axutil_string_t * localname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + + if(attribute->localname) + { + axutil_string_free(attribute->localname, env); + attribute->localname = NULL; + } + + attribute->localname = axutil_string_clone(localname, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_attribute_set_value_str( + axiom_attribute_t * attribute, + const axutil_env_t * env, + axutil_string_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + if(attribute->value) + { + axutil_string_free(attribute->value, env); + attribute->value = NULL; + } + + attribute->value = axutil_string_clone(value, env); + if(!(attribute->value)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} diff --git a/axiom/src/om/om_child_element_iterator.c b/axiom/src/om/om_child_element_iterator.c new file mode 100644 index 0000000..622cfbd --- /dev/null +++ b/axiom/src/om/om_child_element_iterator.c @@ -0,0 +1,119 @@ +/* + * 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_child_element_iterator.h> + +struct axiom_child_element_iterator +{ + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; +}; + +AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL +axiom_child_element_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child) +{ + axiom_child_element_iterator_t *iterator = NULL; + AXIS2_ENV_CHECK(env, NULL); + + iterator = (axiom_child_element_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_child_element_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = current_child; + iterator->last_child = NULL; + + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL axiom_child_element_iterator_free( + void *iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_child_element_iterator_remove( + axiom_child_element_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + return AXIS2_FAILURE; + if(iterator->remove_called) + return AXIS2_FAILURE; + + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + return AXIS2_FAILURE; + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_child_element_iterator_has_next( + axiom_child_element_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + return (iterator->current_child) ? AXIS2_TRUE : AXIS2_FALSE; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_child_element_iterator_next( + axiom_child_element_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + if (iterator->current_child) + { + iterator->last_child = iterator->current_child; + do + { + iterator->current_child = + axiom_node_get_next_sibling(iterator->current_child, env); + + } + while (iterator->current_child && + (axiom_node_get_node_type(iterator->current_child, env) + != AXIOM_ELEMENT)); + + return iterator->last_child; + } + return NULL; +} diff --git a/axiom/src/om/om_children_iterator.c b/axiom/src/om/om_children_iterator.c new file mode 100644 index 0000000..42046e5 --- /dev/null +++ b/axiom/src/om/om_children_iterator.c @@ -0,0 +1,138 @@ +/* + * 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_children_iterator.h> + +struct axiom_children_iterator +{ + axiom_node_t *first_child; + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; +}; + +AXIS2_EXTERN axiom_children_iterator_t *AXIS2_CALL +axiom_children_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child) +{ + axiom_children_iterator_t *iterator = NULL; + AXIS2_ENV_CHECK(env, NULL); + + iterator = (axiom_children_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_children_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = NULL; + iterator->last_child = NULL; + iterator->first_child = NULL; + + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + + iterator->first_child = current_child; + iterator->current_child = current_child; + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_children_iterator_free( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_iterator_remove( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(iterator->remove_called) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + { + return AXIS2_FAILURE; + } + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_children_iterator_has_next( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + return (iterator->current_child) ? AXIS2_TRUE : AXIS2_FALSE; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_children_iterator_next( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + if(iterator->current_child) + { + iterator->last_child = iterator->current_child; + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + return iterator->last_child; + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_iterator_reset( + axiom_children_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + iterator->current_child = iterator->first_child; + return AXIS2_SUCCESS; +} diff --git a/axiom/src/om/om_children_qname_iterator.c b/axiom/src/om/om_children_qname_iterator.c new file mode 100644 index 0000000..d508a9e --- /dev/null +++ b/axiom/src/om/om_children_qname_iterator.c @@ -0,0 +1,190 @@ +/* + * 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_children_qname_iterator.h> +#include <axiom_element.h> + +struct axiom_children_qname_iterator +{ + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; + axutil_qname_t *given_qname; + axis2_bool_t need_to_move_forward; + axis2_bool_t matching_node_found; + +}; + +AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL +axiom_children_qname_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child, + axutil_qname_t * given_qname) +{ + axiom_children_qname_iterator_t *iterator = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, current_child, NULL); + + iterator = (axiom_children_qname_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_children_qname_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = NULL; + iterator->last_child = NULL; + iterator->need_to_move_forward = AXIS2_TRUE; + iterator->matching_node_found = AXIS2_FALSE; + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + iterator->given_qname = NULL; + + iterator->current_child = current_child; + if(given_qname) + { + iterator->given_qname = axutil_qname_clone(given_qname, env); + if(!(iterator->given_qname)) + { + axiom_children_qname_iterator_free(iterator, env); + return NULL; + } + } + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_children_qname_iterator_free( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(iterator->given_qname) + { + axutil_qname_free(iterator->given_qname, env); + } + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_qname_iterator_remove( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(iterator->remove_called) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + return AXIS2_FAILURE; + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_children_qname_iterator_has_next( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + while(iterator->need_to_move_forward) + { + if(iterator->current_child) + { + axiom_element_t *om_element = NULL; + axutil_qname_t *element_qname = NULL; + + if(axiom_node_get_node_type(iterator->current_child, env) == AXIOM_ELEMENT) + { + om_element = (axiom_element_t *)axiom_node_get_data_element( + iterator-> current_child, env); + } + + if(om_element) + { + element_qname = axiom_element_get_qname(om_element, env, iterator->current_child); + } + + if(om_element && axutil_qname_equals(element_qname, env, iterator->given_qname)) + { + iterator->matching_node_found = AXIS2_TRUE; + iterator->need_to_move_forward = AXIS2_FALSE; + } + else + { + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + if(iterator->current_child) + { + iterator->need_to_move_forward = AXIS2_TRUE; + iterator->matching_node_found = AXIS2_TRUE; + } + else + { + iterator->need_to_move_forward = AXIS2_FALSE; + iterator->matching_node_found = AXIS2_FALSE; + } + } + } + else + { + iterator->need_to_move_forward = AXIS2_FALSE; + } + } + return iterator->matching_node_found; + +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_children_qname_iterator_next( + axiom_children_qname_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + iterator->need_to_move_forward = AXIS2_TRUE; + iterator->matching_node_found = AXIS2_FALSE; + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + + iterator->last_child = iterator->current_child; + if(iterator->current_child) + { + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + } + return iterator->last_child; +} + diff --git a/axiom/src/om/om_children_with_specific_attribute_iterator.c b/axiom/src/om/om_children_with_specific_attribute_iterator.c new file mode 100644 index 0000000..8f2e463 --- /dev/null +++ b/axiom/src/om/om_children_with_specific_attribute_iterator.c @@ -0,0 +1,177 @@ +/* + * 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_children_with_specific_attribute_iterator.h> +#include <axiom_attribute.h> +#include <axiom_element.h> + +struct axiom_children_with_specific_attribute_iterator +{ + axiom_node_t *current_child; + axiom_node_t *last_child; + axis2_bool_t next_called; + axis2_bool_t remove_called; + axutil_qname_t *attr_qname; + axis2_char_t *attr_value; + axis2_bool_t detach; +}; + +AXIS2_EXTERN axiom_children_with_specific_attribute_iterator_t *AXIS2_CALL +axiom_children_with_specific_attribute_iterator_create( + const axutil_env_t * env, + axiom_node_t * current_child, + axutil_qname_t * attr_qname, + axis2_char_t * attr_value, + axis2_bool_t detach) +{ + axiom_children_with_specific_attribute_iterator_t *iterator = NULL; + + AXIS2_PARAM_CHECK(env->error, current_child, NULL); + AXIS2_PARAM_CHECK(env->error, attr_qname, NULL); + AXIS2_PARAM_CHECK(env->error, attr_value, NULL); + iterator = (axiom_children_with_specific_attribute_iterator_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_children_with_specific_attribute_iterator_t)); + + if(!iterator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + iterator->current_child = NULL; + iterator->last_child = NULL; + + iterator->next_called = AXIS2_FALSE; + iterator->remove_called = AXIS2_FALSE; + + iterator->attr_qname = axutil_qname_clone(attr_qname, env); + iterator->attr_value = attr_value; + iterator->detach = detach; + + return iterator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_children_with_specific_attribute_iterator_free( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + if(iterator->attr_qname) + { + axutil_qname_free(iterator->attr_qname, env); + } + AXIS2_FREE(env->allocator, iterator); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_children_with_specific_attribute_iterator_remove( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); + + if(!(iterator->next_called)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_NEXT_METHOD_HAS_NOT_YET_BEEN_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + if(iterator->remove_called) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ITERATOR_REMOVE_HAS_ALREADY_BEING_CALLED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + iterator->remove_called = AXIS2_TRUE; + + if(!(iterator->last_child)) + return AXIS2_FAILURE; + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_children_with_specific_attribute_iterator_has_next( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + axis2_bool_t matching_node_found = AXIS2_FALSE; + axis2_bool_t need_to_move_forward = AXIS2_TRUE; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!(iterator->current_child)) + { + return AXIS2_FALSE; + } + while(need_to_move_forward) + { + if(axiom_node_get_node_type(iterator->current_child, env) == AXIOM_ELEMENT) + { + axiom_attribute_t *om_attr = NULL; + axiom_element_t *om_ele = NULL; + om_ele = (axiom_element_t *)axiom_node_get_data_element(iterator-> current_child, env); + om_attr = axiom_element_get_attribute(om_ele, env, iterator->attr_qname); + break; + /*if (om_attr && + (axutil_strcmp(axiom_attribute_get_value(om_attr, env), + iterator->attr_value) == 0)) + { + matching_node_found = AXIS2_TRUE; + need_to_move_forward = AXIS2_FALSE; + } + else + { + iterator->current_child = + axiom_node_get_next_sibling(iterator->current_child, env); + need_to_move_forward = (iterator->current_child != NULL); + + }*/ + } + else + { + + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + need_to_move_forward = (iterator->current_child != NULL); + } + + } + return matching_node_found; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_children_with_specific_attribute_iterator_next( + axiom_children_with_specific_attribute_iterator_t * iterator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, iterator, NULL); + + iterator->next_called = AXIS2_TRUE; + iterator->remove_called = AXIS2_FALSE; + iterator->last_child = iterator->current_child; + iterator->current_child = axiom_node_get_next_sibling(iterator->current_child, env); + if(iterator->last_child && iterator->detach + && (axiom_node_get_parent(iterator->last_child, env))) + { + axiom_node_free_tree(iterator->last_child, env); + } + return iterator->last_child; +} diff --git a/axiom/src/om/om_comment.c b/axiom/src/om/om_comment.c new file mode 100644 index 0000000..ad17f74 --- /dev/null +++ b/axiom/src/om/om_comment.c @@ -0,0 +1,142 @@ +/* + * 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_comment.h> +#include "axiom_node_internal.h" +#include <axutil_string.h> + +struct axiom_comment +{ + + /** comment text */ + axis2_char_t *value; +}; + +AXIS2_EXTERN axiom_comment_t *AXIS2_CALL +axiom_comment_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_comment_t *comment = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, value, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + *node = NULL; + *node = axiom_node_create(env); + if(!*node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + comment = (axiom_comment_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_comment_t)); + if(!comment) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + comment->value = NULL; + + if(value) + { + comment->value = (axis2_char_t *)axutil_strdup(env, value); + if(!comment->value) + { + AXIS2_FREE(env->allocator, comment); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + axiom_node_set_data_element((*node), env, comment); + axiom_node_set_node_type((*node), env, AXIOM_COMMENT); + + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + + return comment; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_comment_free( + axiom_comment_t * comment, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(comment->value) + { + AXIS2_FREE(env->allocator, comment->value); + } + AXIS2_FREE(env->allocator, comment); + return; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_comment_get_value( + axiom_comment_t * comment, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return comment->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_comment_set_value( + axiom_comment_t * comment, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + if(comment->value) + { + AXIS2_FREE(env->allocator, comment->value); + } + + comment->value = (axis2_char_t *)axutil_strdup(env, value); + + if(!comment->value) + { + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_comment_serialize( + axiom_comment_t * comment, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(comment->value) + { + return axiom_output_write(om_output, env, AXIOM_COMMENT, 1, comment->value); + } + return AXIS2_FAILURE; +} diff --git a/axiom/src/om/om_data_source.c b/axiom/src/om/om_data_source.c new file mode 100644 index 0000000..3959e49 --- /dev/null +++ b/axiom/src/om/om_data_source.c @@ -0,0 +1,133 @@ +/* + * 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_data_source.h> +#include <axiom_output.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" +#include <axiom_xml_writer.h> +#include <axiom_output.h> +#include <axiom_attribute.h> +#include <axiom_namespace.h> +#include <axutil_base64.h> + +/********************* axiom_data_source_struct ***************/ + +struct axiom_data_source +{ + + /** stream holding serialized XML string */ + axutil_stream_t *stream; +}; + +AXIS2_EXTERN axiom_data_source_t *AXIS2_CALL +axiom_data_source_create( + const axutil_env_t * env, + axiom_node_t * parent, + axiom_node_t ** node) +{ + + axiom_data_source_t *data_source = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + data_source = (axiom_data_source_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_data_source_t)); + if(!data_source) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + axiom_node_set_data_element((*node), env, data_source); + axiom_node_set_node_type((*node), env, AXIOM_DATA_SOURCE); + axiom_node_set_complete((*node), env, AXIS2_FALSE); + + data_source->stream = NULL; + + data_source->stream = axutil_stream_create_basic(env); + if(!(data_source->stream)) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_FREE(env->allocator, data_source); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_node_add_child(parent, env, (*node)); + } + + return data_source; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_data_source_free( + axiom_data_source_t * data_source, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(data_source->stream) + { + axutil_stream_free(data_source->stream, env); + } + + AXIS2_FREE(env->allocator, data_source); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_data_source_serialize( + axiom_data_source_t * data_source, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + axis2_char_t *data = NULL; + unsigned int data_len = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + data = axutil_stream_get_buffer(data_source->stream, env); + data_len = axutil_stream_get_len(data_source->stream, env); + if(data) + { + data[data_len] = '\0'; + status = axiom_output_write(om_output, env, AXIOM_DATA_SOURCE, 1, data); + } + return status; +} + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axiom_data_source_get_stream( + axiom_data_source_t * data_source, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return data_source->stream; +} diff --git a/axiom/src/om/om_doctype.c b/axiom/src/om/om_doctype.c new file mode 100644 index 0000000..fa5616b --- /dev/null +++ b/axiom/src/om/om_doctype.c @@ -0,0 +1,131 @@ +/* + * 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_doctype.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" + +struct axiom_doctype +{ + + /** Doctype value */ + axis2_char_t *value; +}; + +AXIS2_EXTERN axiom_doctype_t *AXIS2_CALL +axiom_doctype_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_doctype_t *doctype = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + if(!*node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + doctype = (axiom_doctype_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_doctype_t)); + + if(!doctype) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + doctype->value = NULL; + + if(value) + { + doctype->value = (axis2_char_t *)axutil_strdup(env, value); + if(!doctype->value) + { + AXIS2_FREE(env->allocator, doctype); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + axiom_node_set_data_element((*node), env, doctype); + axiom_node_set_node_type((*node), env, AXIOM_DOCTYPE); + + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + + return doctype; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_doctype_free( + axiom_doctype_t * om_doctype, + const axutil_env_t * env) +{ + if(om_doctype) + { + if(om_doctype->value) + { + AXIS2_FREE(env->allocator, om_doctype->value); + } + AXIS2_FREE(env->allocator, om_doctype); + } + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_doctype_set_value( + axiom_doctype_t * om_doctype, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + om_doctype->value = (axis2_char_t *)axutil_strdup(env, value); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_doctype_get_value( + axiom_doctype_t * om_doctype, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return om_doctype->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_doctype_serialize( + axiom_doctype_t * om_doctype, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_doctype->value) + return axiom_output_write(om_output, env, AXIOM_DOCTYPE, 1, om_doctype->value); + + return AXIS2_FAILURE; +} diff --git a/axiom/src/om/om_document.c b/axiom/src/om/om_document.c new file mode 100644 index 0000000..149edec --- /dev/null +++ b/axiom/src/om/om_document.c @@ -0,0 +1,263 @@ +/* + * 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_document.h> +#include <axiom_stax_builder.h> +#include <axutil_string.h> + +struct axiom_document +{ + + /** root element */ + axiom_node_t *root_element; + + /** last child */ + axiom_node_t *last_child; + + /** first child */ + axiom_node_t *first_child; + + /** done building the document */ + axis2_bool_t done; + + /** builder of the document */ + struct axiom_stax_builder *builder; + + /** char set encoding */ + axis2_char_t *char_set_encoding; + + /** XML version */ + axis2_char_t *xml_version; +}; + +AXIS2_EXTERN axiom_document_t *AXIS2_CALL +axiom_document_create( + const axutil_env_t * env, + axiom_node_t * root, + axiom_stax_builder_t * builder) +{ + axiom_document_t *document = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + document = (axiom_document_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_document_t)); + + if(!document) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + document->builder = builder; + document->root_element = root; + document->first_child = root; + document->last_child = root; + document->xml_version = XML_VERSION; + document->char_set_encoding = CHAR_SET_ENCODING; + document->done = AXIS2_FALSE; + + return document; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_document_free( + axiom_document_t * document, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(document->root_element) + { + axiom_node_free_tree(document->root_element, env); + } + AXIS2_FREE(env->allocator, document); + return; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_document_free_self( + axiom_document_t * document, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, document); + return; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_document_build_next( + axiom_document_t * document, + const axutil_env_t * env) +{ + axiom_node_t *last_child = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!document->builder) + { + return NULL; + } + + if(!(document->root_element)) + { + last_child = axiom_stax_builder_next(document->builder, env); + if(last_child) + { + document->last_child = last_child; + document->root_element = last_child; + } + return last_child; + } + else if((document->root_element) && (axiom_node_is_complete(document->root_element, env) + == AXIS2_TRUE)) + return NULL; /* Nothing wrong but done with pulling */ + + last_child = axiom_stax_builder_next(document->builder, env); + if(last_child) + { + document->last_child = last_child; + } + return last_child; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_document_get_root_element( + axiom_document_t * document, + const axutil_env_t * env) +{ + axiom_node_t *node = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(document->root_element) + { + return document->root_element; + } + node = axiom_document_build_next(document, env); + + if(document->root_element) + { + return document->root_element; + } + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_DOCUMENT_STATE_ROOT_NULL, AXIS2_FAILURE); + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_document_set_root_element( + axiom_document_t * document, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(document->root_element) + { + axiom_node_free_tree(document->root_element, env); + document->root_element = node; + return AXIS2_SUCCESS; + } + else + { + document->root_element = node; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_document_build_all( + struct axiom_document * document, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + if(!document) + { + return NULL; + } + if(!document->root_element) + { + axiom_document_get_root_element(document, env); + } + if(document->root_element) + { + do + { + axiom_node_t *ret_val = NULL; + ret_val = axiom_document_build_next(document, env); + if(!ret_val) + { + if(axiom_node_is_complete(document->root_element, env) == AXIS2_TRUE) + { + + /** document is completly build */ + return document->root_element; + } + else + { + + /** error occurred */ + return NULL; + } + } + } + while(!axiom_node_is_complete(document->root_element, env)); + return document->root_element; + } + else + return NULL; +} + +AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL +axiom_document_get_builder( + axiom_document_t * document, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return document->builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_document_set_builder( + axiom_document_t * document, + const axutil_env_t * env, + axiom_stax_builder_t * builder) +{ + document->builder = builder; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_document_serialize( + axiom_document_t * document, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + if(!document) + return AXIS2_FAILURE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!(document->root_element)) + { + axiom_document_get_root_element(document, env); + } + if(document->root_element) + { + return axiom_node_serialize(document->root_element, env, om_output); + } + else + { + return AXIS2_FAILURE; + } +} diff --git a/axiom/src/om/om_element.c b/axiom/src/om/om_element.c new file mode 100644 index 0000000..84982cd --- /dev/null +++ b/axiom/src/om/om_element.c @@ -0,0 +1,1818 @@ +/* + * 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_element.h> +#include "axiom_node_internal.h" +#include <axiom_attribute.h> +#include <axiom_namespace.h> +#include <axiom_xml_writer.h> +#include <axiom_stax_builder.h> +#include <string.h> +#include <stdio.h> + +struct axiom_element +{ + + /** Element's namespace */ + axiom_namespace_t *ns; + + /** Element's local name */ + axutil_string_t *localname; + + /** List of attributes */ + axutil_hash_t *attributes; + + /** List of namespaces */ + axutil_hash_t *namespaces; + + axutil_qname_t *qname; + + axiom_child_element_iterator_t *child_ele_iter; + + axiom_children_iterator_t *children_iter; + + axiom_children_qname_iterator_t *children_qname_iter; + + axis2_char_t *text_value; + + int next_ns_prefix_number; + + axis2_bool_t is_empty; + +}; + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * localname, + axiom_namespace_t * ns, + axiom_node_t ** node) +{ + axiom_element_t *element; + AXIS2_ENV_CHECK(env, NULL); + + if(!localname || !node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localname or node is NULL"); + return NULL; + } + + (*node) = axiom_node_create(env); + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Memory"); + return NULL; + } + element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t)); + + if(!element) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Memory"); + return NULL; + } + element->ns = NULL; + element->localname = NULL; + element->attributes = NULL; + element->namespaces = NULL; + element->qname = NULL; + element->child_ele_iter = NULL; + element->children_iter = NULL; + element->children_qname_iter = NULL; + element->text_value = NULL; + element->next_ns_prefix_number = 0; + element->is_empty = AXIS2_FALSE; + + element->localname = axutil_string_create(env, localname); + if(!element->localname) + { + AXIS2_FREE(env->allocator, element); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + axiom_node_set_complete((*node), env, AXIS2_FALSE); + axiom_node_set_node_type((*node), env, AXIOM_ELEMENT); + axiom_node_set_data_element((*node), env, element); + + if(ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + /* + if (prefix && axutil_strcmp(prefix, "") == 0) + { + element->ns = NULL; + return element; + } + */ + element->ns = axiom_element_find_namespace(element, env, *node, uri, prefix); + + if(element->ns) + { + if(ns != element->ns) + { + axiom_namespace_free(ns, env); + ns = NULL; + } + } + + if(!(element->ns)) + { + if(axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS) + { + element->ns = ns; + } + } + + /*if (prefix && axutil_strcmp(prefix, "") == 0) + { + element->ns = NULL; + } + */ + } + + return element; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_create_with_qname( + const axutil_env_t * env, + axiom_node_t * parent, + const axutil_qname_t * qname, + axiom_node_t ** node) +{ + axiom_element_t *element = NULL; + axis2_char_t *localpart = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!qname || !node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "qname or node is NULL"); + return NULL; + } + localpart = axutil_qname_get_localpart(qname, env); + if(!localpart) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localpart is NULL"); + return NULL; + } + element = axiom_element_create(env, parent, localpart, NULL, node); + if(!element) + { + return NULL; + } + + if(*node) + { + axiom_element_t *om_element = NULL; + axis2_char_t *temp_nsuri = NULL; + axis2_char_t *temp_prefix = NULL; + axiom_namespace_t *ns = NULL; + + om_element = ((axiom_element_t *)axiom_node_get_data_element((*node), env)); + temp_nsuri = axutil_qname_get_uri(qname, env); + temp_prefix = axutil_qname_get_prefix(qname, env); + if(!om_element) + { + return NULL; + } + + if((!temp_nsuri) || (axutil_strcmp(temp_nsuri, "") == 0)) + { + + /** no namespace uri is available in given qname + no need to bother about it + */ + return om_element; + } + + om_element->ns = axiom_element_find_namespace(om_element, env, (*node), temp_nsuri, + temp_prefix); + + if(!(element->ns)) + { + + /** could not find a namespace so declare namespace */ + ns = axiom_namespace_create(env, temp_nsuri, temp_prefix); + if(ns && axiom_element_declare_namespace(om_element, env, *node, ns) == AXIS2_SUCCESS) + { + (element->ns) = ns; + return om_element; + } + else + { + if(ns) + { + axiom_namespace_free(ns, env); + } + axiom_element_free(om_element, env); + AXIS2_FREE(env->allocator, *node); + return NULL; + } + } + } + return element; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_find_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axiom_node_t *parent = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!element_node || !om_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element_node or om_element is NULL"); + return NULL; + } + if(!axiom_node_get_data_element(element_node, env) || axiom_node_get_node_type(element_node, + env) != AXIOM_ELEMENT) + { + /* wrong element type or null node */ + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Wrong element type or null node"); + return NULL; + } + + if(om_element->namespaces) + { + void *ns = NULL; + + if(uri && (!prefix || axutil_strcmp(prefix, "") == 0)) + { + + /** check for a default namepsace */ + axiom_namespace_t *default_ns = NULL; + axutil_hash_index_t *hashindex; + + default_ns = axiom_element_get_default_namespace(om_element, env, element_node); + if(default_ns) + { + axis2_char_t *default_uri = NULL; + default_uri = axiom_namespace_get_uri(default_ns, env); + + if(axutil_strcmp(uri, default_uri) == 0) + { + return default_ns; + } + } + + /** prefix is null , so iterate the namespaces hash to find the namespace */ + for(hashindex = axutil_hash_first(om_element->namespaces, env); hashindex; hashindex + = axutil_hash_next(env, hashindex)) + { + axutil_hash_this(hashindex, NULL, NULL, &ns); + if(ns) + { + axiom_namespace_t *temp_ns = NULL; + axis2_char_t *temp_nsuri = NULL; + temp_ns = (axiom_namespace_t *)ns; + temp_nsuri = axiom_namespace_get_uri(temp_ns, env); + + if(axutil_strcmp(temp_nsuri, uri) == 0) + { + /** namespace uri matches, so free hashindex and return ns*/ + AXIS2_FREE(env->allocator, hashindex); + return (axiom_namespace_t *)(ns); + } + temp_ns = NULL; + temp_nsuri = NULL; + ns = NULL; + } + } + ns = NULL; + } + else if(prefix) + { + + /** prefix is not null get namespace directly if exist */ + ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(ns) + { + axiom_namespace_t *found_ns = NULL; + axis2_char_t *found_uri = NULL; + found_ns = (axiom_namespace_t *)ns; + found_uri = axiom_namespace_get_uri(found_ns, env); + if(uri) + { + /* if uri provided, return found ns only if uri matches */ + return (axutil_strcmp(found_uri, uri) == 0) ? found_ns : NULL; + } + return found_ns; + } + } + } + + /** could not find the namespace in current element scope + look in the parent */ + + parent = axiom_node_get_parent(element_node, env); + + if(parent) + { + if(axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_element_t *om_element = NULL; + om_element = (axiom_element_t *)axiom_node_get_data_element(parent, env); + if(om_element) + + { /** parent exist, parent is om element so find in parent*/ + return axiom_element_find_namespace(om_element, env, parent, uri, prefix); + } + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_declare_namespace_assume_param_ownership( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_namespace_t * ns) +{ + axis2_char_t *prefix = NULL; + axis2_char_t *uri = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!ns || !om_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "namespace or om_element is NULL"); + return AXIS2_FAILURE; + } + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + if(!(om_element->namespaces)) + { + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) + { + return AXIS2_FAILURE; + } + } + if(prefix) + { + axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns); + } + else + { + axis2_char_t *key = NULL; + key = AXIS2_MALLOC(env->allocator, sizeof(char) * 10); + memset(key, 0, sizeof(char) * 10); + om_element->next_ns_prefix_number++; + key[0] = '\0'; + axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns); + } + axiom_namespace_increment_ref(ns, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_declare_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * node, + axiom_namespace_t * ns) +{ + axiom_namespace_t *declared_ns = NULL; + axis2_char_t *prefix = NULL; + axis2_char_t *uri = NULL; + + if(!node || !ns || !om_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "node or namespace or om_element is NULL"); + return AXIS2_FAILURE; + } + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + declared_ns = axiom_element_find_namespace(om_element, env, node, uri, prefix); + + if(declared_ns) + { + if(axiom_namespace_equals(ns, env, declared_ns) == AXIS2_TRUE) + { + /*Namespace already declared, so return */ + return AXIS2_SUCCESS; + } + } + + if(!(om_element->namespaces)) + { + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) + { + return AXIS2_FAILURE; + } + } + if(prefix) + { + axutil_hash_set(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns); + } + else + { + axis2_char_t *key = NULL; + key = AXIS2_MALLOC(env->allocator, sizeof(char) * 10); + memset(key, 0, sizeof(char) * 10); + om_element->next_ns_prefix_number++; + key[0] = '\0'; + axutil_hash_set(om_element->namespaces, key, AXIS2_HASH_KEY_STRING, ns); + } + axiom_namespace_increment_ref(ns, env); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_find_declared_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axutil_hash_index_t *hash_index = NULL; + void *ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!(om_element->namespaces)) + { + return NULL; + } + if(uri && (!prefix || axutil_strcmp(prefix, "") == 0)) + { + /** prefix null iterate the namespace hash for matching uri */ + for(hash_index = axutil_hash_first(om_element->namespaces, env); hash_index; hash_index + = axutil_hash_next(env, hash_index)) + { + axutil_hash_this(hash_index, NULL, NULL, &ns); + if(ns) + { + axiom_namespace_t *temp_ns = NULL; + axis2_char_t *temp_nsuri = NULL; + temp_ns = (axiom_namespace_t *)(ns); + temp_nsuri = axiom_namespace_get_uri(temp_ns, env); + if(axutil_strcmp(temp_nsuri, uri) == 0) + { + AXIS2_FREE(env->allocator, hash_index); + return temp_ns; + } + temp_ns = NULL; + temp_nsuri = NULL; + } + } + ns = NULL; + return NULL; + } + else if(prefix) + { + axiom_namespace_t *found_ns = NULL; + ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(ns) + { + axis2_char_t *found_uri = NULL; + found_ns = (axiom_namespace_t *)ns; + found_uri = axiom_namespace_get_uri(found_ns, env); + /* If uri provided, ensure this namespace found by prefix matches the uri */ + if(uri) + { + return (axutil_strcmp(found_uri, uri) == 0) ? found_ns : NULL; + } + return found_ns; + } + } + return NULL; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_find_namespace_with_qname( + axiom_element_t * element, + const axutil_env_t * env, + axiom_node_t * node, + axutil_qname_t * qname) +{ + AXIS2_ENV_CHECK(env, NULL); + if(!element || !node || !qname) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "element or node or qname is NULL"); + return NULL; + } + + if(axutil_qname_get_uri(qname, env)) + { + return axiom_element_find_namespace(element, env, node, axutil_qname_get_uri(qname, env), + axutil_qname_get_prefix(qname, env)); + } + else + { + return NULL; + } +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_add_attribute( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_attribute_t * attribute, + axiom_node_t * element_node) +{ + + axutil_qname_t *qname = NULL; + axiom_namespace_t *om_namespace = NULL; + axiom_namespace_t *temp_ns = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, attribute, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); + + /* ensure the attribute's namespace structure is declared */ + om_namespace = axiom_attribute_get_namespace(attribute, env); + if(om_namespace) + { + temp_ns = axiom_element_find_namespace(om_element, env, element_node, + axiom_namespace_get_uri(om_namespace, env), axiom_namespace_get_prefix(om_namespace, + env)); + if(temp_ns != om_namespace) + { + axis2_status_t status; + /* as the attribute's namespace structure is not declared in scope, + declare it here */ + status = axiom_element_declare_namespace_assume_param_ownership(om_element, env, + om_namespace); + if(status != AXIS2_SUCCESS) + { + return status; + } + } + } + + if(!(om_element->attributes)) + { + om_element->attributes = axutil_hash_make(env); + if(!(om_element->attributes)) + { + return AXIS2_FAILURE; + } + } + + qname = axiom_attribute_get_qname(attribute, env); + if(qname) + { + axis2_char_t *name = axutil_qname_to_string(qname, env); + axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, attribute); + axiom_attribute_increment_ref(attribute, env); + } + return ((qname) ? AXIS2_SUCCESS : AXIS2_FAILURE); +} + +AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL +axiom_element_get_attribute( + axiom_element_t * om_element, + const axutil_env_t * env, + axutil_qname_t * qname) +{ + axis2_char_t *name = NULL; + axiom_attribute_t *attr = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + name = axutil_qname_to_string(qname, env); + + if((om_element->attributes) && name) + { + attr = (axiom_attribute_t *)(axutil_hash_get(om_element->attributes, name, + AXIS2_HASH_KEY_STRING)); + } + return attr; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_element_free( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!om_element) + { + return; + } + + if(om_element->localname) + { + axutil_string_free(om_element->localname, env); + } + if(om_element->ns) + { + /* it is the responsibility of the element where the namespace is declared to free it */ + } + if(om_element->attributes) + { + axutil_hash_index_t *hi; + void *val = NULL; + + for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_attribute_free((axiom_attribute_t *)val, env); + } + } + axutil_hash_free(om_element->attributes, env); + } + + if(om_element->namespaces) + { + axutil_hash_index_t *hi; + void *val = NULL; + for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + axiom_namespace_free((axiom_namespace_t *)val, env); + } + } + axutil_hash_free(om_element->namespaces, env); + } + if(om_element->qname) + { + axutil_qname_free(om_element->qname, env); + } + if(om_element->children_iter) + { + axiom_children_iterator_free(om_element->children_iter, env); + } + if(om_element->child_ele_iter) + { + AXIOM_CHILD_ELEMENT_ITERATOR_FREE(om_element->child_ele_iter, env); + } + if(om_element->children_qname_iter) + { + axiom_children_qname_iterator_free(om_element->children_qname_iter, env); + } + if(om_element->text_value) + { + AXIS2_FREE(env->allocator, om_element->text_value); + } + AXIS2_FREE(env->allocator, om_element); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_serialize_start_part( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_output_t * om_output, + axiom_node_t * ele_node) +{ + int status = AXIS2_SUCCESS; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_element->is_empty) + { + if(om_element->ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(om_element->ns, env); + prefix = axiom_namespace_get_prefix(om_element->ns, env); + + if((uri) && (prefix) && (axutil_strcmp(prefix, "") != 0)) + { + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4, + axutil_string_get_buffer(om_element-> localname, env), uri, prefix, NULL); + } + else if(uri) + { + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4, + axutil_string_get_buffer(om_element-> localname, env), uri, NULL, NULL); + } + } + else + { + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 4, axutil_string_get_buffer( + om_element-> localname, env), NULL, NULL, NULL); + } + } + else + { + if(om_element->ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(om_element->ns, env); + prefix = axiom_namespace_get_prefix(om_element->ns, env); + + if((uri) && (prefix) && (axutil_strcmp(prefix, "") != 0)) + { + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 3, + axutil_string_get_buffer(om_element-> localname, env), uri, prefix); + } + else if(uri) + { + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 2, + axutil_string_get_buffer(om_element-> localname, env), uri); + } + } + else + { + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 1, axutil_string_get_buffer( + om_element-> localname, env)); + } + } + if(om_element->attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + status = axiom_attribute_serialize((axiom_attribute_t *)val, env, om_output); + } + else + { + status = AXIS2_FAILURE; + } + } + } + + if(om_element->namespaces) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(om_element->namespaces, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + status = axiom_namespace_serialize((axiom_namespace_t *)val, env, om_output); + } + else + { + status = AXIS2_FAILURE; + } + } + } + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_serialize_end_part( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + status = axiom_output_write(om_output, env, AXIOM_ELEMENT, 0); + return status; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_get_localname( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + if(om_element->localname) + return (axis2_char_t *)axutil_string_get_buffer(om_element->localname, env); + else + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_localname( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * localname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + if(om_element->localname) + { + axutil_string_free(om_element->localname, env); + om_element->localname = NULL; + } + om_element->localname = axutil_string_create(env, localname); + if(!(om_element->localname)) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_get_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * ele_node) +{ + axiom_namespace_t *ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(om_element->ns) + { + ns = om_element->ns; + } + else + { + ns = axiom_element_get_default_namespace(om_element, env, ele_node); + + } + return ns; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_namespace_t * ns, + axiom_node_t * node) +{ + axiom_namespace_t *om_ns = NULL; + axis2_status_t status = AXIS2_SUCCESS; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, ns, AXIS2_FAILURE); + om_ns = axiom_element_find_namespace(om_element, env, node, axiom_namespace_get_uri(ns, env), + axiom_namespace_get_prefix(ns, env)); + if(!om_ns) + { + status = axiom_element_declare_namespace(om_element, env, node, ns); + if(status == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + om_element->ns = ns; + } + else + { + om_element->ns = om_ns; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_namespace_assume_param_ownership( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_namespace_t * ns) +{ + om_element->ns = ns; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_element_get_all_attributes( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + + return om_element->attributes; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_element_get_namespaces( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + return om_element->namespaces; +} + +AXIS2_EXTERN axutil_qname_t *AXIS2_CALL +axiom_element_get_qname( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * ele_node) +{ + axiom_namespace_t *ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(om_element->qname) + { + return om_element->qname; + } + else + { + ns = axiom_element_get_namespace(om_element, env, ele_node); + if(ns) + { + if(axiom_namespace_get_prefix(ns, env)) + { + om_element->qname = axutil_qname_create(env, axutil_string_get_buffer( + om_element->localname, env), axiom_namespace_get_uri(ns, env), + axiom_namespace_get_prefix(ns, env)); + } + else + { + om_element->qname = axutil_qname_create(env, axutil_string_get_buffer( + om_element->localname, env), axiom_namespace_get_uri(ns, env), NULL); + } + } + else + { + om_element->qname = axutil_qname_create(env, axutil_string_get_buffer( + om_element->localname, env), NULL, NULL); + } + } + return om_element->qname; +} + +AXIS2_EXTERN axiom_children_iterator_t *AXIS2_CALL +axiom_element_get_children( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + if(!om_element->children_iter) + { + om_element->children_iter = axiom_children_iterator_create(env, axiom_node_get_first_child( + element_node, env)); + } + else + { + axiom_children_iterator_reset(om_element->children_iter, env); + } + return om_element->children_iter; +} + +AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL +axiom_element_get_children_with_qname( + axiom_element_t * om_element, + const axutil_env_t * env, + axutil_qname_t * element_qname, + axiom_node_t * element_node) +{ + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + if(om_element->children_qname_iter) + { + axiom_children_qname_iterator_free(om_element->children_qname_iter, env); + om_element->children_qname_iter = NULL; + } + om_element->children_qname_iter = axiom_children_qname_iterator_create(env, + axiom_node_get_first_child(element_node, env), element_qname); + return om_element->children_qname_iter; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_get_first_child_with_qname( + axiom_element_t * om_element, + const axutil_env_t * env, + axutil_qname_t * element_qname, + axiom_node_t * element_node, + axiom_node_t ** child_node) +{ + axiom_node_t *om_node = NULL; + axiom_children_qname_iterator_t *children_iterator = NULL; + + AXIS2_PARAM_CHECK(env->error, element_qname, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + om_node = axiom_node_get_first_child(element_node, env); + if(!om_node) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "There are no child elements for the node"); + return NULL; + } + children_iterator = axiom_children_qname_iterator_create(env, om_node, element_qname); + if(!children_iterator) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Could not create children qname iterator"); + return NULL; + } + om_node = NULL; + if(axiom_children_qname_iterator_has_next(children_iterator, env)) + { + om_node = axiom_children_qname_iterator_next(children_iterator, env); + } + if(om_node && (axiom_node_get_node_type(om_node, env) == AXIOM_ELEMENT)) + { + axiom_children_qname_iterator_free(children_iterator, env); + + if(child_node) + { + *child_node = om_node; + } + return (axiom_element_t *)axiom_node_get_data_element(om_node, env); + } + + axiom_children_qname_iterator_free(children_iterator, env); + + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_remove_attribute( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_attribute_t * om_attribute) +{ + axutil_qname_t *qname = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_attribute, AXIS2_FAILURE); + + qname = axiom_attribute_get_qname(om_attribute, env); + if(qname && (om_element->attributes)) + { + axis2_char_t *name = NULL; + name = axutil_qname_to_string(qname, env); + if(name) + { + axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, NULL); + return AXIS2_SUCCESS; + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_get_first_element( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node, + axiom_node_t ** first_ele_node) +{ + axiom_node_t *temp_node = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + temp_node = axiom_node_get_first_child(element_node, env); + while(temp_node) + { + if(axiom_node_get_node_type(temp_node, env) == AXIOM_ELEMENT) + { + if(first_ele_node) + { + *first_ele_node = temp_node; + } + return (axiom_element_t *)axiom_node_get_data_element(temp_node, env); + } + else + { + temp_node = axiom_node_get_next_sibling(temp_node, env); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_get_text( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + axis2_char_t *dest = NULL; + const axis2_char_t *temp_text = NULL; + axiom_text_t *text_node = NULL; + axiom_node_t *temp_node = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + if(om_element->text_value) + { + AXIS2_FREE(env->allocator, om_element->text_value); + om_element->text_value = NULL; + } + + temp_node = axiom_node_get_first_child(element_node, env); + + while(temp_node) + { + if(axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT) + { + int dest_len = 0; + int curr_len = 0; + axis2_char_t *temp_dest = NULL; + + text_node = (axiom_text_t *)axiom_node_get_data_element(temp_node, env); + if(text_node) + { + temp_text = axiom_text_get_value(text_node, env); + if(dest && temp_text && axutil_strcmp(temp_text, "") != 0) + { + dest_len = axutil_strlen(dest); + curr_len = dest_len + axutil_strlen(temp_text); + temp_dest = AXIS2_MALLOC(env->allocator, (curr_len + 1) * sizeof(axis2_char_t)); + + memcpy(temp_dest, dest, dest_len * sizeof(axis2_char_t)); + memcpy((temp_dest + dest_len * sizeof(axis2_char_t)), temp_text, curr_len + - dest_len); + + temp_dest[curr_len] = '\0'; + + AXIS2_FREE(env->allocator, dest); + dest = NULL; + dest = temp_dest; + } + else if(!dest && temp_text && axutil_strcmp(temp_text, "") != 0) + { + dest = axutil_strdup(env, temp_text); + } + } + } + temp_node = axiom_node_get_next_sibling(temp_node, env); + } + + om_element->text_value = dest; + return om_element->text_value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_text( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * text, + axiom_node_t * element_node) +{ + axiom_node_t *temp_node, *next_node; + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); + + next_node = axiom_node_get_first_child(element_node, env); + while(next_node) + { + temp_node = next_node; + next_node = axiom_node_get_next_sibling(temp_node, env); + if(axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT) + { + axiom_node_free_tree(temp_node, env); + } + } + + om_text = axiom_text_create(env, NULL, text, &temp_node); + axiom_node_add_child(element_node, env, temp_node); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_to_string( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + return axiom_node_to_string(element_node, env); +} + +AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL +axiom_element_get_child_elements( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + axiom_node_t *first_node = NULL; + axiom_element_t *ele = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + ele = axiom_element_get_first_element(om_element, env, element_node, &first_node); + if(om_element->child_ele_iter) + { + return om_element->child_ele_iter; + } + else if(ele && first_node) + { + om_element->child_ele_iter = axiom_child_element_iterator_create(env, first_node); + return om_element->child_ele_iter; + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_build( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * om_ele_node) +{ + axiom_stax_builder_t *builder = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + AXIS2_PARAM_CHECK(env->error, om_ele_node, AXIS2_FAILURE); + if(axiom_node_get_node_type(om_ele_node, env) != AXIOM_ELEMENT) + { + return AXIS2_FAILURE; + } + + builder = axiom_node_get_builder(om_ele_node, env); + if(!builder) + { + return AXIS2_FAILURE; + } + while(!axiom_node_is_complete(om_ele_node, env) + && !axiom_stax_builder_is_complete(builder, env)) + { + void *value = NULL; + value = axiom_stax_builder_next(builder, env); + if(!value) + { + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_get_default_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * element_node) +{ + axiom_node_t *parent_node = NULL; + axiom_namespace_t *default_ns = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + + if(om_element->namespaces) + { + default_ns = axutil_hash_get(om_element->namespaces, "", AXIS2_HASH_KEY_STRING); + if(default_ns) + { + return default_ns; + } + } + + parent_node = axiom_node_get_parent(element_node, env); + if((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT)) + { + axiom_element_t *parent_ele = NULL; + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(parent_ele) + { + return axiom_element_get_default_namespace(parent_ele, env, parent_node); + } + } + return NULL; +} + +/** + * declared a default namespace explicitly + */ +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_declare_default_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axiom_namespace_t *default_ns = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + + if(axutil_strcmp(uri, "") == 0) + { + return NULL; + } + + default_ns = axiom_namespace_create(env, uri, ""); + if(!default_ns) + { + return NULL; + } + if(!om_element->namespaces) + { + om_element->namespaces = axutil_hash_make(env); + if(!(om_element->namespaces)) + { + axiom_namespace_free(default_ns, env); + return NULL; + } + } + + axutil_hash_set(om_element->namespaces, "", AXIS2_HASH_KEY_STRING, default_ns); + axiom_namespace_increment_ref(default_ns, env); + return default_ns; +} + +/** + * checks for the namespace in the context of this element + * with the given prefix + */ + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_element_find_namespace_uri( + axiom_element_t * om_element, + const axutil_env_t * env, + const axis2_char_t * prefix, + axiom_node_t * element_node) +{ + axiom_node_t *parent_node = NULL; + axiom_namespace_t *ns = NULL; + + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, element_node, NULL); + AXIS2_PARAM_CHECK(env->error, prefix, NULL); + + if(om_element->namespaces) + { + ns = axutil_hash_get(om_element->namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(ns) + { + return ns; + } + } + + parent_node = axiom_node_get_parent(element_node, env); + if((parent_node) && (axiom_node_get_node_type(parent_node, env) == AXIOM_ELEMENT)) + { + axiom_element_t *parent_ele = NULL; + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(parent_ele) + { + return axiom_element_find_namespace_uri(parent_ele, env, prefix, parent_node); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_get_attribute_value( + axiom_element_t * om_element, + const axutil_env_t * env, + axutil_qname_t * qname) +{ + axis2_char_t *name = NULL; + axiom_attribute_t *attr = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, qname, NULL); + + name = axutil_qname_to_string(qname, env); + + if((om_element->attributes) && (NULL != name)) + { + attr = (axiom_attribute_t *)axutil_hash_get(om_element->attributes, name, + AXIS2_HASH_KEY_STRING); + if(attr) + { + return axiom_attribute_get_value(attr, env); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_namespace_with_no_find_in_current_scope( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_namespace_t * om_ns) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_ns, AXIS2_FAILURE); + om_element->ns = om_ns; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_element_extract_attributes( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * ele_node) +{ + axutil_hash_index_t *hi = NULL; + axutil_hash_t *ht_cloned = NULL; + + axiom_attribute_t *om_attr = NULL; + axiom_attribute_t *cloned_attr = NULL; + + axiom_namespace_t *om_ns = NULL; + /*axiom_namespace_t *cloned_ns = NULL; */ + + axis2_char_t *key = NULL; + axutil_qname_t *qn = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + if(!om_element->attributes) + { + return NULL; + } + ht_cloned = axutil_hash_make(env); + if(!ht_cloned) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) + { + void *val = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + om_attr = (axiom_attribute_t *)val; + cloned_attr = axiom_attribute_clone(om_attr, env); + + om_ns = axiom_attribute_get_namespace(om_attr, env); + if(om_ns) + { + /*cloned_ns = axiom_namespace_clone(om_ns, env); */ + /*axiom_attribute_set_namespace(cloned_attr, env, cloned_ns); */ + axiom_attribute_set_namespace(cloned_attr, env, om_ns); + } + qn = axiom_attribute_get_qname(cloned_attr, env); + key = axutil_qname_to_string(qn, env); + axutil_hash_set(ht_cloned, key, AXIS2_HASH_KEY_STRING, cloned_attr); + } + val = NULL; + key = NULL; + qn = NULL; + om_attr = NULL; + cloned_attr = NULL; + om_ns = NULL; + /*cloned_ns = NULL; */ + } + return ht_cloned; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_element_get_attribute_value_by_name( + axiom_element_t * om_element, + const axutil_env_t * env, + axis2_char_t * attr_name) +{ + axutil_hash_index_t *hi = NULL; + + AXIS2_PARAM_CHECK(env->error, attr_name, NULL); + if(!om_element->attributes) + { + return NULL; + } + for(hi = axutil_hash_first(om_element->attributes, env); hi; hi = axutil_hash_next(env, hi)) + { + void *attr = NULL; + axiom_attribute_t *om_attr = NULL; + axutil_hash_this(hi, NULL, NULL, &attr); + if(attr) + { + axis2_char_t *this_attr_name; + axis2_char_t *this_attr_value; + axis2_char_t *attr_qn_str = NULL; + axiom_namespace_t *attr_ns = NULL; + axis2_char_t *prefix = NULL; + + om_attr = (axiom_attribute_t *)attr; + this_attr_name = axiom_attribute_get_localname(om_attr, env); + this_attr_value = axiom_attribute_get_value(om_attr, env); + attr_ns = axiom_attribute_get_namespace(om_attr, env); + if(attr_ns) + { + prefix = axiom_namespace_get_prefix(attr_ns, env); + if(prefix) + { + axis2_char_t *tmp_val = NULL; + tmp_val = axutil_stracat(env, prefix, ":"); + attr_qn_str = axutil_stracat(env, tmp_val, this_attr_name); + if(tmp_val) + { + AXIS2_FREE(env->allocator, tmp_val); + tmp_val = NULL; + } + } + } + else + { + attr_qn_str = axutil_strdup(env, this_attr_name); + } + + if(attr_qn_str && axutil_strcmp(attr_qn_str, attr_name) == 0) + { + AXIS2_FREE(env->allocator, attr_qn_str); + attr_qn_str = NULL; + AXIS2_FREE(env->allocator, hi); + return this_attr_value; + } + + AXIS2_FREE(env->allocator, attr_qn_str); + attr_qn_str = NULL; + } + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_element_create_str( + const axutil_env_t * env, + axiom_node_t * parent, + axutil_string_t * localname, + axiom_namespace_t * ns, + axiom_node_t ** node) +{ + axiom_element_t *element; + AXIS2_ENV_CHECK(env, NULL); + + if(!localname || !node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "localname or node is NULL"); + return NULL; + } + + (*node) = axiom_node_create(env); + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + element = (axiom_element_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_element_t)); + + if(!element) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + element->ns = NULL; + element->localname = NULL; + element->attributes = NULL; + element->namespaces = NULL; + element->qname = NULL; + element->child_ele_iter = NULL; + element->children_iter = NULL; + element->children_qname_iter = NULL; + element->text_value = NULL; + element->next_ns_prefix_number = 0; + element->is_empty = AXIS2_FALSE; + + element->localname = axutil_string_clone(localname, env); + if(!element->localname) + { + AXIS2_FREE(env->allocator, element); + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + axiom_node_set_complete((*node), env, AXIS2_FALSE); + axiom_node_set_node_type((*node), env, AXIOM_ELEMENT); + axiom_node_set_data_element((*node), env, element); + + if(ns) + { + axis2_char_t *uri = NULL; + axis2_char_t *prefix = NULL; + + uri = axiom_namespace_get_uri(ns, env); + prefix = axiom_namespace_get_prefix(ns, env); + + element->ns = axiom_element_find_namespace(element, env, *node, uri, prefix); + if(!(element->ns)) + { + if(axiom_element_declare_namespace(element, env, *node, ns) == AXIS2_SUCCESS) + { + element->ns = ns; + } + } + if(prefix && axutil_strcmp(prefix, "") == 0) + { + element->ns = NULL; + } + } + + return element; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_element_get_localname_str( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + return om_element->localname; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_element_set_localname_str( + axiom_element_t * om_element, + const axutil_env_t * env, + axutil_string_t * localname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + + if(om_element->localname) + { + axutil_string_free(om_element->localname, env); + om_element->localname = NULL; + } + + om_element->localname = axutil_string_clone(localname, env); + + if(!(om_element->localname)) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_element_get_is_empty( + axiom_element_t * om_element, + const axutil_env_t * env) +{ + return om_element->is_empty; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_element_set_is_empty( + axiom_element_t * om_element, + const axutil_env_t * env, + axis2_bool_t is_empty) +{ + om_element->is_empty = is_empty; +} + +/** + * Scan the parents of the element, to determine which namespaces are inscope for the + * the element and its children. + */ +AXIS2_EXTERN axutil_hash_t * AXIS2_CALL +axiom_element_gather_parent_namespaces( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * om_node) +{ + axutil_hash_t *inscope_namespaces = NULL; + axiom_node_t *parent_node = om_node; + + while((parent_node = axiom_node_get_parent(parent_node, env)) && (axiom_node_get_node_type( + parent_node, env) == AXIOM_ELEMENT)) + { + axiom_element_t *parent_element = (axiom_element_t *)axiom_node_get_data_element( + parent_node, env); + axutil_hash_t *parent_namespaces = axiom_element_get_namespaces(parent_element, env); + if(parent_namespaces) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(parent_namespaces, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + /* Check if prefix is already associated with some namespace in node being detached */ + if(!axiom_element_find_declared_namespace(om_element, env, NULL, + axiom_namespace_get_prefix((axiom_namespace_t *)val, env))) + { + axis2_char_t *key = axiom_namespace_get_prefix((axiom_namespace_t *)val, + env); + if(!key) + key = ""; + /* Check if prefix already associated with some namespace in a parent node */ + if(!(inscope_namespaces && axutil_hash_get(inscope_namespaces, key, + AXIS2_HASH_KEY_STRING))) + { + /* Remember this namespace as needing to be declared, if used */ + if(!inscope_namespaces) + inscope_namespaces = axutil_hash_make(env); + if(inscope_namespaces) + axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, val); + } + } + } + } + } + } + + return inscope_namespaces; +} + +/** + * Test if the provided namespace pointer is declared in a parent namespace + * If so, redeclare it in the provided root element + */ +AXIS2_EXTERN void AXIS2_CALL +axiom_element_use_parent_namespace( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * om_node, + axiom_namespace_t *ns, + axiom_element_t * root_element, + axutil_hash_t *inscope_namespaces) +{ + if(ns && inscope_namespaces) + { + axiom_namespace_t *parent_ns; + axis2_char_t *key = axiom_namespace_get_prefix(ns, env); + if(!key) + key = ""; + + parent_ns = axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING); + /* Check if namespace is a namespace declared in a parent and not also + declared at an intermediate level */ + if(parent_ns && (parent_ns == ns) && (ns != axiom_element_find_namespace(om_element, env, + om_node, axiom_namespace_get_uri(ns, env), axiom_namespace_get_prefix(ns, env)))) + { + /* Redeclare this parent namespace at the level of the element being detached */ + axiom_element_declare_namespace_assume_param_ownership(root_element, env, parent_ns); + /* Remove the namespace from the inscope parent namespaces now that it has + been redeclared. */ + axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, NULL); + } + } +} + +/** + * For each child node, determine if it uses a namespace from a parent of the node being detached + * If so, re-declare that namespace in the node being detached + */ +AXIS2_EXTERN void AXIS2_CALL +axiom_element_redeclare_parent_namespaces( + axiom_element_t * om_element, + const axutil_env_t * env, + axiom_node_t * om_node, + axiom_element_t * root_element, + axutil_hash_t *inscope_namespaces) +{ + axiom_node_t *child_node; + axutil_hash_t * attributes; + + if(!om_element || !om_node || !inscope_namespaces) + return; + + /* ensure the element's namespace is declared */ + axiom_element_use_parent_namespace(om_element, env, om_node, om_element->ns, root_element, + inscope_namespaces); + + /* for each attribute, ensure the attribute's namespace is declared */ + attributes = om_element->attributes; + if(attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(attributes, env); hi; hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + axiom_element_use_parent_namespace(om_element, env, om_node, + axiom_attribute_get_namespace((axiom_attribute_t *)val, env), root_element, + inscope_namespaces); + } + } + } + + /* ensure the namespaces in all the children are declared */ + child_node = axiom_node_get_first_child(om_node, env); + while(child_node && (axutil_hash_count(inscope_namespaces) > 0)) + { + if(axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT) + { + axiom_element_redeclare_parent_namespaces(axiom_node_get_data_element(child_node, env), + env, child_node, root_element, inscope_namespaces); + } + child_node = axiom_node_get_next_sibling(child_node, env); + } +} diff --git a/axiom/src/om/om_namespace.c b/axiom/src/om/om_namespace.c new file mode 100644 index 0000000..2d9df2f --- /dev/null +++ b/axiom/src/om/om_namespace.c @@ -0,0 +1,385 @@ +/* + * 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_namespace.h> +#include <axutil_string.h> +#include "axiom_namespace_internal.h" + +struct axiom_namespace +{ + + /** namespace URI */ + axutil_string_t *uri; + + /** namespace prefix */ + axutil_string_t *prefix; + + axis2_char_t *key; + + int ref; +}; + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_namespace_create( + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axiom_namespace_t *om_namespace = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!uri) + { + uri = ""; + } + + om_namespace = (axiom_namespace_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_namespace_t)); + if(!om_namespace) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_namespace->ref = 0; + om_namespace->prefix = NULL; + om_namespace->uri = NULL; + om_namespace->key = NULL; + + om_namespace->uri = axutil_string_create(env, uri); + if(!om_namespace->uri) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(prefix) + { + om_namespace->prefix = axutil_string_create(env, prefix); + if(!om_namespace->prefix) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_FREE(env->allocator, om_namespace->uri); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + return om_namespace; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_namespace_free( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(--om_namespace->ref > 0) + { + return; + } + + if(om_namespace->prefix) + { + axutil_string_free(om_namespace->prefix, env); + } + + if(om_namespace->uri) + { + axutil_string_free(om_namespace->uri, env); + } + + if(om_namespace->key) + { + AXIS2_FREE(env->allocator, om_namespace->key); + } + + AXIS2_FREE(env->allocator, om_namespace); + + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_namespace_equals( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + axiom_namespace_t * om_namespace1) +{ + int uris_differ = 0; + int prefixes_differ = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_namespace, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_namespace1, AXIS2_FAILURE); + + if(!om_namespace || !om_namespace1) + { + return AXIS2_FALSE; + } + + if(om_namespace->uri && om_namespace1->uri) + { + uris_differ = axutil_strcmp(axutil_string_get_buffer(om_namespace->uri, env), + axutil_string_get_buffer(om_namespace1->uri, env)); + } + else + { + uris_differ = (om_namespace->uri || om_namespace1->uri); + } + + if(om_namespace->prefix && om_namespace1->prefix) + { + prefixes_differ = axutil_strcmp(axutil_string_get_buffer(om_namespace->prefix, env), + axutil_string_get_buffer(om_namespace1->prefix, env)); + } + else + { + prefixes_differ = (om_namespace->prefix || om_namespace1->prefix); + } + + return (!uris_differ && !prefixes_differ); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_serialize( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + if(!om_namespace) + { + return AXIS2_FAILURE; + } + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_namespace->uri && NULL != om_namespace->prefix && axutil_strcmp(axutil_string_get_buffer( + om_namespace->prefix, env), "") != 0) + { + status = axiom_output_write(om_output, env, AXIOM_NAMESPACE, 2, axutil_string_get_buffer( + om_namespace-> prefix, env), axutil_string_get_buffer(om_namespace->uri, env)); + } + else if(om_namespace->uri) + { + status = axiom_output_write(om_output, env, AXIOM_NAMESPACE, 2, NULL, + axutil_string_get_buffer(om_namespace->uri, env)); + } + return status; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_namespace_get_uri( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + if(om_namespace->uri) + { + return (axis2_char_t *)axutil_string_get_buffer(om_namespace->uri, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_namespace_get_prefix( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + if(om_namespace->prefix) + { + return (axis2_char_t *)axutil_string_get_buffer(om_namespace->prefix, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_namespace_clone( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + axiom_namespace_t *cloned_ns = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + cloned_ns = axiom_namespace_create_str(env, om_namespace->uri, om_namespace->prefix); + if(cloned_ns) + { + return cloned_ns; + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_namespace_to_string( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + axis2_char_t *temp_str = NULL; + AXIS2_ENV_CHECK(env, NULL); + if(om_namespace->key) + { + AXIS2_FREE(env->allocator, om_namespace->key); + om_namespace->key = NULL; + } + if((om_namespace->uri) && (NULL != om_namespace->prefix)) + { + temp_str = axutil_stracat(env, axutil_string_get_buffer(om_namespace->uri, env), "|"); + om_namespace->key = axutil_stracat(env, temp_str, axutil_string_get_buffer( + om_namespace->prefix, env)); + if(temp_str) + { + AXIS2_FREE(env->allocator, temp_str); + temp_str = NULL; + } + } + else if((om_namespace->uri) && !(om_namespace->prefix)) + { + om_namespace->key = axutil_strdup(env, axutil_string_get_buffer(om_namespace->uri, env)); + if(!(om_namespace->key)) + { + return NULL; + } + } + return om_namespace->key; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_set_uri( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + const axis2_char_t * uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + + if(om_namespace->uri) + { + axutil_string_free(om_namespace->uri, env); + om_namespace->uri = NULL; + } + + om_namespace->uri = axutil_string_create(env, uri); + if(!(om_namespace->uri)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_increment_ref( + struct axiom_namespace * om_namespace, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + om_namespace->ref++; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_namespace_create_str( + const axutil_env_t * env, + axutil_string_t * uri, + axutil_string_t * prefix) +{ + axiom_namespace_t *om_namespace = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!uri) + { + uri = axutil_string_create(env, ""); + } + + om_namespace = (axiom_namespace_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_namespace_t)); + if(!om_namespace) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_namespace->ref = 0; + om_namespace->prefix = NULL; + om_namespace->uri = NULL; + om_namespace->key = NULL; + + om_namespace->uri = axutil_string_clone(uri, env); + if(!om_namespace->uri) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + if(prefix) + { + om_namespace->prefix = axutil_string_clone(prefix, env); + if(!om_namespace->prefix) + { + AXIS2_FREE(env->allocator, om_namespace); + AXIS2_FREE(env->allocator, om_namespace->uri); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + return om_namespace; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_namespace_set_uri_str( + axiom_namespace_t * om_namespace, + const axutil_env_t * env, + axutil_string_t * uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + + if(om_namespace->uri) + { + axutil_string_free(om_namespace->uri, env); + om_namespace->uri = NULL; + } + + om_namespace->uri = axutil_string_clone(uri, env); + if(!(om_namespace->uri)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_namespace_get_uri_str( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + return om_namespace->uri; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_namespace_get_prefix_str( + axiom_namespace_t * om_namespace, + const axutil_env_t * env) +{ + return om_namespace->prefix; +} diff --git a/axiom/src/om/om_navigator.c b/axiom/src/om/om_navigator.c new file mode 100644 index 0000000..c0405b8 --- /dev/null +++ b/axiom/src/om/om_navigator.c @@ -0,0 +1,206 @@ +/* + * 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_navigator.h> + +static void +axiom_navigator_update_next_node( + axiom_navigator_t * om_navigator, + const axutil_env_t * env); + +struct axiom_navigator +{ + axiom_node_t *node; + + axis2_bool_t visited; + + axiom_node_t *next; + + axiom_node_t *root; + + axis2_bool_t backtracked; + + axis2_bool_t end; + + axis2_bool_t start; + +}; + +AXIS2_EXTERN axiom_navigator_t *AXIS2_CALL +axiom_navigator_create( + const axutil_env_t * env, + axiom_node_t * om_node) +{ + axiom_navigator_t *om_navigator = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + om_navigator = (axiom_navigator_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_navigator_t)); + if(!om_navigator) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_navigator->node = NULL; + om_navigator->visited = AXIS2_FALSE; + om_navigator->next = NULL; + om_navigator->root = NULL; + om_navigator->end = AXIS2_FALSE; + om_navigator->start = AXIS2_TRUE; + om_navigator->backtracked = AXIS2_FALSE; + + om_navigator->next = om_node; + om_navigator->root = om_node; + + return om_navigator; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_navigator_free( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_FREE(env->allocator, om_navigator); + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_navigator_is_navigable( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + if(AXIS2_TRUE == om_navigator->end) + { + return AXIS2_FALSE; + } + else + { + if(om_navigator->next) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_navigator_is_completed( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + return om_navigator->end; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_navigator_visited( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + return om_navigator->visited; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_navigator_next( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + + if(!om_navigator->next) + { + return NULL; + } + + om_navigator->node = om_navigator->next; + om_navigator->visited = om_navigator->backtracked; + om_navigator->backtracked = AXIS2_FALSE; + + axiom_navigator_update_next_node(om_navigator, env); + + /** set the starting and ending flags */ + if(om_navigator->root == om_navigator->next) + { + if(!(om_navigator->start)) + { + om_navigator->end = AXIS2_TRUE; + } + else + { + om_navigator->start = AXIS2_FALSE; + } + } + return om_navigator->node; +} + +/** this method encapsulate searching logic */ +static void +axiom_navigator_update_next_node( + axiom_navigator_t * om_navigator, + const axutil_env_t * env) +{ + if(!om_navigator) + { + return; + } + + if(!om_navigator->next) + { + return; + } + + if((AXIOM_ELEMENT == axiom_node_get_node_type(om_navigator->next, env)) + && !(om_navigator->visited)) + { + if(axiom_node_get_first_child(om_navigator->next, env)) + { + om_navigator->next = axiom_node_get_first_child(om_navigator->next, env); + } + else if(AXIS2_TRUE == axiom_node_is_complete(om_navigator->next, env)) + { + om_navigator->backtracked = AXIS2_TRUE; + } + else + { + om_navigator->next = NULL; + } + } + else + { + axiom_node_t *parent = NULL; + axiom_node_t *next_sibling = NULL; + + next_sibling = axiom_node_get_next_sibling(om_navigator->next, env); + + parent = axiom_node_get_parent(om_navigator->next, env); + + if(next_sibling) + { + om_navigator->next = next_sibling; + } + else if((parent) && axiom_node_is_complete(parent, env)) + { + om_navigator->next = parent; + om_navigator->backtracked = AXIS2_TRUE; + } + else + { + om_navigator->next = NULL; + } + } +} diff --git a/axiom/src/om/om_node.c b/axiom/src/om/om_node.c new file mode 100644 index 0000000..9b525aa --- /dev/null +++ b/axiom/src/om/om_node.c @@ -0,0 +1,1455 @@ +/* + * 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_node_internal.h" +#include "axiom_stax_builder_internal.h" +#include <axiom_element.h> +#include <axiom_text.h> +#include <axiom_data_source.h> +#include <axiom_comment.h> +#include <axiom_processing_instruction.h> +#include <axiom_doctype.h> +#include <axiom_document.h> +#include <axiom_stax_builder.h> + +struct axiom_node +{ + + /** document only available if build through builder */ + struct axiom_document *om_doc; + + axiom_stax_builder_t *builder; + + /** parent node */ + axiom_node_t *parent; + + /** previous sibling */ + axiom_node_t *prev_sibling; + + /** next sibling */ + axiom_node_t *next_sibling; + + /** first child */ + axiom_node_t *first_child; + + /** last child */ + axiom_node_t *last_child; + + /** node type, indicates the type stored in data_element */ + axiom_types_t node_type; + + /** done true means that this node is completely built , false otherwise */ + int done; + + /** instances of an om struct, whose type is defined by node type */ + void *data_element; + +}; + +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) +{ + axiom_node_t *node = NULL; + AXIS2_ENV_CHECK(env, NULL); + + node = (axiom_node_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_node_t)); + if(!node) + { + env->error->error_number = AXIS2_ERROR_NO_MEMORY; + return NULL; + } + node->first_child = NULL; + node->last_child = NULL; + node->next_sibling = NULL; + node->prev_sibling = NULL; + node->parent = NULL; + node->node_type = AXIOM_INVALID; + node->done = AXIS2_FALSE; + node->data_element = NULL; + node->om_doc = NULL; + node->builder = NULL; + return node; +} + +AXIS2_EXTERN axiom_node_t* AXIS2_CALL +axiom_node_create_from_buffer( + const axutil_env_t * env, + axis2_char_t *buffer) +{ + axiom_xml_reader_t *reader = NULL; + axiom_stax_builder_t *builder = NULL; + axiom_document_t *document = NULL; + axiom_node_t *om_node = NULL; + + reader = axiom_xml_reader_create_for_memory(env, buffer, axutil_strlen(buffer), "UTF-8", + AXIS2_XML_PARSER_TYPE_BUFFER); + + if(!reader) + { + return NULL; + } + + builder = axiom_stax_builder_create(env, reader); + + if(!builder) + { + return NULL; + } + document = axiom_stax_builder_get_document(builder, env); + if(!document) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Document is null for deserialization"); + return NULL; + } + + om_node = axiom_document_get_root_element(document, env); + + if(!om_node) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Root element of the document is not found"); + return NULL; + } + axiom_document_build_all(document, env); + + axiom_stax_builder_free_self(builder, env); + + return om_node; +} + +static void +axiom_node_free_detached_subtree( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + /* Free any child nodes first */ + if(om_node->first_child) + { + axiom_node_t *child_node = om_node->first_child, *next_sibling; + while(child_node) + { + next_sibling = child_node->next_sibling; + axiom_node_free_detached_subtree(child_node, env); + child_node = next_sibling; + } + } + + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + axiom_element_free((axiom_element_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_COMMENT) + { + if(om_node->data_element) + { + axiom_comment_free((axiom_comment_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_DOCTYPE) + { + /*axiom_doctype_free((axiom_doctype_t*)(om_node->data_element), env); */ + } + else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION) + { + if(om_node->data_element) + { + axiom_processing_instruction_free( + (axiom_processing_instruction_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_TEXT) + { + if(om_node->data_element) + { + axiom_text_free((axiom_text_t *)(om_node->data_element), env); + } + } + else if(om_node->node_type == AXIOM_DATA_SOURCE) + { + if(om_node->data_element) + { + axiom_data_source_free((axiom_data_source_t *)(om_node->data_element), env); + } + } + + AXIS2_FREE(env->allocator, om_node); + + return; +} + +/** + * This free function will free an om_element and all the children contained in it + * If the node is still attached to the tree, it will be detached first + */ +AXIS2_EXTERN void AXIS2_CALL +axiom_node_free_tree( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + if(!om_node) + { + return; + } + + /* Detach this node before freeing it and its subtree. */ + axiom_node_detach_without_namespaces(om_node, env); + + /* Free this node and its subtree */ + axiom_node_free_detached_subtree(om_node, env); + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_add_child( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * child) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, child, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + + if(child->parent) + { + child = axiom_node_detach(child, env); + } + + if(!(om_node->first_child)) + { + om_node->first_child = child; + } + else + { + axiom_node_t *last_sib = NULL; + last_sib = om_node->last_child; + if(last_sib) + { + last_sib->next_sibling = child; + child->prev_sibling = last_sib; + } + } + + child->parent = om_node; + om_node->last_child = child; + return AXIS2_SUCCESS; +} + +/** + * Detach the node without regard to any namespace references in the node or + * its children. + */ +static axiom_node_t * +axiom_node_detach_without_namespaces( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axiom_node_t *parent = NULL; + + parent = om_node->parent; + if(!parent) + { + /* Node is already detached */ + om_node->builder = NULL; + return om_node; + } + + if(!om_node->prev_sibling) + { + parent->first_child = om_node->next_sibling; + } + else + { + axiom_node_t *prev_sib = NULL; + prev_sib = om_node->prev_sibling; + if(prev_sib) + { + prev_sib->next_sibling = om_node->next_sibling; + } + } + + if(om_node->next_sibling) + { + axiom_node_t *next_sibling = NULL; + next_sibling = om_node->next_sibling; + if(next_sibling) + { + next_sibling->prev_sibling = om_node->prev_sibling; + } + } + + if(parent->last_child && (parent->last_child == om_node)) + { + parent->last_child = om_node->prev_sibling; + } + + /* if the STAX builder's last node is what we are detaching, then we should adjust the + * last node if previous sibling is available, set that as the builder's last node. Else set the + * parent as the last node*/ + if(om_node->builder && (axiom_stax_builder_get_lastnode(om_node->builder, env) == om_node)) + { + axiom_node_t *lastnode = parent; + if(om_node->prev_sibling) + { + lastnode = om_node->prev_sibling; + } + axiom_stax_builder_set_lastnode(om_node->builder, env, lastnode); + } + + om_node->parent = NULL; + om_node->prev_sibling = NULL; + om_node->next_sibling = NULL; + om_node->builder = NULL; + return om_node; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_detach( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axutil_hash_t *inscope_namespaces = NULL; + axiom_element_t *om_element = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!om_node) + { + return NULL; + } + + /* If this is an element node, determine which namespaces are available to it + from its parent nodes. */ + if((om_node->node_type == AXIOM_ELEMENT) && (om_element = om_node->data_element)) + { + inscope_namespaces = axiom_element_gather_parent_namespaces(om_element, env, om_node); + } + + /* Detach this node from its parent. */ + om_node = axiom_node_detach_without_namespaces(om_node, env); + + /* If this is an element node, ensure that any namespaces available to it or its + children remain available after the detach. */ + if(om_node && inscope_namespaces) + { + axiom_element_redeclare_parent_namespaces(om_element, env, om_node, om_element, + inscope_namespaces); + } + + if(inscope_namespaces) + { + axutil_hash_free(inscope_namespaces, env); + } + + return om_node; +} + +/** + Internal function , only used in om and soap + not to be used by users + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_parent( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * parent) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(!om_node) + { + return AXIS2_FAILURE; + } + + AXIS2_PARAM_CHECK(env->error, parent, AXIS2_FAILURE); + + if(parent == om_node->parent) + { /* same parent already exist */ + return AXIS2_SUCCESS; + } + /* if a new parent is assigned in place of existing + one first the node should be detached + */ + if(om_node->parent) + { + om_node = axiom_node_detach_without_namespaces(om_node, env); + } + + om_node->parent = parent; + + return AXIS2_SUCCESS; +} + +/** + * This will insert a sibling just after the current information item + * @param node the node in consideration + * @param nodeto_insert the node that will be inserted + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_insert_sibling_after( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * node_to_insert) +{ + axiom_node_t *next_sib = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + AXIS2_PARAM_CHECK(env->error, node_to_insert, AXIS2_FAILURE); + + if(!om_node->parent) + { + /* We shouldn't add a sibling because this node doesn't has a parent. + * This can be the root node of the tree*/ + return AXIS2_FAILURE; + } + + node_to_insert->parent = om_node->parent; + + node_to_insert->prev_sibling = om_node; + + next_sib = om_node->next_sibling; + + if(next_sib) + { + next_sib->prev_sibling = node_to_insert; + } + + node_to_insert->next_sibling = om_node->next_sibling; + + om_node->next_sibling = node_to_insert; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_insert_sibling_before( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * node_to_insert) +{ + axiom_node_t *prev_sibling = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, node_to_insert, AXIS2_FAILURE); + + if(!om_node->parent) + { + /* We shouldn't add a sibling because this node doesn't has a parent. + * This can be the root node of the tree*/ + return AXIS2_FAILURE; + } + + node_to_insert->parent = om_node->parent; + + node_to_insert->prev_sibling = om_node->prev_sibling; + + node_to_insert->next_sibling = om_node; + + prev_sibling = om_node->prev_sibling; + + if(!prev_sibling) + { + axiom_node_t *parent = om_node->parent; + parent->first_child = node_to_insert; + } + else + { + axiom_node_t *prev_sibling = om_node->prev_sibling; + if(prev_sibling) + { + prev_sibling->next_sibling = node_to_insert; + } + } + om_node->prev_sibling = node_to_insert; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_serialize( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + + int status = AXIS2_SUCCESS; + axiom_node_t *temp_node = NULL; + axiom_node_t *nodes[256]; + int count = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!om_node) + { + return AXIS2_SUCCESS; + } + + nodes[count++] = om_node; + + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + do + { + + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + status = axiom_element_serialize_start_part( + (axiom_element_t *)(om_node-> data_element), env, om_output, om_node); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_DATA_SOURCE) + { + if(om_node->data_element) + { + status = axiom_data_source_serialize( + (axiom_data_source_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_TEXT) + { + if(om_node->data_element) + { + status = axiom_text_serialize((axiom_text_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_COMMENT) + { + if(om_node->data_element) + { + status = axiom_comment_serialize((axiom_comment_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_DOCTYPE) + { + if(om_node->data_element) + { + status = axiom_doctype_serialize((axiom_doctype_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION) + { + if(om_node->data_element) + { + status = axiom_processing_instruction_serialize( + (axiom_processing_instruction_t *)(om_node->data_element), env, om_output); + } + + if(status != AXIS2_SUCCESS) + { + return status; + } + } + + 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 + { + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node-> data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + + 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]; + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + return status; + } + } + + 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); + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_serialize_sub_tree( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + + int status = AXIS2_SUCCESS; + axiom_node_t *temp_node = NULL; + axiom_node_t *nodes[256]; + int count = 0; + axutil_hash_t *namespaces = NULL; + axutil_hash_t *namespaces_from_parents = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + if(!om_node) + { + return AXIS2_SUCCESS; + } + + namespaces = axutil_hash_make(env); + if(!namespaces) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "hash for namespaces creation failed"); + return AXIS2_FAILURE; + } + + namespaces_from_parents = axutil_hash_make(env); + if(!namespaces_from_parents) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "hash for namespaces_from_parents creation failed"); + return AXIS2_FAILURE; + } + + nodes[count++] = om_node; + + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + do + { + + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + axutil_hash_t *temp_namespaces = NULL; + axutil_hash_t *temp_attributes = NULL; + axiom_namespace_t *namespace = NULL; + status = axiom_element_serialize_start_part( + (axiom_element_t *)(om_node-> data_element), env, om_output, om_node); + temp_namespaces = axiom_element_get_namespaces( + (axiom_element_t *)(om_node-> data_element), env); + if(temp_namespaces) + { + axutil_hash_t *new_hash = NULL; + new_hash = axutil_hash_overlay(temp_namespaces, env, namespaces); + if(namespaces) + axutil_hash_free(namespaces, env); + namespaces = new_hash; + } + namespace = axiom_element_get_namespace( + (axiom_element_t *)(om_node-> data_element), env, om_node); + if(namespace) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(!ns) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(!ns) + { + axiom_namespace_serialize(namespace, env, om_output); + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, namespace); + } + } + } + } + + temp_attributes = axiom_element_get_all_attributes( + (axiom_element_t *)(om_node->data_element), env); + if(temp_attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(temp_attributes, env); hi; hi = axutil_hash_next( + env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + + namespace + = axiom_attribute_get_namespace((axiom_attribute_t *)val, env); + + if(namespace) + { + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces, prefix, AXIS2_HASH_KEY_STRING); + if(!ns) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(!ns) + { + axiom_namespace_serialize(namespace, env, om_output); + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, namespace); + } + } + } + } + } + else + { + status = AXIS2_FAILURE; + } + } + } + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_DATA_SOURCE) + { + if(om_node->data_element) + { + status = axiom_data_source_serialize( + (axiom_data_source_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_TEXT) + { + if(om_node->data_element) + { + status = axiom_text_serialize((axiom_text_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_COMMENT) + { + if(om_node->data_element) + { + status = axiom_comment_serialize((axiom_comment_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_DOCTYPE) + { + if(om_node->data_element) + { + status = axiom_doctype_serialize((axiom_doctype_t *)(om_node-> data_element), env, + om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + else if(om_node->node_type == AXIOM_PROCESSING_INSTRUCTION) + { + if(om_node->data_element) + { + status = axiom_processing_instruction_serialize( + (axiom_processing_instruction_t *)(om_node->data_element), env, om_output); + } + + if(status != AXIS2_SUCCESS) + { + break; + } + } + + 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 + { + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + + axutil_hash_t *temp_attributes = NULL; + axiom_namespace_t *namespace = NULL; + /* at the writing of end part all the namespaces declared + specially to that element should be cancelled */ + + /* first checking the element namespace */ + namespace = axiom_element_get_namespace( + (axiom_element_t *)(om_node-> data_element), env, om_node); + if(namespace) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, NULL); + } + } + } + + /* then checking the attribute namespaces */ + + temp_attributes = axiom_element_get_all_attributes( + (axiom_element_t *)(om_node->data_element), env); + if(temp_attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(temp_attributes, env); hi; hi + = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + + namespace = axiom_attribute_get_namespace((axiom_attribute_t *)val, + env); + + if(namespace) + { + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, NULL); + } + } + } + } + } + } + + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node-> data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + /* We need to make make sure that om_node is not the root when we take the next sibling */ + if(count > 1) + { + 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]; + if(om_node->node_type == AXIOM_ELEMENT) + { + if(om_node->data_element) + { + axutil_hash_t *temp_attributes = NULL; + axiom_namespace_t *namespace = NULL; + + /* similar to the earlier time, whenever the ending is happened + * namespaces declared specially to that element should be cancelled */ + + /* first checking the element namespace */ + namespace = axiom_element_get_namespace( + (axiom_element_t *)(om_node-> data_element), env, om_node); + if(namespace) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, prefix, + AXIS2_HASH_KEY_STRING, NULL); + } + } + } + + /* then checking the attribute namespaces */ + + temp_attributes = axiom_element_get_all_attributes( + (axiom_element_t *)(om_node->data_element), env); + if(temp_attributes) + { + axutil_hash_index_t *hi; + void *val; + for(hi = axutil_hash_first(temp_attributes, env); hi; hi + = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_namespace_t *ns = NULL; + axis2_char_t *prefix = NULL; + + namespace = axiom_attribute_get_namespace( + (axiom_attribute_t *)val, env); + + if(namespace) + { + prefix = axiom_namespace_get_prefix(namespace, env); + if(prefix) + { + ns = axutil_hash_get(namespaces_from_parents, + prefix, AXIS2_HASH_KEY_STRING); + if(ns) + { + axutil_hash_set(namespaces_from_parents, + prefix, AXIS2_HASH_KEY_STRING, NULL); + } + } + } + } + } + } + status = axiom_element_serialize_end_part( + (axiom_element_t *)(om_node->data_element), env, om_output); + } + if(status != AXIS2_SUCCESS) + { + break; + } + } + + 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(namespaces_from_parents, env); + axutil_hash_free(namespaces, env); + + return status; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_parent( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->parent; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_first_child( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int token = 0; + if(!om_node) + { + return NULL; + } + + /**********************************************************/ + while(!(om_node->first_child) && !(om_node->done) && om_node->builder) + { + token = axiom_stax_builder_next_with_token(om_node->builder, env); + if(token == -1) + { + return NULL; + } + } + + /**********************************************************/ + return om_node->first_child; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_first_element( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int token = 0; + axiom_node_t *first_element; + if(!om_node) + { + return NULL; + } + + /**********************************************************/ + while(!(om_node->first_child) && !(om_node->done) && om_node->builder) + { + token = axiom_stax_builder_next_with_token(om_node->builder, env); + if(token == -1) + { + return NULL; + } + } + + /**********************************************************/ + first_element = om_node->first_child; + + while(first_element && (axiom_node_get_node_type(first_element, env) != AXIOM_ELEMENT)) + { + first_element = axiom_node_get_next_sibling(first_element, env); + } + + return first_element; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_last_child( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->last_child; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_previous_sibling( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->prev_sibling; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_get_next_sibling( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int token = 0; + if(!om_node) + { + return NULL; + } + + while(!(om_node->next_sibling) && om_node->parent && om_node->builder + && !(axiom_node_is_complete(om_node->parent, env))) + { + token = axiom_stax_builder_next_with_token(om_node->builder, env); + if(token == -1) + { + return NULL; + } + } + + return om_node->next_sibling; +} + +AXIS2_EXTERN axiom_types_t AXIS2_CALL +axiom_node_get_node_type( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->node_type; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_node_is_complete( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->done; + +} + +AXIS2_EXTERN struct axiom_document *AXIS2_CALL +axiom_node_get_document( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->om_doc; +} + +AXIS2_EXTERN void *AXIS2_CALL +axiom_node_get_data_element( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + return om_node->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 +axiom_node_set_first_child( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * first_child) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, first_child, AXIS2_FAILURE); + + /** set the parent */ + axiom_node_set_parent(first_child, env, om_node); + + om_node->first_child = first_child; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + only sets the previous sibling link as it is needed by builders + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_previous_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * prev_sibling) +{ + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prev_sibling, AXIS2_FAILURE); + + om_node->prev_sibling = prev_sibling; + return AXIS2_SUCCESS; +} + +/** + internal function, not to be used by users + only sets the next sibling link; + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_next_sibling( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_node_t * next_sibling) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, next_sibling, AXIS2_FAILURE); + om_node->next_sibling = next_sibling; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + sets the node type only used in soap and om + */ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_node_type( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_types_t type) +{ + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + om_node->node_type = type; + return AXIS2_SUCCESS; +} + +/** + internal function , not to be used by users + only used in om and soap + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_data_element( + axiom_node_t * om_node, + const axutil_env_t * env, + void *data_element) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data_element, AXIS2_FAILURE); + om_node->data_element = data_element; + return AXIS2_SUCCESS; +} + +/** + internal function not to be used by users + only sets the build status + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_node_set_complete( + axiom_node_t * om_node, + const axutil_env_t * env, + axis2_bool_t done) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_node, AXIS2_FAILURE); + om_node->done = done; + return AXIS2_SUCCESS; +} + +/** + 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 +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); + 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, + const axutil_env_t * env) +{ + if(!om_node) + { + return NULL; + } + return om_node->builder; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_node_to_string( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_output_t *om_output = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *xml = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + return NULL; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + axiom_xml_writer_free(xml_writer, env); + return NULL; + } + status = axiom_node_serialize(om_node, env, om_output); + if(status == AXIS2_SUCCESS) + { + xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env)); + } + axiom_output_free(om_output, env); + return xml; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_node_sub_tree_to_string( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_output_t *om_output = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *xml = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + return NULL; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + axiom_xml_writer_free(xml_writer, env); + return NULL; + } + status = axiom_node_serialize_sub_tree(om_node, env, om_output); + if(status == AXIS2_SUCCESS) + { + xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env)); + } + axiom_output_free(om_output, env); + return xml; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_node_to_string_non_optimized( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_output_t *om_output = NULL; + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *xml = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + return NULL; + } + + om_output = axiom_output_create(env, xml_writer); + if(!om_output) + { + axiom_xml_writer_free(xml_writer, env); + return NULL; + } + /*This is where we set the output to be non-optimized*/ + axiom_output_set_do_optimize(om_output, env, AXIS2_FALSE); + status = axiom_node_serialize(om_node, env, om_output); + if(status == AXIS2_SUCCESS) + { + xml = axutil_strdup(env, (axis2_char_t *)axiom_xml_writer_get_xml(xml_writer, env)); + } + axiom_output_free(om_output, env); + return xml; +} + 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; +} + diff --git a/axiom/src/om/om_processing_instruction.c b/axiom/src/om/om_processing_instruction.c new file mode 100644 index 0000000..5be688b --- /dev/null +++ b/axiom/src/om/om_processing_instruction.c @@ -0,0 +1,187 @@ +/* + * 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_processing_instruction.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" + +struct axiom_processing_instruction +{ + + /** processing instruction target */ + axis2_char_t *target; + + /** processing instruction value */ + axis2_char_t *value; +}; + +AXIS2_EXTERN axiom_processing_instruction_t *AXIS2_CALL +axiom_processing_instruction_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * target, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_processing_instruction_t *processing_instruction = NULL; + AXIS2_ENV_CHECK(env, NULL); + + if(!node || !target || !value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Node or target or value is NULL"); + return NULL; + } + + *node = axiom_node_create(env); + + if(!*node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + processing_instruction = (axiom_processing_instruction_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_processing_instruction_t)); + + if(!processing_instruction) + { + AXIS2_FREE(env->allocator, (*node)); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + processing_instruction->value = NULL; + + if(value) + { + processing_instruction->value = (axis2_char_t *)axutil_strdup(env, value); + if(!processing_instruction->value) + { + AXIS2_FREE(env->allocator, processing_instruction); + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + + processing_instruction->target = NULL; + + if(target) + { + processing_instruction->target = (axis2_char_t *)axutil_strdup(env, target); + if(!processing_instruction->target) + { + AXIS2_FREE(env->allocator, processing_instruction->value); + AXIS2_FREE(env->allocator, processing_instruction); + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + } + axiom_node_set_data_element(*node, env, processing_instruction); + axiom_node_set_node_type(*node, env, AXIOM_PROCESSING_INSTRUCTION); + if(parent) + { + axiom_node_add_child(parent, env, (*node)); + } + + return processing_instruction; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_processing_instruction_free( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(om_pi->value) + { + AXIS2_FREE(env->allocator, om_pi->value); + om_pi->value = NULL; + } + + if(om_pi->target) + { + AXIS2_FREE(env->allocator, om_pi->target); + om_pi->target = NULL; + } + + AXIS2_FREE(env->allocator, om_pi); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_processing_instruction_set_value( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + om_pi->value = (axis2_char_t *)axutil_strdup(env, value); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_processing_instruction_set_target( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env, + const axis2_char_t * target) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE); + om_pi->target = (axis2_char_t *)axutil_strdup(env, target); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_processing_instruction_get_value( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env) +{ + return om_pi->value; +} +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_processing_instruction_get_target( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env) +{ + return om_pi->target; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_processing_instruction_serialize( + axiom_processing_instruction_t * om_pi, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(om_pi->target && om_pi->value) + { + return axiom_output_write(om_output, env, AXIOM_PROCESSING_INSTRUCTION, 2, om_pi->target, + om_pi->value); + } + else if(om_pi->target) + { + return axiom_output_write(om_output, env, AXIOM_PROCESSING_INSTRUCTION, 2, om_pi->target, + om_pi->value); + } + return AXIS2_FAILURE; +} 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 diff --git a/axiom/src/om/om_text.c b/axiom/src/om/om_text.c new file mode 100644 index 0000000..453c395 --- /dev/null +++ b/axiom/src/om/om_text.c @@ -0,0 +1,637 @@ +/* + * 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_text.h> +#include <axiom_output.h> +#include <axutil_string.h> +#include "axiom_node_internal.h" +#include <axiom_xml_writer.h> +#include <axiom_output.h> +#include <axiom_attribute.h> +#include <axiom_namespace.h> +#include <axutil_base64.h> + +static axis2_bool_t AXIS2_CALL axiom_text_get_is_binary( + axiom_text_t * om_text, + const axutil_env_t * env); + +static axis2_status_t AXIS2_CALL axiom_text_serialize_start_part( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output); + +struct axiom_text +{ + + /** Text value */ + axutil_string_t *value; + + /** The following fields are for MTOM */ + axis2_char_t *mime_type; + axis2_bool_t optimize; + const axis2_char_t *localname; + axis2_bool_t is_binary; + axis2_bool_t is_swa; + axis2_char_t *content_id; + axiom_attribute_t *om_attribute; + axiom_namespace_t *ns; + axiom_data_handler_t *data_handler; +}; + +AXIS2_EXTERN axiom_text_t *AXIS2_CALL +axiom_text_create( + const axutil_env_t * env, + axiom_node_t * parent, + const axis2_char_t * value, + axiom_node_t ** node) +{ + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + om_text = (axiom_text_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_text_t)); + if(!om_text) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_text->mime_type = NULL; + om_text->optimize = AXIS2_FALSE; + om_text->localname = "Include"; + om_text->is_binary = AXIS2_FALSE; + om_text->is_swa = AXIS2_FALSE; + om_text->content_id = NULL; + om_text->om_attribute = NULL; + om_text->value = NULL; + om_text->ns = NULL; + om_text->data_handler = NULL; + om_text->mime_type = NULL; + + if(value) + { + om_text->value = axutil_string_create(env, value); + } + + axiom_node_set_data_element((*node), env, om_text); + axiom_node_set_node_type((*node), env, AXIOM_TEXT); + axiom_node_set_complete((*node), env, AXIS2_FALSE); + + if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_node_add_child(parent, env, (*node)); + } + + return om_text; +} + +AXIS2_EXTERN axiom_text_t *AXIS2_CALL +axiom_text_create_with_data_handler( + const axutil_env_t * env, + axiom_node_t * parent, + axiom_data_handler_t * data_handler, + axiom_node_t ** node) +{ + + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, data_handler, NULL); + + om_text = (axiom_text_t *)axiom_text_create(env, parent, NULL, node); + if(!om_text) + { + return NULL; + } + om_text->optimize = AXIS2_TRUE; + om_text->is_binary = AXIS2_TRUE; + om_text->data_handler = data_handler; + om_text->mime_type = axiom_data_handler_get_content_type(data_handler, env); + return om_text; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_text_free( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(om_text->value) + { + axutil_string_free(om_text->value, env); + } + + if(om_text->ns) + { + axiom_namespace_free(om_text->ns, env); + } + + if(om_text->content_id) + { + AXIS2_FREE(env->allocator, om_text->content_id); + } + + if(om_text->om_attribute) + { + axiom_attribute_free(om_text->om_attribute, env); + } + + if(om_text->data_handler) + { + axiom_data_handler_free(om_text->data_handler, env); + } + + AXIS2_FREE(env->allocator, om_text); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_serialize( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + int status = AXIS2_SUCCESS; + axis2_char_t *attribute_value = NULL; + const axis2_char_t *text = NULL; + axiom_xml_writer_t *om_output_xml_writer = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + if(!axiom_text_get_is_binary(om_text, env)) + { + if(om_text->value) + { + status = axiom_output_write(om_output, env, AXIOM_TEXT, 1, axutil_string_get_buffer( + om_text->value, env)); + } + } + else + { + om_output_xml_writer = axiom_output_get_xml_writer(om_output, env); + if(axiom_output_is_optimized(om_output, env) && om_text->optimize) + { + if(!(axiom_text_get_content_id(om_text, env))) + { + axis2_char_t *content_id = axiom_output_get_next_content_id(om_output, env); + if(content_id) + { + om_text->content_id = axutil_strdup(env, content_id); + } + } + + attribute_value = axutil_stracat(env, "cid:", om_text->content_id); + + /*send binary as MTOM optimised */ + if(om_text->om_attribute) + { + axiom_attribute_free(om_text->om_attribute, env); + om_text->om_attribute = NULL; + } + + om_text->om_attribute = axiom_attribute_create(env, "href", attribute_value, NULL); + + AXIS2_FREE(env->allocator, attribute_value); + attribute_value = NULL; + + if(!om_text->is_swa) /* This is a hack to get SwA working */ + { + axiom_text_serialize_start_part(om_text, env, om_output); + } + else + { + status = axiom_output_write(om_output, env, AXIOM_TEXT, 1, om_text->content_id); + } + + axiom_output_write_optimized(om_output, env, om_text); + + axiom_output_write(om_output, env, AXIOM_ELEMENT, 0); + } + else + { + text = axiom_text_get_text(om_text, env); + axiom_xml_writer_write_characters(om_output_xml_writer, env, (axis2_char_t *)text); + } + } + return status; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_text_get_value( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + if(om_text->value) + { + return axutil_string_get_buffer(om_text->value, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_value( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + + if(om_text->value) + { + axutil_string_free(om_text->value, env); + om_text->value = NULL; + } + + om_text->value = axutil_string_create(env, value); + if(!om_text->value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +/*Following has been implemented for the MTOM support*/ + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_text_get_mime_type( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->mime_type; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_mime_type( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_char_t * mime_type) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + if(om_text->mime_type) + { + AXIS2_FREE(env->allocator, om_text->mime_type); + } + om_text->mime_type = (axis2_char_t *)axutil_strdup(env, mime_type); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_text_get_optimize( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->optimize; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_optimize( + axiom_text_t * om_text, + const axutil_env_t * env, + axis2_bool_t optimize) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + om_text->optimize = optimize; + return AXIS2_SUCCESS; +} + +static axis2_bool_t AXIS2_CALL +axiom_text_get_is_binary( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->is_binary; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_is_binary( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_bool_t is_binary) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + om_text->is_binary = is_binary; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_text_get_localname( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->localname; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_text_get_content_id( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->content_id; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_content_id( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_char_t * content_id) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + if(om_text->content_id) + { + AXIS2_FREE(env->allocator, om_text->content_id); + } + om_text->content_id = (axis2_char_t *)axutil_strdup(env, content_id); + return AXIS2_SUCCESS; +} + +static axis2_status_t AXIS2_CALL +axiom_text_serialize_start_part( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output) +{ + axis2_char_t *namespace_uri = NULL; + axis2_char_t *prefix = NULL; + const axis2_char_t *local_name = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + local_name = axiom_text_get_localname(om_text, env); + + om_text->ns = axiom_namespace_create(env, "http://www.w3.org/2004/08/xop/include", "xop"); + + if(om_text->ns) + { + namespace_uri = axiom_namespace_get_uri(om_text->ns, env); + if(namespace_uri) + { + prefix = axiom_namespace_get_prefix(om_text->ns, env); + + if(prefix) + { + axiom_output_write(om_output, env, AXIOM_ELEMENT, 3, local_name, namespace_uri, + prefix); + } + else + { + axiom_output_write(om_output, env, AXIOM_ELEMENT, 2, local_name, namespace_uri); + } + } + else + { + axiom_output_write(om_output, env, AXIOM_ELEMENT, 1, local_name); + } + } + else + { + axiom_output_write(om_output, env, AXIOM_TEXT, 1, local_name); + } + if(om_text->om_attribute) + { + axiom_attribute_serialize(om_text->om_attribute, env, om_output); + } + if(om_text->ns) + { + axiom_namespace_serialize(om_text->ns, env, om_output); + axiom_namespace_free(om_text->ns, env); + om_text->ns = NULL; + } + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_serialize_attribute( + axiom_text_t * om_text, + const axutil_env_t * env, + axiom_output_t * om_output, + axiom_attribute_t * om_attribute) +{ + axiom_xml_writer_t *xml_writer = NULL; + axiom_namespace_t *om_namespace = NULL; + + axis2_char_t *namespace_uri = NULL; + axis2_char_t *prefix = NULL; + axis2_char_t *attribute_local_name = NULL; + axis2_char_t *attribute_value = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + om_namespace = axiom_namespace_create(env, "", ""); + + namespace_uri = axiom_namespace_get_uri(om_text->ns, env); + attribute_local_name = axiom_attribute_get_localname(om_attribute, env); + + if(om_namespace) + { + prefix = axiom_namespace_get_prefix(om_text->ns, env); + attribute_value = axiom_attribute_get_value(om_attribute, env); + if(prefix) + { + axiom_xml_writer_write_attribute(xml_writer, env, attribute_local_name, attribute_value); + } + else + { + axiom_xml_writer_write_attribute_with_namespace(xml_writer, env, attribute_local_name, + attribute_value, namespace_uri); + } + } + else + { + axiom_xml_writer_write_attribute(xml_writer, env, attribute_local_name, attribute_value); + } + axiom_namespace_free(om_namespace, env); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_serialize_namespace( + axiom_text_t * om_text, + const axutil_env_t * env, + const axiom_namespace_t * om_namespace, + axiom_output_t * om_output) +{ + axiom_xml_writer_t *xml_writer = NULL; + axis2_char_t *namespace_uri = NULL; + axis2_char_t *namespace_prefix = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + om_namespace = axiom_namespace_create(env, "", ""); + + if(om_namespace) + { + namespace_uri = axiom_namespace_get_uri(om_text->ns, env); + namespace_prefix = axiom_namespace_get_prefix(om_text->ns, env); + axiom_xml_writer_write_namespace(xml_writer, env, namespace_prefix, namespace_uri); + axiom_xml_writer_set_prefix(xml_writer, env, namespace_prefix, namespace_uri); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axiom_text_get_text( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + if(om_text->value) + { + return axutil_string_get_buffer(om_text->value, env); + } + else + { + axis2_char_t *data_handler_stream = NULL; + size_t data_handler_stream_size = 0; + if(om_text->data_handler) + { + int encoded_len = 0; + axis2_char_t *encoded_str = NULL; + axiom_data_handler_read_from(om_text->data_handler, env, &data_handler_stream, + &data_handler_stream_size); + if(data_handler_stream) + { + encoded_len = axutil_base64_encode_len((int)data_handler_stream_size); + encoded_str = AXIS2_MALLOC(env->allocator, encoded_len + 2); + if(encoded_str) + { + encoded_len = axutil_base64_encode(encoded_str, data_handler_stream, + (int)data_handler_stream_size); + encoded_str[encoded_len] = '\0'; + return encoded_str; + } + } + } + } + return NULL; +} + +AXIS2_EXTERN axiom_data_handler_t *AXIS2_CALL +axiom_text_get_data_handler( + axiom_text_t * om_text, + const axutil_env_t * env) +{ + return om_text->data_handler; +} + +AXIS2_EXTERN axiom_text_t *AXIS2_CALL +axiom_text_create_str( + const axutil_env_t * env, + axiom_node_t * parent, + axutil_string_t * value, + axiom_node_t ** node) +{ + axiom_text_t *om_text = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, node, NULL); + + *node = axiom_node_create(env); + + if(!(*node)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + om_text = (axiom_text_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_text_t)); + if(!om_text) + { + AXIS2_FREE(env->allocator, *node); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + om_text->mime_type = NULL; + om_text->optimize = AXIS2_FALSE; + om_text->localname = "Include"; + om_text->is_binary = AXIS2_FALSE; + om_text->content_id = NULL; + om_text->om_attribute = NULL; + om_text->value = NULL; + om_text->ns = NULL; + om_text->data_handler = NULL; + om_text->mime_type = NULL; + + if(value) + { + om_text->value = axutil_string_clone(value, env); + } + + axiom_node_set_data_element((*node), env, om_text); + axiom_node_set_node_type((*node), env, AXIOM_TEXT); + axiom_node_set_complete((*node), env, AXIS2_FALSE); + + if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT) + { + axiom_node_add_child(parent, env, (*node)); + } + + return om_text; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_value_str( + struct axiom_text * om_text, + const axutil_env_t * env, + axutil_string_t * value) +{ + if(om_text->value) + { + axutil_string_free(om_text->value, env); + om_text->value = NULL; + } + if(value) + { + om_text->value = axutil_string_clone(value, env); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axiom_text_get_value_str( + struct axiom_text * om_text, + const axutil_env_t * env) +{ + return om_text->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_text_set_is_swa( + axiom_text_t * om_text, + const axutil_env_t * env, + const axis2_bool_t is_swa) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE); + om_text->is_swa = is_swa; + return AXIS2_SUCCESS; +} diff --git a/axiom/src/parser/Makefile.am b/axiom/src/parser/Makefile.am new file mode 100644 index 0000000..6c1d2ba --- /dev/null +++ b/axiom/src/parser/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = $(WRAPPER_DIR) + +DIST_SUBDIRS=guththila libxml2 diff --git a/axiom/src/parser/guththila/Makefile.am b/axiom/src/parser/guththila/Makefile.am new file mode 100644 index 0000000..0cc6be5 --- /dev/null +++ b/axiom/src/parser/guththila/Makefile.am @@ -0,0 +1,13 @@ +lib_LTLIBRARIES = libaxis2_parser.la + +libaxis2_parser_la_LIBADD = ../../../../guththila/src/libguththila.la \ + ../../../../util/src/libaxutil.la + +libaxis2_parser_la_SOURCES = ../xml_reader.c ../xml_writer.c guththila_xml_writer_wrapper.c \ + guththila_xml_reader_wrapper.c + +libaxis2_parser_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I ../../../../util/include \ + -I ../../../../guththila/include diff --git a/axiom/src/parser/guththila/guththila_xml_reader_wrapper.c b/axiom/src/parser/guththila/guththila_xml_reader_wrapper.c new file mode 100644 index 0000000..086ed12 --- /dev/null +++ b/axiom/src/parser/guththila/guththila_xml_reader_wrapper.c @@ -0,0 +1,613 @@ +/* + * 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_xml_reader.h> +#include <axutil_env.h> +#include <axutil_utils.h> +#include <guththila.h> + +/**************** function prototypes ******************************************/ + +int AXIS2_CALL guththila_xml_reader_wrapper_next( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +void AXIS2_CALL guththila_xml_reader_wrapper_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +int AXIS2_CALL guththila_xml_reader_wrapper_get_attribute_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_name_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_value_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_namespace_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_value( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +int AXIS2_CALL guththila_xml_reader_wrapper_get_namespace_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_uri_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_name( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_pi_target( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_pi_data( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_dtd( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +void AXIS2_CALL guththila_xml_reader_wrapper_xml_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + void *data); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_char_set_encoding( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL guththila_xml_reader_wrapper_get_namespace_uri( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_uri_by_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + axis2_char_t * prefix); + +void *AXIS2_CALL +guththila_xml_reader_wrapper_get_context( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_current_buffer( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +/*********** guththila_xml_reader_wrapper_impl_t wrapper struct *******************/ + +typedef struct guththila_xml_reader_wrapper_impl +{ + axiom_xml_reader_t parser; + guththila_t *guththila_parser; + guththila_reader_t *reader; + int event_map[10]; + void *context; + +} guththila_xml_reader_wrapper_impl_t; + +/********************************* Macro ***************************************/ + +#define AXIS2_INTF_TO_IMPL(p) ((guththila_xml_reader_wrapper_impl_t*)p) + +#define AXIS2_IMPL_TO_INTF(p) &(p->parser) + +/**********End macros -- event_map initializing function *********************/ + +static axis2_status_t +guththila_xml_reader_wrapper_init_map( + guththila_xml_reader_wrapper_impl_t * parser) +{ + if(parser) + { + parser->event_map[GUTHTHILA_START_DOCUMENT] = AXIOM_XML_READER_START_DOCUMENT; + parser->event_map[GUTHTHILA_START_ELEMENT] = AXIOM_XML_READER_START_ELEMENT; + parser->event_map[GUTHTHILA_END_ELEMENT] = AXIOM_XML_READER_END_ELEMENT; + parser->event_map[GUTHTHILA_SPACE] = AXIOM_XML_READER_SPACE; + parser->event_map[GUTHTHILA_EMPTY_ELEMENT] = AXIOM_XML_READER_EMPTY_ELEMENT; + parser->event_map[GUTHTHILA_CHARACTER] = AXIOM_XML_READER_CHARACTER; + parser->event_map[GUTHTHILA_ENTITY_REFERANCE] = AXIOM_XML_READER_ENTITY_REFERENCE; + parser->event_map[GUTHTHILA_COMMENT] = AXIOM_XML_READER_COMMENT; + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +static const axiom_xml_reader_ops_t axiom_xml_reader_ops_var = { guththila_xml_reader_wrapper_next, + guththila_xml_reader_wrapper_free, guththila_xml_reader_wrapper_get_attribute_count, + guththila_xml_reader_wrapper_get_attribute_name_by_number, + guththila_xml_reader_wrapper_get_attribute_prefix_by_number, + guththila_xml_reader_wrapper_get_attribute_value_by_number, + guththila_xml_reader_wrapper_get_attribute_namespace_by_number, + guththila_xml_reader_wrapper_get_value, guththila_xml_reader_wrapper_get_namespace_count, + guththila_xml_reader_wrapper_get_namespace_uri_by_number, + guththila_xml_reader_wrapper_get_namespace_prefix_by_number, + guththila_xml_reader_wrapper_get_prefix, guththila_xml_reader_wrapper_get_name, + guththila_xml_reader_wrapper_get_pi_target, guththila_xml_reader_wrapper_get_pi_data, + guththila_xml_reader_wrapper_get_dtd, guththila_xml_reader_wrapper_xml_free, + guththila_xml_reader_wrapper_get_char_set_encoding, + guththila_xml_reader_wrapper_get_namespace_uri, + guththila_xml_reader_wrapper_get_namespace_uri_by_prefix, + guththila_xml_reader_wrapper_get_context, + guththila_xml_reader_wrapper_get_current_buffer}; + +/********************************************************************************/ + +AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL +axiom_xml_reader_create_for_file( + const axutil_env_t * env, + char *filename, + const axis2_char_t * encoding) +{ + guththila_xml_reader_wrapper_impl_t *guththila_impl = NULL; + guththila_t *guththila = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + guththila_impl = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_reader_wrapper_impl_t)); + + if(!guththila_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila_impl->reader = guththila_reader_create_for_file(filename, env); + + if(!(guththila_impl->reader)) + { + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila = (guththila_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_t)); + guththila_init(guththila, guththila_impl->reader, env); + if(!guththila) + { + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila_impl->guththila_parser = guththila; + guththila_impl->context = NULL; + guththila_impl->parser.ops = NULL; + /* guththila_impl->parser.ops = + (axiom_xml_reader_ops_t *) AXIS2_MALLOC(env->allocator, + sizeof(axiom_xml_reader_ops_t)); + if (!(guththila_impl->parser.ops)) + { + guththila_free(guththila, env); + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + */ + guththila_xml_reader_wrapper_init_map(guththila_impl); + + /************** ops *****/ + guththila_impl->parser.ops = &axiom_xml_reader_ops_var; + return &(guththila_impl->parser); +} + +/****** pull parser for io create function ***************************/ + +axiom_xml_reader_t *AXIS2_CALL +axiom_xml_reader_create_for_io( + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK read_input_callback, + AXIS2_CLOSE_INPUT_CALLBACK close_input_callback, + void *ctx, + const char *encoding) +{ + guththila_xml_reader_wrapper_impl_t *guththila_impl = NULL; + /*axutil_allocator_t *allocator = NULL; */ + guththila_t *guththila = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + guththila_impl = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_reader_wrapper_impl_t)); + + if(!guththila_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /*allocator = axutil_allocator_init(NULL); */ + + /*-------difference of two create function is here--------*/ + guththila_impl->reader = guththila_reader_create_for_io(read_input_callback, ctx, env); + + if(!(guththila_impl->reader)) + { + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila = (guththila_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_t)); + guththila_init(guththila, guththila_impl->reader, env); + if(!guththila) + { + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila_impl->guththila_parser = guththila; + guththila_impl->context = ctx; + guththila_impl->parser.ops = NULL; + /* guththila_impl->parser.ops = (axiom_xml_reader_ops_t *) + AXIS2_MALLOC(env->allocator, sizeof(axiom_xml_reader_ops_t)); + if (!(guththila_impl->parser.ops)) + { + guththila_free(guththila, env); + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + }*/ + + guththila_xml_reader_wrapper_init_map(guththila_impl); + + /************** ops *****/ + guththila_impl->parser.ops = &axiom_xml_reader_ops_var; + return &(guththila_impl->parser); +} + +/* ####################################################################### */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_reader_init() +{ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_reader_cleanup() +{ + return AXIS2_SUCCESS; +} + +/* ######################################################################## */ + +AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL +axiom_xml_reader_create_for_memory( + const axutil_env_t * env, + void *buffer, + int size, + const char *encoding, + int type) +{ + guththila_xml_reader_wrapper_impl_t *guththila_impl = NULL; + /*axutil_allocator_t *allocator = NULL; */ + guththila_t *guththila = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + guththila_impl = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_reader_wrapper_impl_t)); + + if(!guththila_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /*allocator = axutil_allocator_init(NULL); */ + + /*-------difference of two create function is here--------*/ + guththila_impl->reader = guththila_reader_create_for_memory(buffer, size, env); + + if(!(guththila_impl->reader)) + { + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila = (guththila_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_t)); + guththila_init(guththila, guththila_impl->reader, env); + if(!guththila) + { + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + guththila_impl->guththila_parser = guththila; + guththila_impl->context = NULL; + guththila_impl->parser.ops = NULL; + /* guththila_impl->parser.ops = (axiom_xml_reader_ops_t *) + AXIS2_MALLOC(env->allocator, sizeof(axiom_xml_reader_ops_t)); + if (!(guththila_impl->parser.ops)) + { + guththila_free(guththila, env); + AXIS2_FREE(env->allocator, guththila_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + */ + guththila_xml_reader_wrapper_init_map(guththila_impl); + + /************** ops *****/ + guththila_impl->parser.ops = &axiom_xml_reader_ops_var; + return &(guththila_impl->parser); +} + +int AXIS2_CALL +guththila_xml_reader_wrapper_next( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + int i = -1; + AXIS2_ENV_CHECK(env, -1); + i = guththila_next(AXIS2_INTF_TO_IMPL(parser)->guththila_parser, env); + return i == -1 ? -1 : AXIS2_INTF_TO_IMPL(parser)->event_map[i]; +} + +void AXIS2_CALL +guththila_xml_reader_wrapper_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + guththila_xml_reader_wrapper_impl_t *parser_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->reader) + { + guththila_reader_free(parser_impl->reader, env); + } + + if(parser_impl->guththila_parser) + { + guththila_un_init(parser_impl->guththila_parser, env); + } + + AXIS2_FREE(env->allocator, parser_impl); +} + +int AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return guththila_get_attribute_count(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_name_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_attribute_name_by_number(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, i, + env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_attribute_prefix_by_number(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, + i, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_value_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_attribute_value_by_number(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, + i, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_attribute_namespace_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_attribute_namespace_by_number( + AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, i, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_value( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_value(AXIS2_INTF_TO_IMPL(parser)->guththila_parser, env); +} + +int AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return guththila_get_namespace_count(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_uri_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_namespace_uri_by_number(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, i, + env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_namespace_prefix_by_number(AXIS2_INTF_TO_IMPL(parser)-> guththila_parser, + i, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_prefix(AXIS2_INTF_TO_IMPL(parser)->guththila_parser, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_name( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, NULL); + return guththila_get_name(AXIS2_INTF_TO_IMPL(parser)->guththila_parser, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_pi_target( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + /* guththila_does not support pi's yet */ + return NULL; +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_pi_data( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + /* guththila_dose not support yet */ + return NULL; +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_dtd( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + printf("not implemented in guththila"); + return NULL; +} + +void AXIS2_CALL +guththila_xml_reader_wrapper_xml_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + void *data) +{ + if(data) + AXIS2_FREE(env->allocator, data); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_char_set_encoding( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return guththila_get_encoding(AXIS2_INTF_TO_IMPL(parser)->guththila_parser, env); +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_uri( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + + return (axis2_char_t *)NULL; +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_namespace_uri_by_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + axis2_char_t * prefix) +{ + return (axis2_char_t *)NULL; +} + +void *AXIS2_CALL +guththila_xml_reader_wrapper_get_context( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + guththila_xml_reader_wrapper_impl_t* parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + return parser_impl->context; +} + +axis2_char_t *AXIS2_CALL +guththila_xml_reader_wrapper_get_current_buffer( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return guththila_get_current_buffer(AXIS2_INTF_TO_IMPL(parser)->guththila_parser, env); +} + diff --git a/axiom/src/parser/guththila/guththila_xml_writer_wrapper.c b/axiom/src/parser/guththila/guththila_xml_writer_wrapper.c new file mode 100644 index 0000000..31b4040 --- /dev/null +++ b/axiom/src/parser/guththila/guththila_xml_writer_wrapper.c @@ -0,0 +1,787 @@ +/* + * 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 <guththila_xml_writer.h> +#include <axutil_utils.h> +#include <axutil_env.h> +#include <axiom_xml_writer.h> +#include <string.h> + +/************************ function prototypes ************************************/ +void AXIS2_CALL guththila_xml_writer_wrapper_free( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_end_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_empty_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_empty_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_empty_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_end_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_end_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_attribute( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_attribute_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_attribute_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri, + axis2_char_t * prefix); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_default_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_comment( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * value); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_processing_instruction( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_processing_instruction_data( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target, + axis2_char_t * data); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_cdata( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * data); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_dtd( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * dtd); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_entity_ref( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * name); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_document_with_version( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * version); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_document_with_version_encoding( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * encoding, + axis2_char_t * version); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_characters( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text); + +axis2_char_t *AXIS2_CALL guththila_xml_writer_wrapper_get_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_set_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_set_default_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_encoded( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text, + int in_attr); + +void *AXIS2_CALL guththila_xml_writer_wrapper_get_xml( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +unsigned int AXIS2_CALL guththila_xml_writer_wrapper_get_xml_size( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +int AXIS2_CALL guththila_xml_writer_wrapper_get_type( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_raw( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * content); + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_flush( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +/***************************** end function pointers *****************************/ + +typedef struct guththila_xml_writer_wrapper_impl +{ + axiom_xml_writer_t writer; + guththila_xml_writer_t *wr; +} guththila_xml_writer_wrapper_impl_t; + +static const axiom_xml_writer_ops_t axiom_xml_writer_ops_var = { guththila_xml_writer_wrapper_free, + guththila_xml_writer_wrapper_write_start_element, + guththila_xml_writer_wrapper_end_start_element, + guththila_xml_writer_wrapper_write_start_element_with_namespace, + guththila_xml_writer_wrapper_write_start_element_with_namespace_prefix, + guththila_xml_writer_wrapper_write_empty_element, + guththila_xml_writer_wrapper_write_empty_element_with_namespace, + guththila_xml_writer_wrapper_write_empty_element_with_namespace_prefix, + guththila_xml_writer_wrapper_write_end_element, + guththila_xml_writer_wrapper_write_end_document, guththila_xml_writer_wrapper_write_attribute, + guththila_xml_writer_wrapper_write_attribute_with_namespace, + guththila_xml_writer_wrapper_write_attribute_with_namespace_prefix, + guththila_xml_writer_wrapper_write_namespace, + guththila_xml_writer_wrapper_write_default_namespace, + guththila_xml_writer_wrapper_write_comment, + guththila_xml_writer_wrapper_write_processing_instruction, + guththila_xml_writer_wrapper_write_processing_instruction_data, + guththila_xml_writer_wrapper_write_cdata, guththila_xml_writer_wrapper_write_dtd, + guththila_xml_writer_wrapper_write_entity_ref, + guththila_xml_writer_wrapper_write_start_document, + guththila_xml_writer_wrapper_write_start_document_with_version, + guththila_xml_writer_wrapper_write_start_document_with_version_encoding, + guththila_xml_writer_wrapper_write_characters, guththila_xml_writer_wrapper_get_prefix, + guththila_xml_writer_wrapper_set_prefix, guththila_xml_writer_wrapper_set_default_prefix, + guththila_xml_writer_wrapper_write_encoded, guththila_xml_writer_wrapper_get_xml, + guththila_xml_writer_wrapper_get_xml_size, guththila_xml_writer_wrapper_get_type, + guththila_xml_writer_wrapper_write_raw, guththila_xml_writer_wrapper_flush }; + +/****************************** Macros *******************************************/ + +#define AXIS2_INTF_TO_IMPL(p) ((guththila_xml_writer_wrapper_impl_t*)p) + +/******************************* End macro ***************************************/ + +AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL +axiom_xml_writer_create( + const axutil_env_t * env, + axis2_char_t * filename, + axis2_char_t * encoding, + int is_prefix_default, + int compression) +{ + guththila_xml_writer_wrapper_impl_t *writer_impl; + + AXIS2_ENV_CHECK(env, NULL); + + writer_impl = (guththila_xml_writer_wrapper_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_wrapper_impl_t)); + return &(writer_impl->writer); +} + +AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL +axiom_xml_writer_create_for_memory( + const axutil_env_t * env, + axis2_char_t * encoding, + int is_prefix_default, + int compression, + int type) +{ + guththila_xml_writer_wrapper_impl_t *writer_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + writer_impl = (guththila_xml_writer_wrapper_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_wrapper_impl_t)); + + if(!writer_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /* creating guththila parser */ + /* guththila xml stream writer for memory */ + + writer_impl->wr = guththila_create_xml_stream_writer_for_memory(env); + + if(!(writer_impl->wr)) + { + AXIS2_FREE(env->allocator, writer_impl->wr); + AXIS2_FREE(env->allocator, writer_impl); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + writer_impl->writer.ops = NULL; + /* ops */ + writer_impl->writer.ops = &axiom_xml_writer_ops_var; + return &(writer_impl->writer); + +} + +void AXIS2_CALL +guththila_xml_writer_wrapper_free( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + if(AXIS2_INTF_TO_IMPL(writer)->wr) + { + guththila_xml_writer_free(AXIS2_INTF_TO_IMPL(writer)->wr, env); + } + + if(writer) + { + AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(writer)); + } + +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname) +{ + int status = AXIS2_SUCCESS; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + guththila_write_start_element(AXIS2_INTF_TO_IMPL(writer)->wr, localname, env); + return status; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri) +{ + int status = AXIS2_SUCCESS; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + guththila_write_start_element_with_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, namespace_uri, + localname, env); + return status; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + guththila_write_start_element_with_prefix_and_namespace(AXIS2_INTF_TO_IMPL + (writer)->wr, prefix, namespace_uri, localname, env); + return AXIS2_SUCCESS; + +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_empty_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + guththila_write_empty_element(AXIS2_INTF_TO_IMPL(writer)->wr, localname, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_empty_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + guththila_write_empty_element_with_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, namespace_uri, + localname, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_empty_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + + guththila_write_empty_element_with_prefix_and_namespace(AXIS2_INTF_TO_IMPL + (writer)->wr, prefix, namespace_uri, localname, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_end_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + guththila_write_end_element(AXIS2_INTF_TO_IMPL(writer)->wr, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_end_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + guththila_write_end_document(AXIS2_INTF_TO_IMPL(writer)->wr, env); + return AXIS2_SUCCESS; + +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_attribute( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value) +{ + if(!value) + value = ""; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + guththila_write_attribute(AXIS2_INTF_TO_IMPL(writer)->wr, localname, value, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_attribute_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri) +{ + if(!value) + value = ""; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + + guththila_write_attribute_with_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, namespace_uri, + localname, value, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_attribute_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + guththila_write_attribute_with_prefix_and_namespace(AXIS2_INTF_TO_IMPL + (writer)->wr, prefix, namespace_uri, localname, value, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * namespace_uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + /* when default namespace comes is passed, prefix is null */ + if(prefix) + guththila_write_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, prefix, namespace_uri, env); + else + guththila_write_default_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, namespace_uri, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_default_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * namespace_uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + guththila_write_default_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, namespace_uri, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_comment( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * value) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + guththila_write_comment(AXIS2_INTF_TO_IMPL(writer)->wr, value, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_processing_instruction( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_processing_instruction_data( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target, + axis2_char_t * data) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_cdata( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * data) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_dtd( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * dtd) +{ + /* AXIS2_ENV_CHECK( env, AXIS2_FAILURE); */ + /* AXIS2_PARAM_CHECK(env->error, dtd, AXIS2_FAILURE); */ + /* return guththila_write_dtd( */ + /* (axutil_env_t *)env, */ + /* AXIS2_INTF_TO_IMPL(writer)->parser, */ + /* dtd); */ + return 0; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_entity_ref( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * name) +{ + /* AXIS2_ENV_CHECK( env, AXIS2_FAILURE); */ + /* AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); */ + /* return guththila_write_entity_ref( */ + /* (axutil_env_t *)env, */ + /* AXIS2_INTF_TO_IMPL(writer)->parser, */ + /* name); */ + return 0; + +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + guththila_write_start_document(AXIS2_INTF_TO_IMPL(writer)->wr, env, NULL, NULL); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_document_with_version( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * version) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, version, AXIS2_FAILURE); + guththila_write_start_document(AXIS2_INTF_TO_IMPL(writer)->wr, env, NULL, version); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_start_document_with_version_encoding( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * encoding, + axis2_char_t * version) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, encoding, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, version, AXIS2_FAILURE); + guththila_write_start_document(AXIS2_INTF_TO_IMPL(writer)->wr, env, encoding, version); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_characters( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + guththila_write_characters(AXIS2_INTF_TO_IMPL(writer)->wr, text, env); + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +guththila_xml_writer_wrapper_get_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + return guththila_get_prefix_for_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, uri, env); +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_set_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + guththila_write_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, prefix, uri, env); + return AXIS2_SUCCESS; + +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_set_default_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + guththila_write_default_namespace(AXIS2_INTF_TO_IMPL(writer)->wr, uri, env); + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_encoded( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text, + int in_attr) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + return AXIS2_SUCCESS; +} + +void *AXIS2_CALL +guththila_xml_writer_wrapper_get_xml( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + char *buffer = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + buffer = guththila_get_memory_buffer(AXIS2_INTF_TO_IMPL(writer)->wr, env); + return (void *)buffer; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_write_raw( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * content) +{ + if(!content) + { + return AXIS2_FAILURE; + } + else + { + guththila_write_to_buffer(AXIS2_INTF_TO_IMPL(writer)->wr, (char *)content, (int)strlen( + content), env); + return AXIS2_SUCCESS; + } +} + +unsigned int AXIS2_CALL +guththila_xml_writer_wrapper_get_xml_size( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + return guththila_get_memory_buffer_size(AXIS2_INTF_TO_IMPL(writer)->wr, env); +} + +int AXIS2_CALL +guththila_xml_writer_wrapper_get_type( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return 0; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_flush( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +guththila_xml_writer_wrapper_end_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + /* nothing to do , + it is automatically taken care by the libxml2 writer */ + return AXIS2_SUCCESS; +} diff --git a/axiom/src/parser/libxml2/Makefile.am b/axiom/src/parser/libxml2/Makefile.am new file mode 100644 index 0000000..a5b4c75 --- /dev/null +++ b/axiom/src/parser/libxml2/Makefile.am @@ -0,0 +1,17 @@ +lib_LTLIBRARIES = libaxis2_parser.la + + +libaxis2_parser_la_SOURCES = ../xml_reader.c ../xml_writer.c \ + libxml2_reader_wrapper.c libxml2_writer_wrapper.c + +libaxis2_parser_la_LIBADD = @LIBXML2_LIBS@ \ + ../../../../util/src/libaxutil.la + +libaxis2_parser_la_LDFLAGS = -version-info $(VERSION_NO) +libaxis2_libxml2_la_LDFLAGS = -version-info $(VERSION_NO) + + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/parser \ + -I ../../../../util/include \ + @LIBXML2_CFLAGS@ diff --git a/axiom/src/parser/libxml2/libxml2_reader_wrapper.c b/axiom/src/parser/libxml2/libxml2_reader_wrapper.c new file mode 100644 index 0000000..2510d49 --- /dev/null +++ b/axiom/src/parser/libxml2/libxml2_reader_wrapper.c @@ -0,0 +1,949 @@ +/* + * 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_xml_reader.h> +#include <libxml/xmlreader.h> +#include <libxml/parser.h> +#include <axutil_utils_defines.h> +#include <axutil_utils.h> +#include <string.h> +#include <axutil_string.h> + + +int AXIS2_CALL axis2_libxml2_reader_wrapper_next( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +void AXIS2_CALL axis2_libxml2_reader_wrapper_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +int AXIS2_CALL axis2_libxml2_reader_wrapper_get_attribute_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_name_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_value_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_value( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +int AXIS2_CALL axis2_libxml2_reader_wrapper_get_namespace_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_uri_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_name( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_pi_target( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_pi_data( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_dtd( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +void AXIS2_CALL axis2_libxml2_reader_wrapper_xml_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + void *data); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_char_set_encoding( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL axis2_libxml2_reader_wrapper_get_namespace_uri( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_uri_by_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + axis2_char_t * prefix); + +axis2_status_t +axis2_libxml2_reader_wrapper_fill_maps( + axiom_xml_reader_t * parser, + const axutil_env_t * env); + +void +axis2_libxml2_reader_wrapper_error_handler( + void *arg, + const char *msg, + int severities, + void *locator_ptr); + +static int +axis2_libxml2_reader_wrapper_read_input_callback( + void *ctx, + char *buffer, + int size); + +static int +axis2_libxml2_reader_wrapper_close_input_callback( + void *ctx); + +typedef struct axis2_libxml2_reader_wrapper_impl_t +{ + axiom_xml_reader_t parser; + + xmlTextReaderPtr reader; + + int current_event; + int current_attribute_count; + int current_namespace_count; + int event_map[18]; + + void *ctx; + /* assuming that max ns and attribute will be 20 */ + + int *namespace_map; + int *attribute_map; + + AXIS2_READ_INPUT_CALLBACK read_input_callback; + + AXIS2_CLOSE_INPUT_CALLBACK close_input_callback; + +} axis2_libxml2_reader_wrapper_impl_t; + +#define AXIS2_INTF_TO_IMPL(p) ((axis2_libxml2_reader_wrapper_impl_t*)p) +#define AXIS2_IMPL_TO_INTF(p) &(p->parser) + +static const axiom_xml_reader_ops_t axiom_xml_reader_ops_var = { axis2_libxml2_reader_wrapper_next, + axis2_libxml2_reader_wrapper_free, axis2_libxml2_reader_wrapper_get_attribute_count, + axis2_libxml2_reader_wrapper_get_attribute_name_by_number, + axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number, + axis2_libxml2_reader_wrapper_get_attribute_value_by_number, + axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number, + axis2_libxml2_reader_wrapper_get_value, axis2_libxml2_reader_wrapper_get_namespace_count, + axis2_libxml2_reader_wrapper_get_namespace_uri_by_number, + axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number, + axis2_libxml2_reader_wrapper_get_prefix, axis2_libxml2_reader_wrapper_get_name, + axis2_libxml2_reader_wrapper_get_pi_target, axis2_libxml2_reader_wrapper_get_pi_data, + axis2_libxml2_reader_wrapper_get_dtd, axis2_libxml2_reader_wrapper_xml_free, + axis2_libxml2_reader_wrapper_get_char_set_encoding, + axis2_libxml2_reader_wrapper_get_namespace_uri, + axis2_libxml2_reader_wrapper_get_namespace_uri_by_prefix }; + +static axis2_status_t +axis2_libxml2_reader_wrapper_init_map( + axis2_libxml2_reader_wrapper_impl_t * parser) +{ + int i = 0; + if(parser) + { + for(i = 0; i < 18; i++) + { + parser->event_map[i] = -1; + } + + parser->event_map[XML_READER_TYPE_ELEMENT] = AXIOM_XML_READER_START_ELEMENT; + parser->event_map[XML_READER_TYPE_DOCUMENT] = AXIOM_XML_READER_START_DOCUMENT; + parser->event_map[XML_READER_TYPE_TEXT] = AXIOM_XML_READER_CHARACTER; + parser->event_map[XML_READER_TYPE_CDATA] = AXIOM_XML_READER_CHARACTER; + parser->event_map[XML_READER_TYPE_SIGNIFICANT_WHITESPACE] = AXIOM_XML_READER_SPACE; + parser->event_map[XML_READER_TYPE_WHITESPACE] = AXIOM_XML_READER_SPACE; + parser->event_map[XML_READER_TYPE_END_ELEMENT] = AXIOM_XML_READER_END_ELEMENT; + parser->event_map[XML_READER_TYPE_ENTITY_REFERENCE] = AXIOM_XML_READER_ENTITY_REFERENCE; + parser->event_map[XML_READER_TYPE_END_ENTITY] = AXIOM_XML_READER_SPACE; + parser->event_map[XML_READER_TYPE_ENTITY] = AXIOM_XML_READER_SPACE; + parser->event_map[XML_READER_TYPE_PROCESSING_INSTRUCTION] + = AXIOM_XML_READER_PROCESSING_INSTRUCTION; + parser->event_map[XML_READER_TYPE_COMMENT] = AXIOM_XML_READER_COMMENT; + parser->event_map[XML_READER_TYPE_DOCUMENT_TYPE] = AXIOM_XML_READER_DOCUMENT_TYPE; + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_reader_init() +{ + xmlInitParser(); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_reader_cleanup() +{ + xmlCleanupParser(); + return AXIS2_SUCCESS; +} + +static axis2_libxml2_reader_wrapper_impl_t* +libxml2_reader_wrapper_create( + const axutil_env_t *env) +{ + axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL; + wrapper_impl = (axis2_libxml2_reader_wrapper_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_libxml2_reader_wrapper_impl_t)); + + if(!wrapper_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create libxml2 reader wrapper"); + return NULL; + } + memset(wrapper_impl, 0, sizeof(axis2_libxml2_reader_wrapper_impl_t)); + wrapper_impl->attribute_map = NULL; + wrapper_impl->namespace_map = NULL; + wrapper_impl->close_input_callback = NULL; + wrapper_impl->read_input_callback = NULL; + wrapper_impl->ctx = NULL; + wrapper_impl->current_namespace_count = 0; + wrapper_impl->current_attribute_count = 0; + wrapper_impl->current_event = -1; + return wrapper_impl; +} + +AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL +axiom_xml_reader_create_for_file( + const axutil_env_t * env, + char *filename, + const axis2_char_t * encoding) +{ + + axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, filename, NULL); + + wrapper_impl = libxml2_reader_wrapper_create(env); + if(!wrapper_impl) + { + return NULL; + } + + wrapper_impl->reader = xmlReaderForFile(filename, encoding, XML_PARSE_RECOVER); + if(!(wrapper_impl->reader)) + { + AXIS2_FREE(env->allocator, wrapper_impl); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE); + return NULL; + } + + xmlTextReaderSetErrorHandler(wrapper_impl->reader, + (xmlTextReaderErrorFunc)axis2_libxml2_reader_wrapper_error_handler, (void *)env); + wrapper_impl->current_event = -1; + wrapper_impl->ctx = NULL; + axis2_libxml2_reader_wrapper_init_map(wrapper_impl); + + wrapper_impl->parser.ops = &axiom_xml_reader_ops_var; + return &(wrapper_impl->parser); +} + +AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL +axiom_xml_reader_create_for_io( + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK read_input_callback, + AXIS2_CLOSE_INPUT_CALLBACK close_input_callback, + void *ctx, + const axis2_char_t * encoding) +{ + axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + + if(!read_input_callback) + { + return NULL; + } + + wrapper_impl = libxml2_reader_wrapper_create(env); + if(!wrapper_impl) + { + return NULL; + } + wrapper_impl->close_input_callback = NULL; + wrapper_impl->read_input_callback = NULL; + wrapper_impl->read_input_callback = read_input_callback; + wrapper_impl->close_input_callback = close_input_callback; + wrapper_impl->ctx = ctx; + if(wrapper_impl->close_input_callback) + { + wrapper_impl->reader = xmlReaderForIO(axis2_libxml2_reader_wrapper_read_input_callback, + axis2_libxml2_reader_wrapper_close_input_callback, wrapper_impl, NULL, encoding, + XML_PARSE_RECOVER); + } + else + { + wrapper_impl->reader = xmlReaderForIO(axis2_libxml2_reader_wrapper_read_input_callback, + NULL, wrapper_impl, NULL, encoding, XML_PARSE_RECOVER); + } + if(!(wrapper_impl->reader)) + { + AXIS2_FREE(env->allocator, wrapper_impl); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE); + return NULL; + } + + xmlTextReaderSetErrorHandler(wrapper_impl->reader, + (xmlTextReaderErrorFunc)axis2_libxml2_reader_wrapper_error_handler, (void *)env); + + wrapper_impl->current_event = -1; + + axis2_libxml2_reader_wrapper_init_map(wrapper_impl); + + wrapper_impl->parser.ops = &axiom_xml_reader_ops_var; + return &(wrapper_impl->parser); +} + +AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL +axiom_xml_reader_create_for_memory( + const axutil_env_t * env, + void *container, + int size, + const axis2_char_t * encoding, + int type) +{ + axis2_libxml2_reader_wrapper_impl_t *wrapper_impl = NULL; + + AXIS2_PARAM_CHECK(env->error, container, NULL); + + wrapper_impl = libxml2_reader_wrapper_create(env); + if(!wrapper_impl) + { + return NULL; + } + wrapper_impl->close_input_callback = NULL; + wrapper_impl->read_input_callback = NULL; + wrapper_impl->ctx = NULL; + + if(AXIS2_XML_PARSER_TYPE_BUFFER == type) + { + wrapper_impl->reader = xmlReaderForMemory((axis2_char_t *)container, size, NULL, encoding, + XML_PARSE_RECOVER); + } + else if(AXIS2_XML_PARSER_TYPE_DOC == type) + { + wrapper_impl->reader = xmlReaderWalker((xmlDocPtr)container); + } + else + { + AXIS2_FREE(env->allocator, wrapper_impl); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_XML_PARSER_INVALID_MEM_TYPE, AXIS2_FAILURE); + return NULL; + } + + if(!(wrapper_impl->reader)) + { + AXIS2_FREE(env->allocator, wrapper_impl); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_READER, AXIS2_FAILURE); + return NULL; + } + + if(AXIS2_XML_PARSER_TYPE_BUFFER == type) + { + xmlTextReaderSetErrorHandler(wrapper_impl->reader, + (xmlTextReaderErrorFunc)axis2_libxml2_reader_wrapper_error_handler, (void *)env); + } + + wrapper_impl->current_event = -1; + + axis2_libxml2_reader_wrapper_init_map(wrapper_impl); + + wrapper_impl->parser.ops = &axiom_xml_reader_ops_var; + return &(wrapper_impl->parser); +} + +int AXIS2_CALL +axis2_libxml2_reader_wrapper_next( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + int ret_val = 0; + int node = 2; + int empty_check = 0; + axis2_libxml2_reader_wrapper_impl_t *parser_impl; + AXIS2_ENV_CHECK(env, -1); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + ret_val = xmlTextReaderRead(parser_impl->reader); + if(ret_val == 0) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "xml stream is over "); + } + if(ret_val == -1) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, " error occurred in reading xml stream "); + return -1; + } + + if(ret_val == 1) + { + node = xmlTextReaderNodeType(parser_impl->reader); + parser_impl->current_event = parser_impl->event_map[node]; + parser_impl->current_attribute_count = 0; + parser_impl->current_namespace_count = 0; + + if(node == XML_READER_TYPE_ELEMENT) + { + empty_check = xmlTextReaderIsEmptyElement(parser_impl->reader); + axis2_libxml2_reader_wrapper_fill_maps(parser, env); + } + if(empty_check == 1) + { + parser_impl->current_event = AXIOM_XML_READER_EMPTY_ELEMENT; + return AXIOM_XML_READER_EMPTY_ELEMENT; + } + return parser_impl->event_map[node]; + } + else + { + return -1; + } +} + +/** + * If your application crashes here, it may be due to an earlier call to + * xmlCleanupParser() function. In client API, op_client create function has a call + * to axiom_xml_reader_init and op_client_free function has a call to axiom_xml_reader_cleanup + * function. You can avoid the call to axiom_xml_reader_cleanup using + * axis2_options_set_xml_parser_reset function in client API. + * refer to jira issue: https://issues.apache.org/jira/browse/AXIS2C-884 + */ +void AXIS2_CALL +axis2_libxml2_reader_wrapper_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->ctx) + { + AXIS2_FREE(env->allocator, parser_impl->ctx); + } + + if(parser_impl->reader) + { + xmlTextReaderClose(parser_impl->reader); + xmlFreeTextReader(parser_impl->reader); + } + if(parser_impl->namespace_map) + { + AXIS2_FREE(env->allocator, parser_impl->namespace_map); + parser_impl->namespace_map = NULL; + } + if(parser_impl->attribute_map) + { + AXIS2_FREE(env->allocator, parser_impl->attribute_map); + parser_impl->attribute_map = NULL; + } + AXIS2_FREE(env->allocator, AXIS2_INTF_TO_IMPL(parser)); + return; +} + +int AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->current_event == AXIOM_XML_READER_START_ELEMENT || parser_impl->current_event + == AXIOM_XML_READER_EMPTY_ELEMENT) + { + return parser_impl->current_attribute_count; + } + else + { + return 0; + } +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_name_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl; + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + if(parser_impl->current_attribute_count > 0 && parser_impl->current_attribute_count >= i) + { + int ret = + xmlTextReaderMoveToAttributeNo(parser_impl->reader, parser_impl->attribute_map[i]); + if(ret == 1) + { + return (axis2_char_t *)xmlTextReaderLocalName(parser_impl->reader); + } + else + { + return NULL; + } + } + return NULL; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + if(parser_impl->current_attribute_count > 0 && parser_impl->current_attribute_count >= i) + { + int ret = + xmlTextReaderMoveToAttributeNo(parser_impl->reader, parser_impl->attribute_map[i]); + if(ret == 1) + { + return (axis2_char_t *)xmlTextReaderPrefix(parser_impl->reader); + } + else + { + return NULL; + } + } + return NULL; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_value_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + + axis2_libxml2_reader_wrapper_impl_t *parser_impl; + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + if(parser_impl->current_attribute_count > 0 && parser_impl->current_attribute_count >= i) + { + int ret = + xmlTextReaderMoveToAttributeNo(parser_impl->reader, parser_impl->attribute_map[i]); + if(ret == 1) + { + return (axis2_char_t *)xmlTextReaderValue(parser_impl->reader); + } + else + { + return NULL; + } + } + return NULL; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_attribute_namespace_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl; + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + if(parser_impl->current_attribute_count > 0 && parser_impl->current_attribute_count >= i) + { + int ret = + xmlTextReaderMoveToAttributeNo(parser_impl->reader, parser_impl->attribute_map[i]); + + if(ret == 1) + { + return (axis2_char_t *)xmlTextReaderNamespaceUri(parser_impl-> reader); + } + else + { + return NULL; + } + } + return NULL; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_value( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + return (axis2_char_t *)xmlTextReaderValue(parser_impl->reader); + +} + +int AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->current_event == AXIOM_XML_READER_START_ELEMENT || parser_impl->current_event + == AXIOM_XML_READER_EMPTY_ELEMENT) + { + return parser_impl->current_namespace_count; + } + else + { + return 0; + } +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_uri_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + if(parser_impl->current_namespace_count > 0 && parser_impl->current_namespace_count >= i) + { + + int ret = + xmlTextReaderMoveToAttributeNo(parser_impl->reader, parser_impl->namespace_map[i]); + if(ret == 1) + { + return (axis2_char_t *)xmlTextReaderValue(parser_impl->reader); + } + else + return NULL; + } + return NULL; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + if(parser_impl->current_namespace_count > 0 && parser_impl->current_namespace_count >= i) + { + int ret = + xmlTextReaderMoveToAttributeNo(parser_impl->reader, parser_impl->namespace_map[i]); + + if(ret == 1) + { + return (axis2_char_t *)xmlTextReaderLocalName(parser_impl->reader); + } + else + { + return NULL; + } + } + return NULL; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + xmlTextReaderMoveToElement(parser_impl->reader); + return (axis2_char_t *)xmlTextReaderPrefix(parser_impl->reader); +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_name( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + xmlTextReaderMoveToElement(parser_impl->reader); + return (axis2_char_t *)xmlTextReaderLocalName(parser_impl->reader); +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_pi_target( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->current_event == AXIOM_XML_READER_PROCESSING_INSTRUCTION) + { + return (axis2_char_t *)xmlTextReaderLocalName(parser_impl->reader); + } + else + { + return NULL; + } +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_dtd( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->current_event == AXIOM_XML_READER_DOCUMENT_TYPE) + { + return (axis2_char_t *)xmlTextReaderLocalName(parser_impl->reader); + } + else + { + return NULL; + } +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_pi_data( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(parser_impl->current_event == AXIOM_XML_READER_PROCESSING_INSTRUCTION) + { + return (axis2_char_t *)xmlTextReaderValue(parser_impl->reader); + } + else + { + return NULL; + } +} + +void AXIS2_CALL +axis2_libxml2_reader_wrapper_xml_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + void *data) +{ + AXIS2_ENV_CHECK(env, void); + if(data) + xmlFree(data); + return; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_char_set_encoding( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *reader_impl = NULL; + reader_impl = AXIS2_INTF_TO_IMPL(parser); + return (axis2_char_t *)xmlTextReaderConstEncoding(reader_impl->reader); +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_uri( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + return (axis2_char_t *)xmlTextReaderNamespaceUri(parser_impl->reader); +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_reader_wrapper_get_namespace_uri_by_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + axis2_char_t * prefix) +{ + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + parser_impl = AXIS2_INTF_TO_IMPL(parser); + if(!prefix || axutil_strcmp(prefix, "") == 0) + { + return NULL; + } + return (axis2_char_t *)xmlTextReaderLookupNamespace(parser_impl->reader, + (const xmlChar *)prefix); +} + +axis2_status_t +axis2_libxml2_reader_wrapper_fill_maps( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + int libxml2_attribute_count = 0; + int attr_count = 0; + int ns_count = 0; + int i = 0; + char *q_name = NULL; + axis2_libxml2_reader_wrapper_impl_t *parser_impl = NULL; + int map_size = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + parser_impl = AXIS2_INTF_TO_IMPL(parser); + + libxml2_attribute_count = xmlTextReaderAttributeCount(parser_impl->reader); + if(libxml2_attribute_count == 0) + { + parser_impl->current_attribute_count = 0; + parser_impl->current_namespace_count = 0; + return AXIS2_SUCCESS; + } + map_size = libxml2_attribute_count + 1; + if(parser_impl->namespace_map) + { + AXIS2_FREE(env->allocator, parser_impl->namespace_map); + parser_impl->namespace_map = NULL; + } + if(parser_impl->attribute_map) + { + AXIS2_FREE(env->allocator, parser_impl->attribute_map); + parser_impl->attribute_map = NULL; + } + parser_impl->attribute_map = AXIS2_MALLOC(env->allocator, sizeof(int) * map_size); + memset(parser_impl->attribute_map, 0, map_size * sizeof(int)); + + parser_impl->namespace_map = AXIS2_MALLOC(env->allocator, sizeof(int) * map_size); + memset(parser_impl->namespace_map, 0, map_size * sizeof(int)); + + for(i = 0; i < map_size; i++) + { + parser_impl->namespace_map[i] = -1; + parser_impl->attribute_map[i] = -1; + } + + for(i = 0; i < libxml2_attribute_count; i++) + { + xmlTextReaderMoveToAttributeNo(parser_impl->reader, i); + q_name = (char *)xmlTextReaderName(parser_impl->reader); + if(q_name) + { + if((strcmp(q_name, "xmlns") == 0) || (strncmp(q_name, "xmlns:", 6) == 0)) + { + /* found a namespace */ + ns_count++; + parser_impl->namespace_map[ns_count] = i; + } + else + { + /* found an attribute */ + attr_count++; + parser_impl->attribute_map[attr_count] = i; + } + + xmlFree(q_name); + q_name = NULL; + } + + parser_impl->current_attribute_count = attr_count; + parser_impl->current_namespace_count = ns_count; + } + return AXIS2_SUCCESS; +} + +static int +axis2_libxml2_reader_wrapper_read_input_callback( + void *ctx, + char *buffer, + int size) +{ + return ((axis2_libxml2_reader_wrapper_impl_t *)ctx)-> read_input_callback(buffer, size, + ((axis2_libxml2_reader_wrapper_impl_t *)ctx)->ctx); +} + +void +axis2_libxml2_reader_wrapper_error_handler( + void *arg, + const char *msg, + int severities, + void *locator_ptr) +{ + const axutil_env_t *env = NULL; + env = (const axutil_env_t *)arg; + + switch(severities) + { + case XML_PARSER_SEVERITY_VALIDITY_WARNING: + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s VALIDITY WARNTING", msg); + } + break; + case XML_PARSER_SEVERITY_VALIDITY_ERROR: + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s -- VALIDITY ERROR", msg); + } + break; + case XML_PARSER_SEVERITY_WARNING: + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s -- VALIDITY ERROR", msg); + } + break; + case XML_PARSER_SEVERITY_ERROR: + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s -- SEVERITY_ERROR", msg); + } + break; + default: + break; + } +} + +static int +axis2_libxml2_reader_wrapper_close_input_callback( + void *ctx) +{ + return ((axis2_libxml2_reader_wrapper_impl_t *)ctx)-> close_input_callback( + ((axis2_libxml2_reader_wrapper_impl_t *)ctx)-> ctx); +} diff --git a/axiom/src/parser/libxml2/libxml2_writer_wrapper.c b/axiom/src/parser/libxml2/libxml2_writer_wrapper.c new file mode 100644 index 0000000..4c889d4 --- /dev/null +++ b/axiom/src/parser/libxml2/libxml2_writer_wrapper.c @@ -0,0 +1,1571 @@ +/* + * 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 <libxml/xmlwriter.h> +#include <axutil_utils.h> +#include <axutil_utils_defines.h> +#include <axutil_env.h> +#include <axiom_xml_writer.h> +#include <axutil_string.h> +#include <string.h> +#include <axutil_stack.h> +#include <axutil_hash.h> +#include <axutil_array_list.h> + +/*******************************************************************************/ + +#define ENCODING "ISO-8859-1" + +#define AXIS2_XMLNS_NAMESPACE_URI "http://www.w3.org/XML/1998/namespace" +#define AXIS2_XMLNS_PREFIX "xml" + +typedef struct uri_prefix_element +{ + axis2_char_t *prefix; + + axis2_char_t *uri; + + axis2_char_t *real_prefix; + + axis2_char_t *key; + +} uri_prefix_element_t; + +typedef struct axis2_libxml2_writer_wrapper_impl +{ + axiom_xml_writer_t writer; + + xmlTextWriterPtr xml_writer; + + xmlBufferPtr buffer; + + xmlDocPtr doc; + + int writer_type; + + axis2_char_t *encoding; + + int is_prefix_defaulting; + + int compression; + + axutil_stack_t *stack; + + axis2_bool_t in_empty_element; + + axis2_bool_t in_start_element; + + axutil_hash_t *uri_prefix_map; + + uri_prefix_element_t *default_lang_namespace; + +} axis2_libxml2_writer_wrapper_impl_t; + +#define AXIS2_INTF_TO_IMPL(p) ((axis2_libxml2_writer_wrapper_impl_t*)p) + +void AXIS2_CALL axis2_libxml2_writer_wrapper_free( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_end_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_empty_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_empty_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_end_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_end_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_attribute( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_attribute_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri, + axis2_char_t * prefix); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_default_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * namespace_uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_comment( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * value); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_processing_instruction( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_processing_instruction_data( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target, + axis2_char_t * data); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_cdata( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * data); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_dtd( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * dtd); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_entity_ref( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * name); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_document_with_version( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * version); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * encoding, + axis2_char_t * version); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_characters( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text); + +axis2_char_t *AXIS2_CALL axis2_libxml2_writer_wrapper_get_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_set_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_set_default_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_encoded( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text, + int in_attr); + +void *AXIS2_CALL axis2_libxml2_writer_wrapper_get_xml( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +unsigned int AXIS2_CALL axis2_libxml2_writer_wrapper_get_xml_size( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_flush( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +int AXIS2_CALL axis2_libxml2_writer_wrapper_get_type( + axiom_xml_writer_t * writer, + const axutil_env_t * env); + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_raw( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * content); + +static axis2_status_t +axis2_libxml2_writer_wrapper_push( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix); + +static axis2_bool_t +axis2_libxml2_writer_wrapper_is_namespace_declared( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * key); + +static void +uri_prefix_element_free( + uri_prefix_element_t * up_element, + const axutil_env_t * env); + +static uri_prefix_element_t * +uri_prefix_element_create( + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix, + const axis2_char_t * real_prefix, + const axis2_char_t * key); + +static void +create_key_from_uri_prefix( + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix, + axis2_char_t * array); + +static axis2_char_t * +axis2_libxml2_writer_wrapper_find_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri); + +static uri_prefix_element_t * +axis2_libxml2_writer_wrapper_find_prefix_in_context( + axutil_array_list_t * context, + const axutil_env_t * env, + axis2_char_t * uri); + +static const axiom_xml_writer_ops_t axiom_xml_writer_ops_var = { axis2_libxml2_writer_wrapper_free, + axis2_libxml2_writer_wrapper_write_start_element, + axis2_libxml2_writer_wrapper_end_start_element, + axis2_libxml2_writer_wrapper_write_start_element_with_namespace, + axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix, + axis2_libxml2_writer_wrapper_write_empty_element, + axis2_libxml2_writer_wrapper_write_empty_element_with_namespace, + axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix, + axis2_libxml2_writer_wrapper_write_end_element, + axis2_libxml2_writer_wrapper_write_end_document, axis2_libxml2_writer_wrapper_write_attribute, + axis2_libxml2_writer_wrapper_write_attribute_with_namespace, + axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix, + axis2_libxml2_writer_wrapper_write_namespace, + axis2_libxml2_writer_wrapper_write_default_namespace, + axis2_libxml2_writer_wrapper_write_comment, + axis2_libxml2_writer_wrapper_write_processing_instruction, + axis2_libxml2_writer_wrapper_write_processing_instruction_data, + axis2_libxml2_writer_wrapper_write_cdata, axis2_libxml2_writer_wrapper_write_dtd, + axis2_libxml2_writer_wrapper_write_entity_ref, + axis2_libxml2_writer_wrapper_write_start_document, + axis2_libxml2_writer_wrapper_write_start_document_with_version, + axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding, + axis2_libxml2_writer_wrapper_write_characters, axis2_libxml2_writer_wrapper_get_prefix, + axis2_libxml2_writer_wrapper_set_prefix, axis2_libxml2_writer_wrapper_set_default_prefix, + axis2_libxml2_writer_wrapper_write_encoded, axis2_libxml2_writer_wrapper_get_xml, + axis2_libxml2_writer_wrapper_get_xml_size, axis2_libxml2_writer_wrapper_get_type, + axis2_libxml2_writer_wrapper_write_raw, axis2_libxml2_writer_wrapper_flush }; + +AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL +axiom_xml_writer_create( + const axutil_env_t * env, + axis2_char_t * filename, + axis2_char_t * encoding, + int is_prefix_default, + int compression) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + writer_impl = (axis2_libxml2_writer_wrapper_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_libxml2_writer_wrapper_impl_t)); + if(!writer_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create an XML writer wrapper"); + return NULL; + } + writer_impl->xml_writer = xmlNewTextWriterFilename(filename, compression); + + if(!(writer_impl->xml_writer)) + { + AXIS2_FREE(env->allocator, writer_impl); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_WRITER, AXIS2_FAILURE); + return NULL; + } + writer_impl->buffer = NULL; + writer_impl->encoding = NULL; + writer_impl->compression = 0; + writer_impl->in_empty_element = AXIS2_FALSE; + writer_impl->in_start_element = AXIS2_FALSE; + writer_impl->stack = NULL; + writer_impl->uri_prefix_map = NULL; + writer_impl->default_lang_namespace = NULL; + + writer_impl->writer_type = AXIS2_XML_PARSER_TYPE_FILE; + writer_impl->compression = compression; + + if(encoding) + { + writer_impl->encoding = axutil_strdup(env, encoding); + } + else + { + writer_impl->encoding = axutil_strdup(env, ENCODING); + } + + writer_impl->uri_prefix_map = axutil_hash_make(env); + if(!(writer_impl->uri_prefix_map)) + { + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create URI prefix hash map"); + return NULL; + } + writer_impl->writer.ops = &axiom_xml_writer_ops_var; + return &(writer_impl->writer); +} + +AXIS2_EXTERN axiom_xml_writer_t *AXIS2_CALL +axiom_xml_writer_create_for_memory( + const axutil_env_t * env, + axis2_char_t * encoding, + int is_prefix_default, + int compression, + int type) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, NULL); + writer_impl = (axis2_libxml2_writer_wrapper_impl_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_libxml2_writer_wrapper_impl_t)); + if(!writer_impl) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create writer wrapper"); + return NULL; + } + + writer_impl->encoding = NULL; + writer_impl->buffer = NULL; + writer_impl->doc = NULL; + writer_impl->in_empty_element = AXIS2_FALSE; + writer_impl->in_start_element = AXIS2_FALSE; + writer_impl->stack = NULL; + writer_impl->uri_prefix_map = NULL; + writer_impl->default_lang_namespace = NULL; + writer_impl->compression = compression; + + if(AXIS2_XML_PARSER_TYPE_BUFFER == type) + { + writer_impl->writer_type = AXIS2_XML_PARSER_TYPE_BUFFER; + writer_impl->buffer = xmlBufferCreate(); + if(!(writer_impl->buffer)) + { + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create a buffer for writer wrapper"); + return NULL; + } + + writer_impl->xml_writer = xmlNewTextWriterMemory(writer_impl->buffer, 0); + } + else if(AXIS2_XML_PARSER_TYPE_DOC == type) + { + writer_impl->writer_type = AXIS2_XML_PARSER_TYPE_DOC; + writer_impl->xml_writer = xmlNewTextWriterDoc(&writer_impl->doc, 0); + } + else + { + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_XML_PARSER_INVALID_MEM_TYPE, AXIS2_FAILURE); + return NULL; + } + + if(!(writer_impl->xml_writer)) + { + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env); + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_CREATING_XML_STREAM_WRITER, AXIS2_FAILURE); + return NULL; + } + + if(encoding) + { + writer_impl->encoding = axutil_strdup(env, encoding); + } + else + { + writer_impl->encoding = axutil_strdup(env, ENCODING); + } + + writer_impl->uri_prefix_map = axutil_hash_make(env); + if(!(writer_impl->uri_prefix_map)) + { + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create URI prefix hash map"); + return NULL; + } + writer_impl->stack = axutil_stack_create(env); + if(!(writer_impl->stack)) + { + axis2_libxml2_writer_wrapper_free(&(writer_impl->writer), env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create the stack for writer wrapper"); + return NULL; + } + + writer_impl->writer.ops = &axiom_xml_writer_ops_var; + + return &(writer_impl->writer); +} + +void AXIS2_CALL +axis2_libxml2_writer_wrapper_free( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + if(writer_impl->xml_writer) + { + xmlFreeTextWriter(writer_impl->xml_writer); + writer_impl->xml_writer = NULL; + } + if(writer_impl->buffer) + { + xmlBufferFree(writer_impl->buffer); + writer_impl->buffer = NULL; + } + if(writer_impl->encoding) + { + AXIS2_FREE(env->allocator, writer_impl->encoding); + writer_impl->encoding = NULL; + } + if(writer_impl->uri_prefix_map) + { + axutil_hash_free(writer_impl->uri_prefix_map, env); + writer_impl->uri_prefix_map = NULL; + } + if(writer_impl->stack) + { + axutil_stack_free(writer_impl->stack, env); + writer_impl->stack = NULL; + } + if(writer_impl->default_lang_namespace) + { + uri_prefix_element_free(writer_impl->default_lang_namespace, env); + writer_impl->default_lang_namespace = NULL; + } + + AXIS2_FREE(env->allocator, writer_impl); + writer_impl = NULL; + return; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname) +{ + int status = 0; + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + writer_impl->in_start_element = AXIS2_TRUE; + + status = xmlTextWriterStartElement(writer_impl->xml_writer, (xmlChar *)localname); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_end_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + /* nothing to do , + it is automatically taken care by the libxml2 writer */ + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterStartElementNS(writer_impl->xml_writer, + NULL, BAD_CAST localname, NULL); + + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + writer_impl->in_start_element = AXIS2_TRUE; + + status = xmlTextWriterStartElementNS(writer_impl->xml_writer, + BAD_CAST prefix, + BAD_CAST localname, BAD_CAST NULL); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE_PREFIX, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_empty_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname) +{ + int status = 0; + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterStartElement(writer_impl->xml_writer, (xmlChar *)localname); + + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + status = xmlTextWriterEndElement(writer_impl->xml_writer); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_empty_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterStartElementNS(writer_impl->xml_writer, + NULL, BAD_CAST localname, + BAD_CAST namespace_uri); + + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + status = xmlTextWriterEndElement(writer_impl->xml_writer); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_empty_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterStartElementNS(writer_impl->xml_writer, + BAD_CAST prefix, + BAD_CAST localname, BAD_CAST NULL); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_ELEMENT_WITH_NAMESPACE_PREFIX, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + status = xmlTextWriterEndElement(writer_impl->xml_writer); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_EMPTY_ELEMENT_WITH_NAMESPACE_PREFIX, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_end_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + writer_impl->in_start_element = AXIS2_FALSE; + /* write an empty element in case the element is empty, + status = xmlTextWriterFullEndElement(writer_impl->xml_writer); + Above call write it like <a></a>. + Call below will write it like <a/> */ + status = xmlTextWriterEndElement(writer_impl->xml_writer); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_END_ELEMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_end_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterEndDocument(writer_impl->xml_writer); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_END_DOCUMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_attribute( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + if(!value) + { + value = ""; + } + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterWriteAttribute(writer_impl->xml_writer, + BAD_CAST localname, BAD_CAST value); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_attribute_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + + if(!value) + { + value = ""; + } + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterWriteAttributeNS(writer_impl->xml_writer, + NULL, BAD_CAST localname, + BAD_CAST NULL, BAD_CAST value); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_attribute_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + + if(!value) + { + value = ""; + } + writer_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterWriteAttributeNS(writer_impl->xml_writer, + BAD_CAST prefix, BAD_CAST localname, + BAD_CAST NULL, BAD_CAST value); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE_PREFIX, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +/** need to work on this */ +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * namespace_uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + char *xmlnsprefix = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + if(prefix && (axutil_strcmp(prefix, "") != 0)) + { + xmlnsprefix = (axis2_char_t *)AXIS2_MALLOC(env->allocator, (sizeof(char) * (axutil_strlen( + prefix) + 7))); + sprintf(xmlnsprefix, "xmlns:%s", prefix); + } + else + { + xmlnsprefix = axutil_strdup(env, "xmlns"); + } + + status = xmlTextWriterWriteAttribute(writer_impl->xml_writer, + BAD_CAST xmlnsprefix, + BAD_CAST namespace_uri); + AXIS2_FREE(env->allocator, xmlnsprefix); + xmlnsprefix = NULL; + + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_ATTRIBUTE_WITH_NAMESPACE_PREFIX, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + AXIS2_FREE(env->allocator, xmlnsprefix); + xmlnsprefix = NULL; + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_default_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * namespace_uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + axis2_char_t *xmlns = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, namespace_uri, AXIS2_FAILURE) + xmlns = AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * (strlen("xmlns") + 1)); + sprintf(xmlns, "xmlns"); + status = xmlTextWriterWriteAttribute(writer_impl->xml_writer, + (const xmlChar *) xmlns, + BAD_CAST namespace_uri); + + if(xmlns) + { + AXIS2_FREE(env->allocator, xmlns); + xmlns = NULL; + } + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_DEFAULT_NAMESPACE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_comment( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * value) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterWriteComment(writer_impl->xml_writer, BAD_CAST value); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_COMMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_processing_instruction( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterStartPI(writer_impl->xml_writer, BAD_CAST target); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_PROCESSING_INSTRUCTION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_processing_instruction_data( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target, + axis2_char_t * data) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterWritePI(writer_impl->xml_writer, + BAD_CAST target, BAD_CAST data); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_PROCESSING_INSTRUCTION, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_cdata( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * data) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, data, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterWriteCDATA(writer_impl->xml_writer, BAD_CAST data); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_CDATA, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_dtd( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * dtd) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, dtd, AXIS2_FAILURE); + + status = xmlTextWriterStartDTD(writer_impl->xml_writer, + BAD_CAST dtd, NULL, NULL); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_DTD, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_entity_ref( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * name) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, name, AXIS2_FAILURE); + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *wrapper_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + wrapper_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterStartDocument(wrapper_impl->xml_writer, NULL, NULL, NULL); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_document_with_version( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * version) +{ + axis2_libxml2_writer_wrapper_impl_t *wrapper_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, version, AXIS2_FAILURE); + + wrapper_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterStartDocument(wrapper_impl->xml_writer, version, NULL, NULL); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_start_document_with_version_encoding( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * encoding, + axis2_char_t * version) +{ + axis2_libxml2_writer_wrapper_impl_t *wrapper_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + wrapper_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterStartDocument(wrapper_impl->xml_writer, version, encoding, NULL); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_characters( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + status = xmlTextWriterWriteString(writer_impl->xml_writer, BAD_CAST text); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_START_DOCUMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +axis2_char_t *AXIS2_CALL +axis2_libxml2_writer_wrapper_get_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_PARAM_CHECK(env->error, uri, NULL); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + if(!uri || axutil_strcmp(uri, "") == 0) + { + return NULL; + } + return axis2_libxml2_writer_wrapper_find_prefix(writer, env, uri); +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_set_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + + axis2_bool_t is_declared = AXIS2_FALSE; + axis2_char_t key[1024]; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, prefix, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + if(axutil_strcmp(uri, "") == 0) + { + return AXIS2_FAILURE; + } + + create_key_from_uri_prefix(env, uri, prefix, key); + + is_declared = axis2_libxml2_writer_wrapper_is_namespace_declared(writer, env, key); + if(!is_declared) + { + return axis2_libxml2_writer_wrapper_push(writer, env, uri, prefix); + } + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_set_default_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axis2_bool_t is_declared = AXIS2_FALSE; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + if(axutil_strcmp(uri, "") == 0) + { + return AXIS2_FAILURE; + } + is_declared = axis2_libxml2_writer_wrapper_is_namespace_declared(writer, env, uri); + if(!is_declared) + { + return axis2_libxml2_writer_wrapper_push(writer, env, uri, NULL); + } + return AXIS2_FAILURE; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_encoded( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text, + int in_attr) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + return AXIS2_FAILURE; +} + +void *AXIS2_CALL +axis2_libxml2_writer_wrapper_get_xml( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + writer_impl = AXIS2_INTF_TO_IMPL(writer); + if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_BUFFER) + { + int output_bytes = 0; + output_bytes = xmlTextWriterFlush(writer_impl->xml_writer); + return writer_impl->buffer->content; + } + else if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_DOC) + { + return (void *)writer_impl->doc; + } + else if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_FILE) + { + return NULL; + } + + return NULL; +} + +unsigned int AXIS2_CALL +axis2_libxml2_writer_wrapper_get_xml_size( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + if(writer_impl->writer_type == AXIS2_XML_PARSER_TYPE_BUFFER) + { + return writer_impl->buffer->use; + } + else + { + return 0; + } +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_flush( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + writer_impl = AXIS2_INTF_TO_IMPL(writer); + if(writer_impl->xml_writer) + { + int ret = 0; + ret = xmlTextWriterFlush(writer_impl->xml_writer); + if(ret > -1) + return AXIS2_SUCCESS; + } + + return AXIS2_FAILURE; +} + +int AXIS2_CALL +axis2_libxml2_writer_wrapper_get_type( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + return writer_impl->writer_type; +} + +static axis2_status_t +axis2_libxml2_writer_wrapper_push( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + axutil_array_list_t *current_list = NULL; + axis2_char_t key[1024]; + const axis2_char_t *temp_prefix = NULL; + writer_impl = AXIS2_INTF_TO_IMPL(writer); + if(!prefix || axutil_strcmp(prefix, "") == 0) + { + temp_prefix = "default"; + } + else + { + temp_prefix = prefix; + } + + if(writer_impl->stack) + { + current_list = (axutil_array_list_t *)axutil_stack_get(writer_impl->stack, env); + + if(current_list) + { + uri_prefix_element_t *ele = NULL; + create_key_from_uri_prefix(env, uri, prefix, key); + + ele = uri_prefix_element_create(env, uri, temp_prefix, prefix, key); + if(ele) + { + axutil_array_list_add(current_list, env, ele); + axutil_hash_set(writer_impl->uri_prefix_map, ele->key, AXIS2_HASH_KEY_STRING, + ele->prefix); + } + } + } + return AXIS2_SUCCESS; +} + +static axis2_bool_t +axis2_libxml2_writer_wrapper_is_namespace_declared( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * key) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + AXIS2_ENV_CHECK(env, AXIS2_FALSE); + writer_impl = AXIS2_INTF_TO_IMPL(writer); + if(writer_impl->uri_prefix_map && NULL != key) + { + void *ret = NULL; + ret = axutil_hash_get(writer_impl->uri_prefix_map, key, AXIS2_HASH_KEY_STRING); + if(ret) + { + return AXIS2_TRUE; + } + } + return AXIS2_FALSE; +} + +static void +uri_prefix_element_free( + uri_prefix_element_t * up_element, + const axutil_env_t * env) +{ + if(up_element) + { + if(up_element->uri) + { + AXIS2_FREE(env->allocator, up_element->uri); + up_element->uri = NULL; + } + if(up_element->prefix) + { + AXIS2_FREE(env->allocator, up_element->prefix); + up_element->prefix = NULL; + } + if(up_element->key) + { + AXIS2_FREE(env->allocator, up_element->key); + up_element->key = NULL; + } + if(up_element->real_prefix) + { + AXIS2_FREE(env->allocator, up_element->real_prefix); + up_element->real_prefix = NULL; + } + AXIS2_FREE(env->allocator, up_element); + up_element = NULL; + } + return; +} + +static uri_prefix_element_t * +uri_prefix_element_create( + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix, + const axis2_char_t * real_prefix, + const axis2_char_t * key) +{ + uri_prefix_element_t *up_element = NULL; + up_element = (uri_prefix_element_t *)AXIS2_MALLOC(env->allocator, sizeof(uri_prefix_element_t)); + + if(!uri) + { + return NULL; + } + + if(!up_element) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create URI prefix element %s", + uri); + return NULL; + } + up_element->key = NULL; + up_element->prefix = NULL; + up_element->uri = NULL; + up_element->real_prefix = NULL; + + up_element->uri = axutil_strdup(env, uri); + if(!up_element->uri) + { + uri_prefix_element_free(up_element, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + up_element->prefix = axutil_strdup(env, prefix); + if(prefix && !up_element->prefix) + { + uri_prefix_element_free(up_element, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + up_element->key = axutil_strdup(env, key); + if(key && !up_element->key) + { + uri_prefix_element_free(up_element, env); + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + up_element->real_prefix = axutil_strdup(env, real_prefix); + + return up_element; +} + +static void +create_key_from_uri_prefix( + const axutil_env_t * env, + const axis2_char_t * uri, + const axis2_char_t * prefix, + axis2_char_t * array) +{ + if(!prefix) + { + prefix = ""; + } + sprintf(array, "%s%s%s", uri, "|", prefix); +} + +static axis2_char_t * +axis2_libxml2_writer_wrapper_find_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int size = 0; + int i = 0; + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + + if(!writer_impl->stack) + { + return NULL; + } + size = axutil_stack_size(writer_impl->stack, env); + if(size <= 0) + { + return NULL; + } + + for(i = size - 1; i < 0; i--) + { + axutil_array_list_t *context = NULL; + void *value = NULL; + value = axutil_stack_get_at(writer_impl->stack, env, i); + if(value) + { + uri_prefix_element_t *up_ele = NULL; + context = (axutil_array_list_t *)value; + up_ele = axis2_libxml2_writer_wrapper_find_prefix_in_context(context, env, uri); + if(up_ele) + { + return up_ele->real_prefix; + } + } + } + return NULL; +} + +static uri_prefix_element_t * +axis2_libxml2_writer_wrapper_find_prefix_in_context( + axutil_array_list_t * context, + const axutil_env_t * env, + axis2_char_t * uri) +{ + int size = 0; + int i = 0; + if(!context) + { + return NULL; + } + size = axutil_array_list_size(context, env); + for(i = 0; i < size; i++) + { + uri_prefix_element_t *ele = NULL; + void *value = NULL; + value = axutil_array_list_get(context, env, i); + if(value) + { + ele = (uri_prefix_element_t *)value; + if(ele->uri && axutil_strcmp(uri, ele->uri)) + { + return ele; + } + } + } + return NULL; +} + +axis2_status_t AXIS2_CALL +axis2_libxml2_writer_wrapper_write_raw( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * content) +{ + axis2_libxml2_writer_wrapper_impl_t *writer_impl = NULL; + int status = 0; + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, content, AXIS2_FAILURE); + + writer_impl = AXIS2_INTF_TO_IMPL(writer); + status = xmlTextWriterWriteRaw(writer_impl->xml_writer, BAD_CAST content); + if(status < 0) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_WRITING_DATA_SOURCE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} diff --git a/axiom/src/parser/xml_reader.c b/axiom/src/parser/xml_reader.c new file mode 100644 index 0000000..47e2334 --- /dev/null +++ b/axiom/src/parser/xml_reader.c @@ -0,0 +1,203 @@ +/* + * 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_xml_reader.h> + +AXIS2_EXTERN int AXIS2_CALL +axiom_xml_reader_next( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->next(parser, env); +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xml_reader_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + (parser)->ops->free(parser, env); +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_xml_reader_get_attribute_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_attribute_count(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_attribute_name_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + return (parser)->ops->get_attribute_name_by_number(parser, env, i); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_attribute_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + return (parser)->ops->get_attribute_prefix_by_number(parser, env, i); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_attribute_value_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + return (parser)->ops->get_attribute_value_by_number(parser, env, i); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_attribute_namespace_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + return (parser)->ops->get_attribute_namespace_by_number(parser, env, i); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_value( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_value(parser, env); +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_xml_reader_get_namespace_count( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_namespace_count(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_namespace_uri_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + return (parser)->ops->get_namespace_uri_by_number(parser, env, i); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_namespace_prefix_by_number( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + int i) +{ + return (parser)->ops->get_namespace_prefix_by_number(parser, env, i); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_prefix(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_name( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_name(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_pi_target( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_pi_target(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_pi_data( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_pi_data(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_dtd( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_dtd(parser, env); +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xml_reader_xml_free( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + void *data) +{ + (parser)->ops->xml_free(parser, env, data); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_char_set_encoding( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_char_set_encoding(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_namespace_uri( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_namespace_uri(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_namespace_uri_by_prefix( + axiom_xml_reader_t * parser, + const axutil_env_t * env, + axis2_char_t * prefix) +{ + return (parser)->ops->get_namespace_uri_by_prefix(parser, env, prefix); +} + +AXIS2_EXTERN void *AXIS2_CALL +axiom_xml_reader_get_context( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_context(parser, env); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_reader_get_current_buffer( + axiom_xml_reader_t * parser, + const axutil_env_t * env) +{ + return (parser)->ops->get_current_buffer(parser, env); +} + diff --git a/axiom/src/parser/xml_writer.c b/axiom/src/parser/xml_writer.c new file mode 100644 index 0000000..cefaeae --- /dev/null +++ b/axiom/src/parser/xml_writer.c @@ -0,0 +1,337 @@ +/* + * 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_xml_writer.h> + +AXIS2_EXTERN void AXIS2_CALL +axiom_xml_writer_free( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + (writer)->ops->free(writer, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname) +{ + return (writer)->ops->write_start_element(writer, env, localname); + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_end_start_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->end_start_element(writer, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_start_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri) +{ + return (writer)->ops->write_start_element_with_namespace(writer, env, localname, namespace_uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_start_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + return (writer)->ops->write_start_element_with_namespace_prefix(writer, env, localname, + namespace_uri, prefix); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_empty_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname) +{ + return (writer)->ops->write_empty_element(writer, env, localname); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_empty_element_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri) +{ + return (writer)->ops->write_empty_element_with_namespace(writer, env, localname, namespace_uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_empty_element_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + return (writer)->ops->write_empty_element_with_namespace_prefix(writer, env, localname, + namespace_uri, prefix); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_end_element( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->write_end_element(writer, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_end_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->write_end_document(writer, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_attribute( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value) +{ + return (writer)->ops->write_attribute(writer, env, localname, value); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_attribute_with_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri) +{ + return (writer)->ops->write_attribute_with_namespace(writer, env, localname, value, + namespace_uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_attribute_with_namespace_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * localname, + axis2_char_t * value, + axis2_char_t * namespace_uri, + axis2_char_t * prefix) +{ + return (writer)->ops->write_attribute_with_namespace_prefix(writer, env, localname, value, + namespace_uri, prefix); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * namespace_uri) +{ + return (writer)->ops->write_namespace(writer, env, prefix, namespace_uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_default_namespace( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * namespace_uri) +{ + return (writer)->ops->write_default_namespace(writer, env, namespace_uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_comment( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * value) +{ + return (writer)->ops->write_comment(writer, env, value); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_processing_instruction( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target) +{ + return (writer)->ops->write_processing_instruction(writer, env, target); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_processing_instruction_data( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * target, + axis2_char_t * data) +{ + return (writer)->ops->write_processing_instruction_data(writer, env, target, data); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_cdata( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * data) +{ + return (writer)->ops->write_cdata(writer, env, data); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_dtd( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * dtd) +{ + return (writer)->ops->write_cdata(writer, env, dtd); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_entity_ref( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * name) +{ + return (writer)->ops->write_entity_ref(writer, env, name); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_start_document( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->write_start_document(writer, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_start_document_with_version( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * version) +{ + return (writer)->ops->write_start_document_with_version(writer, env, version); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_start_document_with_version_encoding( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * version, + axis2_char_t * encoding) +{ + return (writer)->ops->write_start_document_with_version_encoding(writer, env, encoding, version); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_characters( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text) +{ + return (writer)->ops->write_characters(writer, env, text); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_xml_writer_get_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + return (writer)->ops->get_prefix(writer, env, uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_set_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * prefix, + axis2_char_t * uri) +{ + return (writer)->ops->set_prefix(writer, env, prefix, uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_set_default_prefix( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * uri) +{ + return (writer)->ops->set_default_prefix(writer, env, uri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_encoded( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * text, + int in_attr) +{ + return (writer)->ops->write_encoded(writer, env, text, in_attr); +} + +AXIS2_EXTERN void *AXIS2_CALL +axiom_xml_writer_get_xml( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->get_xml(writer, env); +} + +AXIS2_EXTERN unsigned int AXIS2_CALL +axiom_xml_writer_get_xml_size( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->get_xml_size(writer, env); +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_xml_writer_get_type( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->get_type(writer, env); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_write_raw( + axiom_xml_writer_t * writer, + const axutil_env_t * env, + axis2_char_t * content) +{ + return (writer)->ops->write_raw(writer, env, content); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_xml_writer_flush( + axiom_xml_writer_t * writer, + const axutil_env_t * env) +{ + return (writer)->ops->flush(writer, env); +} diff --git a/axiom/src/soap/Makefile.am b/axiom/src/soap/Makefile.am new file mode 100644 index 0000000..5b53ba8 --- /dev/null +++ b/axiom/src/soap/Makefile.am @@ -0,0 +1,33 @@ +noinst_LTLIBRARIES = libaxis2_soap.la +libaxis2_soap_la_SOURCES = soap_fault.c \ + soap_fault_code.c \ + soap_fault_detail.c \ + soap_fault_node.c \ + soap_fault_reason.c \ + soap_fault_role.c \ + soap_fault_sub_code.c \ + soap_fault_text.c \ + soap_fault_value.c \ + soap_header_block.c \ + soap_header.c \ + soap_body.c \ + soap_envelope.c \ + soap_builder.c \ + soap11_builder_helper.c \ + soap12_builder_helper.c + +libaxis2_soap_la_LIBADD = +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/parser \ + -I$(top_builddir)/src/om \ + -I ../../../util/include + +EXTRA_DIST = axiom_soap11_builder_helper.h \ + _axiom_soap_fault_code.h _axiom_soap_fault_reason.h \ + _axiom_soap_fault_value.h axiom_soap12_builder_helper.h \ + _axiom_soap_fault_detail.h _axiom_soap_fault_role.h \ + _axiom_soap_header_block.h _axiom_soap_body.h \ + _axiom_soap_fault.h _axiom_soap_fault_sub_code.h \ + _axiom_soap_header.h _axiom_soap_envelope.h \ + _axiom_soap_fault_node.h _axiom_soap_fault_text.h + diff --git a/axiom/src/soap/_axiom_soap_body.h b/axiom/src/soap/_axiom_soap_body.h new file mode 100644 index 0000000..bb25b84 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_body.h @@ -0,0 +1,69 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_BODY_H +#define _AXIOM_SOAP_BODY_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_body.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_body Soap Body + * @ingroup axiom_soap + * @{ + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_body_set_base_node( + axiom_soap_body_t * body, + const axutil_env_t * env, + axiom_node_t * om_node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_body_set_builder( + axiom_soap_body_t * body, + const axutil_env_t * env, + struct axiom_soap_builder *builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_body_set_fault( + axiom_soap_body_t * body, + const axutil_env_t * env, + struct axiom_soap_fault *soap_fault); + + AXIS2_EXTERN axiom_soap_body_t *AXIS2_CALL + axiom_soap_body_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_BODY_H */ diff --git a/axiom/src/soap/_axiom_soap_envelope.h b/axiom/src/soap/_axiom_soap_envelope.h new file mode 100644 index 0000000..1c446cc --- /dev/null +++ b/axiom/src/soap/_axiom_soap_envelope.h @@ -0,0 +1,84 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_ENVELOPE_H +#define _AXIOM_SOAP_ENVELOPE_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_envelope.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_envelope Soap Envelope + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_envelope_set_base_node( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env, + axiom_node_t * om_node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_envelope_set_body( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env, + struct axiom_soap_body *body); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_envelope_set_header( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env, + struct axiom_soap_header *header); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_envelope_set_builder( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env, + struct axiom_soap_builder *soap_builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_envelope_set_soap_version_internal( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env, + int soap_version); + + AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL + + axiom_soap_envelope_create_null( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_ENVELOPE_H */ diff --git a/axiom/src/soap/_axiom_soap_fault.h b/axiom/src/soap/_axiom_soap_fault.h new file mode 100644 index 0000000..2f0c410 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault.h @@ -0,0 +1,105 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_H +#define _AXIOM_SOAP_FAULT_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault Soap fault + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_code( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + struct axiom_soap_fault_code *code); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_reason( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + struct axiom_soap_fault_reason *reason); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_node( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + struct axiom_soap_fault_node *node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_role( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + struct axiom_soap_fault_role *role); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_detail( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + struct axiom_soap_fault_detail *detail); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_base_node( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_builder( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + struct axiom_soap_builder *builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_set_soap_version( + axiom_soap_fault_t * fault, + const axutil_env_t * env, + int soap_version); + + AXIS2_EXTERN int AXIS2_CALL + axiom_soap_fault_get_soap_version( + axiom_soap_fault_t * fault, + const axutil_env_t * env); + + AXIS2_EXTERN axiom_soap_fault_t *AXIS2_CALL + axiom_soap_fault_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_code.h b/axiom/src/soap/_axiom_soap_fault_code.h new file mode 100644 index 0000000..3905a18 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_code.h @@ -0,0 +1,91 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_CODE_H +#define _AXIOM_SOAP_FAULT_CODE_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_code.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_code Soap fault code + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_code_set_value( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + struct axiom_soap_fault_value *fault_val); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_code_set_sub_code( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + struct axiom_soap_fault_sub_code *fault_subcode); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_code_set_base_node( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_fault_code_set_builder( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + struct axiom_soap_builder *soap_builder); + + AXIS2_EXTERN int AXIS2_CALL + axiom_soap_fault_code_get_soap_version( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_code_set_soap_version( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + int soap_version); + + AXIS2_EXTERN axiom_soap_fault_code_t *AXIS2_CALL + + axiom_soap_fault_code_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_CODE_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_detail.h b/axiom/src/soap/_axiom_soap_fault_detail.h new file mode 100644 index 0000000..69369ca --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_detail.h @@ -0,0 +1,60 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_DETAIL_H +#define _AXIOM_SOAP_FAULT_DETAIL_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_detail.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_detail soap fault detail + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_detail_set_base_node( + axiom_soap_fault_detail_t * fault_detail, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axiom_soap_fault_detail_t *AXIS2_CALL + + axiom_soap_fault_detail_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_DETAIL_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_node.h b/axiom/src/soap/_axiom_soap_fault_node.h new file mode 100644 index 0000000..94ddad7 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_node.h @@ -0,0 +1,60 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_NODE_H +#define _AXIOM_SOAP_FAULT_NODE_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_node.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_node Soap fault_node + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_node_set_base_node( + axiom_soap_fault_node_t * fault_node, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axiom_soap_fault_node_t *AXIS2_CALL + + axiom_soap_fault_node_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_NODE_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_reason.h b/axiom/src/soap/_axiom_soap_fault_reason.h new file mode 100644 index 0000000..2307a31 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_reason.h @@ -0,0 +1,87 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_REASON_H +#define _AXIOM_SOAP_FAULT_REASON_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_reason.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_reason Soap Reason + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_reason_set_builder( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + struct axiom_soap_builder *builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_reason_set_base_node( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_reason_set_soap_fault_text( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + struct axiom_soap_fault_text *soap_text); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_reason_set_soap_version( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + int soap_version); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_reason_get_soap_version( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env); + + AXIS2_EXTERN axiom_soap_fault_reason_t *AXIS2_CALL + + axiom_soap_fault_reason_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_REASON_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_role.h b/axiom/src/soap/_axiom_soap_fault_role.h new file mode 100644 index 0000000..9c4ec4b --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_role.h @@ -0,0 +1,60 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_ROLE_H +#define _AXIOM_SOAP_FAULT_ROLE_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_role.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_role Soap_fault_role + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_role_set_base_node( + axiom_soap_fault_role_t * fault_role, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axiom_soap_fault_role_t *AXIS2_CALL + + axiom_soap_fault_role_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_ROLE_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_sub_code.h b/axiom/src/soap/_axiom_soap_fault_sub_code.h new file mode 100644 index 0000000..878d4e6 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_sub_code.h @@ -0,0 +1,93 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_CODE_SUB_CODE_H +#define _AXIOM_SOAP_FAULT_CODE_SUB_CODE_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_sub_code.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_sub_code Soap_fault_code + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_sub_code_set_sub_code( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + axiom_soap_fault_sub_code_t * sub_code); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_sub_code_set_value( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + struct axiom_soap_fault_value *fault_sub_code_val); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_sub_code_set_base_node( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_sub_code_set_builder( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + struct axiom_soap_builder *builder); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_sub_code_set_soap_version( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + int soap_version); + + AXIS2_EXTERN int AXIS2_CALL + axiom_soap_fault_sub_code_get_soap_version( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env); + + AXIS2_EXTERN axiom_soap_fault_sub_code_t *AXIS2_CALL + + axiom_soap_fault_sub_code_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_CODE_SUB_CODE_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_text.h b/axiom/src/soap/_axiom_soap_fault_text.h new file mode 100644 index 0000000..dfc8772 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_text.h @@ -0,0 +1,60 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_TEXT_H +#define _AXIOM_SOAP_FAULT_TEXT_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_text.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_text soap fault text + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_text_set_base_node( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axiom_soap_fault_text_t *AXIS2_CALL + + axiom_soap_fault_text_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_TEXT_H */ diff --git a/axiom/src/soap/_axiom_soap_fault_value.h b/axiom/src/soap/_axiom_soap_fault_value.h new file mode 100644 index 0000000..a524f7f --- /dev/null +++ b/axiom/src/soap/_axiom_soap_fault_value.h @@ -0,0 +1,60 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_FAULT_VALUE_H +#define _AXIOM_SOAP_FAULT_VALUE_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_fault_value.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_fault_value Soap Fault Value + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_fault_value_set_base_node( + axiom_soap_fault_value_t * fault_value, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL + + axiom_soap_fault_value_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_FAULT_VALUE_H */ diff --git a/axiom/src/soap/_axiom_soap_header.h b/axiom/src/soap/_axiom_soap_header.h new file mode 100644 index 0000000..7571aa6 --- /dev/null +++ b/axiom/src/soap/_axiom_soap_header.h @@ -0,0 +1,77 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_HEADER_H +#define _AXIOM_SOAP_HEADER_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_header.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_header Soap header + * @ingroup axiom_soap + * @{ + */ + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_header_set_base_node( + axiom_soap_header_t * header, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_header_set_soap_version( + axiom_soap_header_t * header, + const axutil_env_t * env, + int soap_version); + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_header_set_header_block( + axiom_soap_header_t * header, + const axutil_env_t * env, + struct axiom_soap_header_block *header_block); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axiom_soap_header_set_builder( + axiom_soap_header_t * header, + const axutil_env_t * env, + struct axiom_soap_builder *builder); + + AXIS2_EXTERN axiom_soap_header_t *AXIS2_CALL + axiom_soap_header_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_HEADER_H */ diff --git a/axiom/src/soap/_axiom_soap_header_block.h b/axiom/src/soap/_axiom_soap_header_block.h new file mode 100644 index 0000000..65cb3ab --- /dev/null +++ b/axiom/src/soap/_axiom_soap_header_block.h @@ -0,0 +1,66 @@ + +/* + * 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. + */ + +#ifndef _AXIOM_SOAP_HEADER_BLOCK_H +#define _AXIOM_SOAP_HEADER_BLOCK_H + +/** @defgroup axiom_soap AXIOM (Axis Object Model) + * @ingroup axis2 + * @{ + */ + +/** @} */ + +#include <axiom_soap_header_block.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_soap_header_block Soap header block + * @ingroup axiom_soap + * @{ + */ + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_header_block_set_soap_version( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + int soap_version); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap_header_block_set_base_node( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + axiom_node_t * node); + + AXIS2_EXTERN axiom_soap_header_block_t *AXIS2_CALL + + axiom_soap_header_block_create( + const axutil_env_t * env); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /** _AXIOM_SOAP_HEADER_BLOCK_H */ diff --git a/axiom/src/soap/axiom_soap11_builder_helper.h b/axiom/src/soap/axiom_soap11_builder_helper.h new file mode 100644 index 0000000..13e914a --- /dev/null +++ b/axiom/src/soap/axiom_soap11_builder_helper.h @@ -0,0 +1,71 @@ + +/* + * 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. + */ + +#ifndef AXIOM_SOAP11_BUILDER_HELPER_H +#define AXIOM_SOAP11_BUILDER_HELPER_H + +/** + * @file axiom_soap_11_builder_helper.h + * @brief axiom_soap11_builder_helper + */ +#include <axiom_soap_builder.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axiom_soap11_builder_helper + axiom_soap11_builder_helper_t; + + /** + * @defgroup axiom_soap11_builder_helper + * @ingroup axiom_soap + * @{ + */ + + /** + * creates a soap11_builder_helper_create + * @param env Environment. MUST NOT be NULL + */ + AXIS2_EXTERN axiom_soap11_builder_helper_t *AXIS2_CALL + + axiom_soap11_builder_helper_create( + const axutil_env_t * env, + axiom_soap_builder_t * soap_builder, + axiom_stax_builder_t * om_builder); + + AXIS2_EXTERN void AXIS2_CALL + axiom_soap11_builder_helper_free( + axiom_soap11_builder_helper_t * builder_helper, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap11_builder_helper_handle_event( + axiom_soap11_builder_helper_t * builder_helper, + const axutil_env_t * env, + axiom_node_t * om_element_node, + int element_level); + + /** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* AXIOM_SOAP11_BUILDER_HELPER_H */ diff --git a/axiom/src/soap/axiom_soap12_builder_helper.h b/axiom/src/soap/axiom_soap12_builder_helper.h new file mode 100644 index 0000000..e901627 --- /dev/null +++ b/axiom/src/soap/axiom_soap12_builder_helper.h @@ -0,0 +1,71 @@ + +/* + * 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. + */ + +#ifndef AXIOM_SOAP12_BUILDER_HELPER_H +#define AXIOM_SOAP12_BUILDER_HELPER_H + +#include <axiom_soap_builder.h> + +/** + * @file axiom_soap_12_builder_helper.h + * @brief axiom_soap12_builder_helper + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axiom_soap12_builder_helper + axiom_soap12_builder_helper_t; + + /** + * @defgroup axiom_soap12_builder_helper + * @ingroup axiom_soap + * @{ + */ + + /** + * creates a soap12_builder_helper_create + * @param env Environment. MUST NOT be NULL + */ + AXIS2_EXTERN axiom_soap12_builder_helper_t *AXIS2_CALL + + axiom_soap12_builder_helper_create( + const axutil_env_t * env, + axiom_soap_builder_t * soap_builder); + + AXIS2_EXTERN void AXIS2_CALL + axiom_soap12_builder_helper_free( + axiom_soap12_builder_helper_t * builder_helper, + const axutil_env_t * env); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + + axiom_soap12_builder_helper_handle_event( + axiom_soap12_builder_helper_t * builder_helper, + const axutil_env_t * env, + axiom_node_t * om_element_node, + int element_level); + + /** @} */ +#ifdef __cplusplus +} +#endif + +#endif /*AXIOM_SOAP11_BUILDER_HELPER_H */ diff --git a/axiom/src/soap/soap11_builder_helper.c b/axiom/src/soap/soap11_builder_helper.c new file mode 100644 index 0000000..ab2e4d8 --- /dev/null +++ b/axiom/src/soap/soap11_builder_helper.c @@ -0,0 +1,340 @@ +/* + * 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_soap11_builder_helper.h" +#include <axiom_stax_builder.h> +#include <axiom_soap_builder.h> +#include <axiom_soap_const.h> +#include "_axiom_soap_fault_code.h" +#include "_axiom_soap_fault_value.h" +#include "_axiom_soap_fault_reason.h" +#include "_axiom_soap_fault.h" +#include "_axiom_soap_body.h" +#include "_axiom_soap_fault_detail.h" +#include <axiom_soap_fault_text.h> +#include "_axiom_soap_fault_role.h" +#include <axiom_stax_builder_internal.h> +#include <axiom_node_internal.h> + +static axis2_status_t +axiom_soap11_builder_helper_process_text( + axiom_soap11_builder_helper_t * builder_helper, + const axutil_env_t * env); + +struct axiom_soap11_builder_helper +{ + axiom_soap_builder_t *soap_builder; + + axis2_bool_t fault_code_present; + + axis2_bool_t fault_string_present; + + axiom_stax_builder_t *om_builder; + + axiom_node_t *last_processed_node; + +}; + +AXIS2_EXTERN axiom_soap11_builder_helper_t *AXIS2_CALL +axiom_soap11_builder_helper_create( + const axutil_env_t * env, + axiom_soap_builder_t * soap_builder, + axiom_stax_builder_t * om_builder) +{ + axiom_soap11_builder_helper_t *builder_helper = NULL; + + AXIS2_PARAM_CHECK(env->error, soap_builder, NULL); + AXIS2_PARAM_CHECK(env->error, om_builder, NULL); + + builder_helper = (axiom_soap11_builder_helper_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap11_builder_helper_t)); + + if(!builder_helper) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP 1.1 builder helper"); + return NULL; + } + + builder_helper->fault_code_present = AXIS2_FALSE; + builder_helper->fault_string_present = AXIS2_FALSE; + builder_helper->last_processed_node = NULL; + builder_helper->soap_builder = soap_builder; + builder_helper->om_builder = om_builder; + + return builder_helper; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap11_builder_helper_free( + axiom_soap11_builder_helper_t * builder_helper, + const axutil_env_t * env) +{ + + AXIS2_FREE(env->allocator, builder_helper); + builder_helper = NULL; + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap11_builder_helper_handle_event( + axiom_soap11_builder_helper_t * builder_helper, + const axutil_env_t * env, + axiom_node_t * om_element_node, + int element_level) +{ + axiom_element_t *om_ele = NULL; + axis2_char_t *ele_localname = NULL; + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_soap_fault_t *soap_fault = NULL; + + AXIS2_PARAM_CHECK(env->error, om_element_node, AXIS2_FAILURE); + + om_ele = (axiom_element_t *)axiom_node_get_data_element(om_element_node, env); + + ele_localname = axiom_element_get_localname(om_ele, env); + if(!ele_localname) + { + return AXIS2_FAILURE; + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(builder_helper->soap_builder, env); + + if(!soap_envelope) + { + return AXIS2_FAILURE; + } + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + if(!soap_body) + { + return AXIS2_FAILURE; + } + + soap_fault = axiom_soap_body_get_fault(soap_body, env); + if(!soap_fault) + { + return AXIS2_FAILURE; + } + + if(element_level == 4) + { + axiom_soap_fault_code_t *fault_code = NULL; + axiom_soap_fault_value_t *fault_value = NULL; + axiom_node_t *fault_value_node = NULL; + axiom_element_t *fault_value_ele = NULL; + + if(axutil_strcmp(ele_localname, AXIOM_SOAP11_SOAP_FAULT_CODE_LOCAL_NAME) == 0) + { + axis2_status_t status = AXIS2_SUCCESS; + + if(builder_helper->fault_string_present) + { + axiom_soap_builder_set_bool_processing_mandatory_fault_elements( + builder_helper->soap_builder, env, AXIS2_FALSE); + } + + fault_code = axiom_soap_fault_code_create(env); + if(!fault_code) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_code_set_base_node(fault_code, env, om_element_node); + + axiom_soap_fault_set_code(soap_fault, env, fault_code); + + axiom_soap_fault_code_set_builder(fault_code, env, builder_helper->soap_builder); + + axiom_element_set_localname(om_ele, env, AXIOM_SOAP12_SOAP_FAULT_CODE_LOCAL_NAME); + + fault_value = axiom_soap_fault_value_create_with_code(env, fault_code); + if(!fault_value) + { + return AXIS2_FAILURE; + } + fault_value_node = axiom_soap_fault_value_get_base_node(fault_value, env); + if(!fault_value_node) + { + return AXIS2_FAILURE; + } + fault_value_ele = (axiom_element_t *)axiom_node_get_data_element(fault_value_node, env); + + axiom_stax_builder_set_lastnode(builder_helper->om_builder, env, fault_value_node); + + status = axiom_soap11_builder_helper_process_text(builder_helper, env); + if(status == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + axiom_stax_builder_set_lastnode(builder_helper->om_builder, env, om_element_node); + axiom_node_set_complete(om_element_node, env, AXIS2_TRUE); + + axiom_stax_builder_set_element_level(builder_helper->om_builder, env, (element_level + - 1)); + builder_helper->fault_code_present = AXIS2_TRUE; + } + else if(axutil_strcmp(AXIOM_SOAP11_SOAP_FAULT_STRING_LOCAL_NAME, ele_localname) == 0) + { + + axiom_soap_fault_reason_t *fault_reason = NULL; + axiom_soap_fault_text_t *fault_text = NULL; + axiom_node_t *fault_text_node = NULL; + int status = AXIS2_SUCCESS; + if(builder_helper->fault_code_present) + { + axiom_soap_builder_set_bool_processing_mandatory_fault_elements( + builder_helper->soap_builder, env, AXIS2_FALSE); + } + + axiom_element_set_localname(om_ele, env, AXIOM_SOAP12_SOAP_FAULT_REASON_LOCAL_NAME); + + fault_reason = axiom_soap_fault_reason_create(env); + if(!fault_reason) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_reason_set_base_node(fault_reason, env, om_element_node); + + axiom_soap_fault_set_reason(soap_fault, env, fault_reason); + + fault_text = axiom_soap_fault_text_create_with_parent(env, fault_reason); + if(!fault_text) + { + return AXIS2_FAILURE; + } + fault_text_node = axiom_soap_fault_text_get_base_node(fault_text, env); + if(!fault_text_node) + { + return AXIS2_FAILURE; + } + axiom_stax_builder_set_lastnode(builder_helper->om_builder, env, fault_text_node); + + status = axiom_soap11_builder_helper_process_text(builder_helper, env); + if(status == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + axiom_stax_builder_set_lastnode(builder_helper->om_builder, env, om_element_node); + + axiom_node_set_complete(om_element_node, env, AXIS2_TRUE); + + axiom_stax_builder_set_element_level(builder_helper->om_builder, env, (element_level + - 1)); + + builder_helper->fault_string_present = AXIS2_TRUE; + + } + else if(axutil_strcmp(AXIOM_SOAP11_SOAP_FAULT_ACTOR_LOCAL_NAME, ele_localname) == 0) + { + axiom_soap_fault_role_t *fault_role = NULL; + fault_role = axiom_soap_fault_role_create(env); + if(!fault_role) + { + return AXIS2_FAILURE; + } + axiom_element_set_localname(om_ele, env, AXIOM_SOAP12_SOAP_FAULT_ROLE_LOCAL_NAME); + + axiom_soap_fault_role_set_base_node(fault_role, env, om_element_node); + + axiom_soap_fault_set_role(soap_fault, env, fault_role); + /* + Role element may not have a namespace associated, hence commented, else it segfaults here - Samisa + status = axiom_soap_builder_process_namespace_data( + builder_helper->soap_builder, env, om_element_node, AXIS2_TRUE); + if(status == AXIS2_FAILURE) + return AXIS2_FAILURE; */ + } + else if(axutil_strcmp(AXIOM_SOAP11_SOAP_FAULT_DETAIL_LOCAL_NAME, ele_localname) == 0) + { + axiom_soap_fault_detail_t *fault_detail = NULL; + fault_detail = axiom_soap_fault_detail_create(env); + if(!fault_detail) + { + return AXIS2_FAILURE; + } + axiom_element_set_localname(om_ele, env, AXIOM_SOAP12_SOAP_FAULT_DETAIL_LOCAL_NAME); + + axiom_soap_fault_detail_set_base_node(fault_detail, env, om_element_node); + + axiom_soap_fault_set_detail(soap_fault, env, fault_detail); + } + else + { + return AXIS2_SUCCESS; + } + } + else if(element_level == 5) + { + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_element = NULL; + axis2_char_t *parent_localname = NULL; + + parent_node = axiom_node_get_parent(om_element_node, env); + if(!parent_node) + { + return AXIS2_FAILURE; + } + parent_element = (axiom_element_t *)axiom_node_get_data_element(om_element_node, env); + parent_localname = axiom_element_get_localname(parent_element, env); + + if(!parent_localname) + { + return AXIS2_FAILURE; + } + if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_ROLE_LOCAL_NAME) == 0) + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP11_FAULT_ACTOR_SHOULD_NOT_HAVE_CHILD_ELEMENTS, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SOAP 1.1 Actor should not have child elements"); + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +static axis2_status_t +axiom_soap11_builder_helper_process_text( + axiom_soap11_builder_helper_t * builder_helper, + const axutil_env_t * env) +{ + int token = 0; + + token = axiom_stax_builder_next_with_token(builder_helper->om_builder, env); + + if(token == -1) + { + return AXIS2_FAILURE; + } + while(token != AXIOM_XML_READER_END_ELEMENT) + { + if(token != AXIOM_XML_READER_CHARACTER) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ONLY_CHARACTERS_ARE_ALLOWED_HERE, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Unidentified character in SOAP 1.1 builder helper processing"); + return AXIS2_FAILURE; + + } + token = axiom_stax_builder_next_with_token(builder_helper->om_builder, env); + if(token == -1) + { + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} diff --git a/axiom/src/soap/soap12_builder_helper.c b/axiom/src/soap/soap12_builder_helper.c new file mode 100644 index 0000000..179d26d --- /dev/null +++ b/axiom/src/soap/soap12_builder_helper.c @@ -0,0 +1,718 @@ +/* + * 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_soap12_builder_helper.h" +#include <axutil_array_list.h> +#include "_axiom_soap_body.h" +#include "_axiom_soap_fault.h" +#include "_axiom_soap_envelope.h" +#include "_axiom_soap_fault_code.h" +#include "_axiom_soap_fault_sub_code.h" +#include "_axiom_soap_fault_node.h" +#include "_axiom_soap_fault_detail.h" +#include "_axiom_soap_fault_reason.h" +#include "_axiom_soap_fault_role.h" +#include "_axiom_soap_fault_value.h" +#include "_axiom_soap_fault_text.h" + +struct axiom_soap12_builder_helper +{ + axiom_soap_builder_t *soap_builder; + + axis2_bool_t code_present; + + axis2_bool_t reason_present; + + axis2_bool_t node_present; + + axis2_bool_t role_present; + + axis2_bool_t detail_present; + + axis2_bool_t subcode_value_present; + + axis2_bool_t value_present; + + axis2_bool_t sub_code_present; + + axis2_bool_t sub_sub_code_present; + + axis2_bool_t code_processing; + + axis2_bool_t sub_code_processing; + + axis2_bool_t reason_processing; + + axutil_array_list_t *detail_element_names; +}; + +AXIS2_EXTERN axiom_soap12_builder_helper_t *AXIS2_CALL +axiom_soap12_builder_helper_create( + const axutil_env_t * env, + axiom_soap_builder_t * soap_builder) +{ + axiom_soap12_builder_helper_t *builder_helper = NULL; + AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, soap_builder, NULL); + + builder_helper = (axiom_soap12_builder_helper_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap12_builder_helper_t)); + if(!builder_helper) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP 1.1 builder helper"); + return NULL; + } + + builder_helper->code_present = AXIS2_FALSE; + builder_helper->detail_present = AXIS2_FALSE; + builder_helper->reason_present = AXIS2_FALSE; + builder_helper->role_present = AXIS2_FALSE; + builder_helper->sub_code_present = AXIS2_FALSE; + builder_helper->reason_processing = AXIS2_FALSE; + builder_helper->code_processing = AXIS2_FALSE; + builder_helper->sub_code_processing = AXIS2_FALSE; + builder_helper->detail_element_names = NULL; + builder_helper->node_present = AXIS2_FALSE; + builder_helper->soap_builder = soap_builder; + builder_helper->sub_sub_code_present = AXIS2_FALSE; + builder_helper->value_present = AXIS2_FALSE; + builder_helper->subcode_value_present = AXIS2_FALSE; + + return builder_helper; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap12_builder_helper_free( + axiom_soap12_builder_helper_t * builder_helper, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + + if(builder_helper->detail_element_names) + { + axutil_array_list_free(builder_helper->detail_element_names, env); + builder_helper->detail_element_names = NULL; + } + + AXIS2_FREE(env->allocator, builder_helper); + builder_helper = NULL; + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap12_builder_helper_handle_event( + axiom_soap12_builder_helper_t * builder_helper, + const axutil_env_t * env, + axiom_node_t * om_ele_node, + int element_level) +{ + axis2_char_t *ele_localname = NULL; + axiom_element_t *om_ele = NULL; + + axiom_soap_body_t *soap_body = NULL; + axiom_soap_fault_t *soap_fault = NULL; + axiom_soap_envelope_t *soap_envelope = NULL; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_ele_node, AXIS2_FAILURE); + + om_ele = (axiom_element_t *)axiom_node_get_data_element(om_ele_node, env); + if(!om_ele) + { + return AXIS2_FAILURE; + } + + ele_localname = axiom_element_get_localname(om_ele, env); + if(!ele_localname) + { + return AXIS2_FAILURE; + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(builder_helper->soap_builder, env); + if(!soap_envelope) + { + return AXIS2_FAILURE; + } + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + if(!soap_body) + { + return AXIS2_FAILURE; + } + + soap_fault = axiom_soap_body_get_fault(soap_body, env); + if(!soap_fault) + { + return AXIS2_FAILURE; + } + + if(element_level == 4) + { + if(axutil_strcmp(AXIOM_SOAP12_SOAP_FAULT_CODE_LOCAL_NAME, ele_localname) == 0) + { + if(builder_helper->code_present) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_CODE_ELEMENTS_ENCOUNTERED, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Multiple fault code elements encountered in SOAP fault"); + return AXIS2_FAILURE; + } + else + { + axiom_soap_fault_code_t *soap_fault_code = NULL; + soap_fault_code = axiom_soap_fault_code_create(env); + if(!soap_fault_code) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_code_set_base_node(soap_fault_code, env, om_ele_node); + + axiom_soap_fault_code_set_builder(soap_fault_code, env, + builder_helper->soap_builder); + + axiom_soap_fault_set_code(soap_fault, env, soap_fault_code); + + builder_helper->code_present = AXIS2_TRUE; + builder_helper->code_processing = AXIS2_TRUE; + } + } + else if(axutil_strcmp(AXIOM_SOAP12_SOAP_FAULT_REASON_LOCAL_NAME, ele_localname) == 0) + { + if(!(builder_helper->code_processing) && !(builder_helper->sub_code_processing)) + { + if(builder_helper->code_present) + { + if(builder_helper->reason_present) + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_MULTIPLE_REASON_ELEMENTS_ENCOUNTERED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Multiple fault reason elements encountered in SOAP fault"); + + return AXIS2_FAILURE; + } + else + { + axiom_soap_fault_reason_t *fault_reason = NULL; + fault_reason = axiom_soap_fault_reason_create(env); + if(!fault_reason) + { + return AXIS2_FAILURE; + } + + axiom_soap_fault_reason_set_base_node(fault_reason, env, om_ele_node); + + axiom_soap_fault_set_reason(soap_fault, env, fault_reason); + + axiom_soap_fault_reason_set_builder(fault_reason, env, + builder_helper-> soap_builder); + + builder_helper->reason_present = AXIS2_TRUE; + builder_helper->reason_processing = AXIS2_TRUE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else + { + if(builder_helper->code_processing) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_FAULT_CODE_DOES_NOT_HAVE_A_VALUE, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_FAULT_CODE_DOES_NOT_HAVE_A_VALUE, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + } + else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_NODE_LOCAL_NAME) == 0) + { + if(!(builder_helper->reason_processing)) + { + if(builder_helper->reason_present && !(builder_helper->role_present) + && !(builder_helper->detail_present)) + { + if(builder_helper->node_present) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_NODE_ELEMENTS_ENCOUNTERED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + axiom_soap_fault_node_t *soap_fault_node = NULL; + soap_fault_node = axiom_soap_fault_node_create(env); + if(!soap_fault_node) + { + return AXIS2_FAILURE; + } + + axiom_soap_fault_node_set_base_node(soap_fault_node, env, om_ele_node); + + axiom_soap_fault_set_node(soap_fault, env, soap_fault_node); + + builder_helper->node_present = AXIS2_TRUE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED, + AXIS2_FALSE); + + return AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_FAULT_REASON_ELEMENT_SHOULD_HAVE_A_TEXT, AXIS2_FALSE); + return AXIS2_FAILURE; + } + + } + else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_ROLE_LOCAL_NAME) == 0) + { + if(!(builder_helper->reason_processing)) + { + if(builder_helper->reason_present && !(builder_helper->detail_present)) + { + if(builder_helper->role_present) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_ROLE_ELEMENTS_ENCOUNTERED, + AXIS2_FAILURE); + + return AXIS2_FAILURE; + } + else + { + axiom_soap_fault_role_t *soap_fault_role = NULL; + soap_fault_role = axiom_soap_fault_role_create(env); + if(!soap_fault_role) + return AXIS2_FAILURE; + + axiom_soap_fault_role_set_base_node(soap_fault_role, env, om_ele_node); + + axiom_soap_fault_set_role(soap_fault, env, soap_fault_role); + builder_helper->role_present = AXIS2_TRUE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else + { + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_FAULT_ROLE_ELEMENT_SHOULD_HAVE_A_TEXT, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_DETAIL_LOCAL_NAME) == 0) + { + if(!(builder_helper->reason_processing)) + { + if(builder_helper->reason_present) + { + if(builder_helper->detail_present) + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_MULTIPLE_DETAIL_ELEMENTS_ENCOUNTERED, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + + axiom_soap_fault_detail_t *soap_fault_detail = NULL; + soap_fault_detail = axiom_soap_fault_detail_create(env); + if(!soap_fault_detail) + return AXIS2_FAILURE; + + axiom_soap_fault_detail_set_base_node(soap_fault_detail, env, om_ele_node); + + axiom_soap_fault_set_detail(soap_fault, env, soap_fault_detail); + builder_helper->detail_present = AXIS2_TRUE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_WRONG_ELEMENT_ORDER_ENCOUNTERED, + AXIS2_FAILURE); + + return AXIS2_FAILURE; + + } + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_FAULT_REASON_ELEMENT_SHOULD_HAVE_A_TEXT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_UNSUPPORTED_ELEMENT_IN_SOAP_FAULT_ELEMENT, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else if(element_level == 5) + { + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axis2_char_t *parent_localname = NULL; + parent_node = axiom_node_get_parent(om_ele_node, env); + if(!parent_node) + { + return AXIS2_FAILURE; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + return AXIS2_FAILURE; + } + parent_localname = axiom_element_get_localname(parent_ele, env); + if(!parent_localname) + { + return AXIS2_FAILURE; + } + + if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_CODE_LOCAL_NAME) == 0) + { + if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME) == 0) + { + if(!(builder_helper->value_present)) + { + axiom_soap_fault_value_t *soap_fault_value = NULL; + axiom_soap_fault_code_t *parent_fcode = NULL; + + soap_fault_value = axiom_soap_fault_value_create(env); + if(!soap_fault_value) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_value_set_base_node(soap_fault_value, env, om_ele_node); + + parent_fcode = axiom_soap_fault_get_code(soap_fault, env); + if(!parent_fcode) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_code_set_value(parent_fcode, env, soap_fault_value); + + builder_helper->value_present = AXIS2_TRUE; + builder_helper->code_processing = AXIS2_FALSE; + + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_MULTIPLE_VALUE_ENCOUNTERED_IN_CODE_ELEMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME) == 0) + { + if(!(builder_helper->sub_code_present)) + { + if(builder_helper->value_present) + { + + axiom_soap_fault_sub_code_t *fault_subcode = NULL; + axiom_soap_fault_code_t *fault_code = NULL; + + fault_subcode = axiom_soap_fault_sub_code_create(env); + if(!fault_subcode) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_sub_code_set_base_node(fault_subcode, env, om_ele_node); + + fault_code = axiom_soap_fault_get_code(soap_fault, env); + if(!fault_code) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_code_set_sub_code(fault_code, env, fault_subcode); + + axiom_soap_fault_sub_code_set_builder(fault_subcode, env, + builder_helper-> soap_builder); + + builder_helper->sub_code_present = AXIS2_TRUE; + builder_helper->sub_code_processing = AXIS2_TRUE; + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_FAULT_VALUE_SHOULD_BE_PRESENT_BEFORE_SUB_CODE, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_THIS_LOCALNAME_NOT_SUPPORTED_INSIDE_THE_CODE_ELEMENT, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + } + else if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_REASON_LOCAL_NAME) == 0) + { + if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_TEXT_LOCAL_NAME) == 0) + { + axiom_soap_fault_text_t *soap_fault_text = NULL; + axiom_soap_fault_reason_t *fault_reason = NULL; + + soap_fault_text = axiom_soap_fault_text_create(env); + if(!soap_fault_text) + { + return AXIS2_FAILURE; + } + axiom_soap_fault_text_set_base_node(soap_fault_text, env, om_ele_node); + + fault_reason = axiom_soap_fault_get_reason(soap_fault, env); + if(!fault_reason) + { + return AXIS2_FAILURE; + } + + axiom_soap_fault_reason_add_soap_fault_text(fault_reason, env, soap_fault_text); + builder_helper->reason_processing = AXIS2_FALSE; + + axiom_soap_builder_set_bool_processing_mandatory_fault_elements( + builder_helper->soap_builder, env, AXIS2_FALSE); + + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_THIS_LOCALNAME_IS_NOT_SUPPORTED_INSIDE_THE_REASON_ELEMENT, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + } + else if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_DETAIL_LOCAL_NAME) == 0) + { + axiom_soap_builder_set_processing_detail_elements(builder_helper-> soap_builder, env, + AXIS2_TRUE); + + if(!(builder_helper->detail_element_names)) + { + builder_helper->detail_element_names = axutil_array_list_create(env, 20); + } + + axutil_array_list_add(builder_helper->detail_element_names, env, ele_localname); + + } + else + { + + return AXIS2_FAILURE; + } + + } + else if(element_level > 5) + { + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axis2_char_t *parent_localname = NULL; + + parent_node = axiom_node_get_parent(om_ele_node, env); + if(!parent_node) + { + return AXIS2_FAILURE; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + return AXIS2_FAILURE; + } + + parent_localname = axiom_element_get_localname(parent_ele, env); + if(!parent_localname) + { + return AXIS2_FAILURE; + } + if(axutil_strcmp(parent_localname, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME) == 0) + { + if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME) == 0) + { + if(builder_helper->subcode_value_present) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED, + AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + + axiom_soap_fault_sub_code_t *sub_code = NULL; + axiom_soap_fault_code_t *code = NULL; + axiom_soap_fault_value_t *value = NULL; + code = axiom_soap_fault_get_code(soap_fault, env); + + if(!code) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "fault code null when it should not be null"); + return AXIS2_FAILURE; + } + + sub_code = axiom_soap_fault_code_get_sub_code(code, env); + if(!sub_code) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "fault subcode null when it should not be null"); + return AXIS2_FAILURE; + } + value = axiom_soap_fault_value_create(env); + if(!value) + { + return AXIS2_FAILURE; + } + + axiom_soap_fault_value_set_base_node(value, env, om_ele_node); + + axiom_soap_fault_sub_code_set_value(sub_code, env, value); + + builder_helper->subcode_value_present = AXIS2_TRUE; + builder_helper->sub_sub_code_present = AXIS2_FALSE; + builder_helper->sub_code_processing = AXIS2_FALSE; + } + } + else if(axutil_strcmp(ele_localname, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME) == 0) + { + if(builder_helper->subcode_value_present) + { + if(!(builder_helper->sub_sub_code_present)) + { + axiom_soap_fault_code_t *fault_code = NULL; + axiom_soap_fault_sub_code_t *parent_subcode = NULL; + axiom_soap_fault_sub_code_t *subcode = NULL; + + subcode = axiom_soap_fault_sub_code_create(env); + if(!subcode) + { + return AXIS2_FAILURE; + } + + axiom_soap_fault_sub_code_set_base_node(subcode, env, om_ele_node); + + fault_code = axiom_soap_fault_get_code(soap_fault, env); + if(!fault_code) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "fault code null when it should not be null"); + return AXIS2_FAILURE; + } + parent_subcode = axiom_soap_fault_code_get_sub_code(fault_code, env); + if(!parent_subcode) + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "fault subcode null when it should not be null"); + return AXIS2_FAILURE; + } + + axiom_soap_fault_sub_code_set_sub_code(parent_subcode, env, subcode); + + builder_helper->subcode_value_present = AXIS2_FALSE; + builder_helper->sub_sub_code_present = AXIS2_TRUE; + builder_helper->sub_code_processing = AXIS2_TRUE; + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_MULTIPLE_SUB_CODE_VALUES_ENCOUNTERED, AXIS2_FAILURE); + + return AXIS2_FAILURE; + } + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_FAULT_VALUE_SHOULD_BE_PRESENT_BEFORE_SUB_CODE, + AXIS2_FAILURE); + + return AXIS2_FAILURE; + + } + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_THIS_LOCALNAME_IS_NOT_SUPPORTED_INSIDE_THE_SUB_CODE_ELEMENT, + AXIS2_FAILURE); + + return AXIS2_FAILURE; + } + } + else if(axiom_soap_builder_is_processing_detail_elements(builder_helper->soap_builder, env)) + { + + int detail_element_level = 0; + axis2_bool_t local_name_exists = AXIS2_FALSE; + int i = 0; + if(!(builder_helper->detail_element_names)) + { + return AXIS2_FAILURE; + } + + for(i = 0; i < axutil_array_list_size(builder_helper->detail_element_names, env); i++) + { + if(axutil_strcmp(parent_localname, axutil_array_list_get( + builder_helper->detail_element_names, env, i)) == 0) + { + local_name_exists = AXIS2_TRUE; + detail_element_level = i + 1; + } + } + if(local_name_exists) + { + axutil_array_list_add(builder_helper->detail_element_names, env, ele_localname); + } + else + { + return AXIS2_FAILURE; + } + } + } + return AXIS2_SUCCESS; +} diff --git a/axiom/src/soap/soap_body.c b/axiom/src/soap/soap_body.c new file mode 100644 index 0000000..8fb7d8f --- /dev/null +++ b/axiom/src/soap/soap_body.c @@ -0,0 +1,547 @@ +/* + * 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_soap_envelope.h" +#include "_axiom_soap_body.h" +#include <axutil_hash.h> +#include <axiom_soap_const.h> +#include <axiom_soap_builder.h> +#include <axiom_soap_fault_code.h> +#include <axiom_soap_fault_reason.h> +#include <axiom_soap_fault_detail.h> +#include <axiom_soap_fault_role.h> +#include "_axiom_soap_fault_value.h" +#include "_axiom_soap_fault_text.h" +#include <axiom_util.h> + +struct axiom_soap_body +{ + axiom_node_t *om_ele_node; + + axis2_bool_t has_fault; + + axiom_soap_fault_t *soap_fault; + + axiom_soap_builder_t *soap_builder; + + int soap_version; +}; + +AXIS2_EXTERN axiom_soap_body_t *AXIS2_CALL +axiom_soap_body_create( + const axutil_env_t * env) +{ + axiom_soap_body_t *soap_body = NULL; + + soap_body = (axiom_soap_body_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_soap_body_t)); + + if(!soap_body) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + soap_body->om_ele_node = NULL; + soap_body->soap_builder = NULL; + soap_body->has_fault = AXIS2_FALSE; + soap_body->soap_fault = NULL; + + return soap_body; +} + +AXIS2_EXTERN axiom_soap_body_t *AXIS2_CALL +axiom_soap_body_create_with_parent( + const axutil_env_t * env, + axiom_soap_envelope_t * envelope) +{ + axiom_soap_body_t *soap_body = NULL; + axiom_element_t *ele = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axiom_namespace_t *om_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, envelope, NULL); + + soap_body = axiom_soap_body_create(env); + if(!soap_body) + { + return NULL; + } + + /*get parent node from SOAP envelope */ + parent_node = axiom_soap_envelope_get_base_node(envelope, env); + if(!parent_node) + { + axiom_soap_body_free(soap_body, env); + return NULL; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + + if(!parent_ele) + { + axiom_soap_body_free(soap_body, env); + return NULL; + } + + om_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + + ele = axiom_element_create(env, parent_node, AXIOM_SOAP_BODY_LOCAL_NAME, om_ns, + &(soap_body->om_ele_node)); + if(!ele) + { + axiom_soap_body_free(soap_body, env); + return NULL; + } + + axiom_soap_envelope_set_body(envelope, env, soap_body); + + return soap_body; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_body_free( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + + if(soap_body->soap_fault) + { + axiom_soap_fault_free(soap_body->soap_fault, env); + soap_body->soap_fault = NULL; + } + AXIS2_FREE(env->allocator, soap_body); + soap_body = NULL; + return; +} + +/** + * Indicates whether a soap fault is available with this soap body + * @param soap_body axiom_soap_body struct + * @param env environment must not be null + * @return AXIS2_TRUE if fault is available, AXIS2_FALSE otherwise + */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_soap_body_has_fault( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + if(soap_body->soap_fault) + { + soap_body->has_fault = AXIS2_TRUE; + } + else + { + while(!axiom_node_is_complete(soap_body->om_ele_node, env)) + { + if(axiom_soap_builder_next(soap_body->soap_builder, env) != AXIS2_SUCCESS) + { + /* problem in building the SOAP body. Note that has_fault is about soap fault, + * not about problem in building the node. So, even though there is a problem + * building the body, has_fault should be AXIS2_FALSE + */ + break; + } + + if(soap_body->soap_fault) + { + soap_body->has_fault = AXIS2_TRUE; + break; + } + } + } + + return soap_body->has_fault; +} + +/** + * Returns the axiom_soap_fault_t struct in this axiom_soap_bodY_t + * struct + * + * @return the <code>SOAPFault</code> object in this <code>SOAPBody</code> + * object + */ +AXIS2_EXTERN axiom_soap_fault_t *AXIS2_CALL +axiom_soap_body_get_fault( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + if(soap_body->soap_fault) + { + return soap_body->soap_fault; + } + else if(soap_body->soap_builder) + { + while(!(soap_body->soap_fault) && !(axiom_node_is_complete(soap_body->om_ele_node, env))) + { + int status = AXIS2_SUCCESS; + status = axiom_soap_builder_next(soap_body->soap_builder, env); + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + if(soap_body->soap_fault) + { + soap_body->has_fault = AXIS2_TRUE; + return soap_body->soap_fault; + } + } + return NULL; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_body_get_base_node( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + return soap_body->om_ele_node; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_set_base_node( + axiom_soap_body_t * soap_body, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + soap_body->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_set_builder( + axiom_soap_body_t * soap_body, + const axutil_env_t * env, + axiom_soap_builder_t * builder) +{ + AXIS2_PARAM_CHECK(env->error, builder, AXIS2_FAILURE); + + soap_body->soap_builder = builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_soap_builder_t *AXIS2_CALL +axiom_soap_body_get_builder( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + if(!soap_body) + { + return NULL; + } + return soap_body->soap_builder; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_build( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + axiom_node_t *xop_node = NULL; + axis2_bool_t is_replaced = AXIS2_FALSE; + axiom_element_t *xop_element = NULL; + + if(soap_body->om_ele_node && soap_body->soap_builder) + { + xop_node + = axiom_util_get_node_by_local_name(env, soap_body->om_ele_node, AXIS2_XOP_INCLUDE); + + if(xop_node) + { + xop_element = (axiom_element_t *)axiom_node_get_data_element(xop_node, env); + if(xop_element) + { + is_replaced = axiom_soap_builder_replace_xop(soap_body->soap_builder, env, + xop_node, xop_element); + } + } + + while(axiom_node_is_complete(soap_body->om_ele_node, env) != AXIS2_TRUE) + { + status = axiom_soap_builder_next(soap_body->soap_builder, env); + if(status == AXIS2_FAILURE) + { + return AXIS2_FAILURE; + } + } + } + return AXIS2_SUCCESS; +} + +/** + This is an internal function + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_set_fault( + axiom_soap_body_t * soap_body, + const axutil_env_t * env, + axiom_soap_fault_t * soap_fault) +{ + AXIS2_PARAM_CHECK(env->error, soap_fault, AXIS2_FAILURE); + if(soap_body->soap_fault) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_ONLY_ONE_SOAP_FAULT_ALLOWED_IN_BODY, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + else + { + soap_body->soap_fault = soap_fault; + soap_body->has_fault = AXIS2_TRUE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_add_child( + axiom_soap_body_t * soap_body, + const axutil_env_t * env, + axiom_node_t * child) +{ + AXIS2_PARAM_CHECK(env->error, child, AXIS2_FAILURE); + + if(soap_body->om_ele_node) + { + return axiom_node_add_child(soap_body->om_ele_node, env, child); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_soap_body_get_soap_version( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + axiom_element_t *body_ele = NULL; + axiom_namespace_t *om_ns = NULL; + axis2_char_t *uri = NULL; + + if(!soap_body->om_ele_node) + { + return AXIS2_FAILURE; + } + body_ele = axiom_node_get_data_element(soap_body->om_ele_node, env); + if(!body_ele) + { + return AXIS2_FAILURE; + } + om_ns = axiom_element_get_namespace(body_ele, env, soap_body->om_ele_node); + if(!om_ns) + { + return AXIS2_FAILURE; + } + uri = axiom_namespace_get_uri(om_ns, env); + if(uri) + { + if(axutil_strcmp(uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI) == 0) + { + return AXIOM_SOAP11; + } + else if(axutil_strcmp(uri, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI) == 0) + { + return AXIOM_SOAP12; + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_convert_fault_to_soap11( + axiom_soap_body_t * soap_body, + const axutil_env_t * env) +{ + if(soap_body) + { + axiom_soap_fault_t *soap_fault = NULL; + if(axiom_soap_body_has_fault(soap_body, env)) + { + soap_fault = axiom_soap_body_get_fault(soap_body, env); + if(soap_fault) + { + axiom_soap_fault_code_t *fault_code = NULL; + axiom_soap_fault_reason_t *fault_reason = NULL; + axiom_soap_fault_detail_t *fault_detail = NULL; + axiom_soap_fault_role_t *fault_role = NULL; + fault_code = axiom_soap_fault_get_code(soap_fault, env); + if(fault_code) + { + axiom_node_t *fault_code_om_node = NULL; + axiom_element_t *fault_code_om_ele = NULL; + axiom_node_t *fault_value_om_node = NULL; + axiom_element_t *fault_value_om_ele = NULL; + axiom_soap_fault_value_t *fault_value = NULL; + axis2_char_t *text = NULL; + + fault_code_om_node = axiom_soap_fault_code_get_base_node(fault_code, env); + if(fault_code_om_node) + { + fault_code_om_ele = (axiom_element_t *)axiom_node_get_data_element( + fault_code_om_node, env); + if(fault_code_om_ele) + { + axiom_element_set_localname(fault_code_om_ele, env, + AXIOM_SOAP11_SOAP_FAULT_CODE_LOCAL_NAME); + + fault_value = axiom_soap_fault_code_get_value(fault_code, env); + + if(fault_value) + { + fault_value_om_node = axiom_soap_fault_value_get_base_node( + fault_value, env); + if(fault_value_om_node) + { + fault_value_om_ele + = (axiom_element_t *)axiom_node_get_data_element( + fault_value_om_node, env); + if(fault_value_om_ele) + { + text = axiom_element_get_text(fault_value_om_ele, env, + fault_value_om_node); + if(text) + { + axiom_element_set_text(fault_code_om_ele, env, text, + fault_code_om_node); + } + } + axiom_node_free_tree(fault_value_om_node, env); + axiom_soap_fault_value_set_base_node(fault_value, env, NULL); + } + } + } + } + } + fault_reason = axiom_soap_fault_get_reason(soap_fault, env); + if(fault_reason) + { + axiom_node_t *fault_reason_om_node = NULL; + axiom_element_t *fault_reason_om_ele = NULL; + axiom_node_t *fault_text_om_node = NULL; + axiom_element_t *fault_text_om_ele = NULL; + axiom_soap_fault_text_t *fault_text = NULL; + axis2_char_t *text = NULL; + + fault_reason_om_node = axiom_soap_fault_reason_get_base_node(fault_reason, env); + if(fault_reason_om_node) + { + fault_reason_om_ele = (axiom_element_t *)axiom_node_get_data_element( + fault_reason_om_node, env); + + if(fault_reason_om_ele) + { + + axiom_element_set_localname(fault_reason_om_ele, env, + AXIOM_SOAP11_SOAP_FAULT_STRING_LOCAL_NAME); + + fault_text = axiom_soap_fault_reason_get_first_soap_fault_text( + fault_reason, env); + if(fault_text) + { + fault_text_om_node = axiom_soap_fault_text_get_base_node( + fault_text, env); + if(fault_text_om_node) + { + fault_text_om_ele + = (axiom_element_t *)axiom_node_get_data_element( + fault_text_om_node, env); + if(fault_text_om_ele) + { + text = axiom_element_get_text(fault_text_om_ele, env, + fault_text_om_node); + if(text) + { + axiom_element_set_text(fault_reason_om_ele, env, text, + fault_reason_om_node); + } + } + axiom_node_free_tree(fault_text_om_node, env); + axiom_soap_fault_text_set_base_node(fault_text, env, NULL); + } + } + } + } + } + + fault_role = axiom_soap_fault_get_role(soap_fault, env); + if(fault_role) + { + axiom_node_t *fault_role_om_node = NULL; + axiom_element_t *fault_role_om_ele = NULL; + + fault_role_om_node = axiom_soap_fault_role_get_base_node(fault_role, env); + if(fault_role_om_node) + { + fault_role_om_ele = (axiom_element_t *)axiom_node_get_data_element( + fault_role_om_node, env); + if(fault_role_om_ele) + { + axiom_element_set_localname(fault_role_om_ele, env, + AXIOM_SOAP11_SOAP_FAULT_ACTOR_LOCAL_NAME); + } + } + } + + fault_detail = axiom_soap_fault_get_detail(soap_fault, env); + if(fault_detail) + { + axiom_node_t *fault_detail_om_node = NULL; + axiom_element_t *fault_detail_om_ele = NULL; + fault_detail_om_node = axiom_soap_fault_detail_get_base_node(fault_detail, env); + if(fault_detail_om_node) + { + fault_detail_om_ele = (axiom_element_t *)axiom_node_get_data_element( + fault_detail_om_node, env); + if(fault_detail_om_ele) + { + axiom_element_set_localname(fault_detail_om_ele, env, + AXIOM_SOAP11_SOAP_FAULT_DETAIL_LOCAL_NAME); + } + } + } + } + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_body_process_attachments( + axiom_soap_body_t * soap_body, + const axutil_env_t * env, + void *user_pram, + axis2_char_t *callback_name) +{ + axis2_status_t status = AXIS2_FAILURE; + + status = axiom_soap_builder_create_attachments(soap_body->soap_builder, env, user_pram, + callback_name); + + if(status == AXIS2_FAILURE) + { + return status; + } + else + { + return axiom_soap_body_build(soap_body, env); + } +} + + diff --git a/axiom/src/soap/soap_builder.c b/axiom/src/soap/soap_builder.c new file mode 100644 index 0000000..6960c03 --- /dev/null +++ b/axiom/src/soap/soap_builder.c @@ -0,0 +1,1206 @@ +/* + * 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_soap_builder.h> +#include "_axiom_soap_envelope.h" +#include "_axiom_soap_header.h" +#include "axiom_soap11_builder_helper.h" +#include "axiom_soap12_builder_helper.h" +#include <axiom_soap_const.h> +#include "_axiom_soap_body.h" +#include "_axiom_soap_header_block.h" +#include <axiom_stax_builder_internal.h> +#include "_axiom_soap_fault.h" +#include <axutil_http_chunked_stream.h> + +static axis2_status_t +axiom_soap_builder_construct_node( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axiom_node_t * om_element_node); + +static axis2_status_t +axiom_soap_builder_identify_soap_version( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + const axis2_char_t * soap_version_uri_from_transport); + +static axis2_status_t +axiom_soap_builder_parse_headers( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env); + +static axis2_status_t +axiom_soap_builder_process_namespace_data( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axiom_node_t * om_node); + +static axis2_status_t +axiom_soap_builder_construct_soap_header( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_node); + +static axis2_status_t +axiom_soap_builder_construct_soap_body( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_node); + +static axis2_status_t +axiom_soap_builder_construct_soap_fault( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_node); + +static axis2_status_t +axiom_soap_builder_construct_xop_include( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_element_node); + +struct axiom_soap_builder +{ + axiom_stax_builder_t *om_builder; + + axiom_soap_envelope_t *soap_envelope; + + axis2_bool_t header_present; + + axis2_bool_t body_present; + + int element_level; + + axis2_bool_t processing_fault; + + axis2_bool_t processing_detail_elements; + + axis2_char_t *sender_fault_code; + + axis2_char_t *receiver_fault_code; + + axis2_bool_t processing_mandatory_fault_elements; + + void *builder_helper; + + axiom_namespace_t *envelope_ns; + + int soap_version; + + int last_node_status; + + axis2_bool_t done; + + axutil_hash_t *mime_body_parts; + + axiom_mime_parser_t *mime_parser; + + AXIS2_READ_INPUT_CALLBACK callback; + + void *callback_ctx; + +}; + +typedef enum axis2_builder_last_node_states +{ + AXIS2_BUILDER_LAST_NODE_NULL = 0, + AXIS2_BUILDER_LAST_NODE_NOT_NULL +} axis2_builder_last_node_states; + +#define AXIS2_MAX_EVENT 100 + +AXIS2_EXTERN axiom_soap_builder_t *AXIS2_CALL +axiom_soap_builder_create( + const axutil_env_t * env, + axiom_stax_builder_t * stax_builder, + const axis2_char_t * soap_version) +{ + axiom_soap_builder_t *soap_builder = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + AXIS2_PARAM_CHECK(env->error, stax_builder, NULL); + + soap_builder = (axiom_soap_builder_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_builder_t)); + + if(soap_builder == NULL) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + soap_builder->done = AXIS2_FALSE; + soap_builder->body_present = AXIS2_FALSE; + soap_builder->builder_helper = NULL; + soap_builder->element_level = 0; + soap_builder->header_present = AXIS2_FALSE; + soap_builder->processing_detail_elements = AXIS2_FALSE; + soap_builder->processing_fault = AXIS2_FALSE; + soap_builder->processing_mandatory_fault_elements = AXIS2_FALSE; + soap_builder->receiver_fault_code = NULL; + soap_builder->sender_fault_code = NULL; + soap_builder->soap_version = AXIOM_SOAP12; + soap_builder->last_node_status = -1; + soap_builder->envelope_ns = NULL; + soap_builder->soap_envelope = NULL; + soap_builder->mime_body_parts = NULL; + soap_builder->om_builder = stax_builder; + soap_builder->mime_parser = NULL; + soap_builder->callback = NULL; + soap_builder->callback_ctx = NULL; + + status = axiom_soap_builder_identify_soap_version(soap_builder, env, soap_version); + if(status == AXIS2_FAILURE) + { + axiom_soap_builder_free(soap_builder, env); + return NULL; + } + status = axiom_soap_builder_parse_headers(soap_builder, env); + if(status == AXIS2_FAILURE) + { + axiom_soap_builder_free(soap_builder, env); + return NULL; + } + return soap_builder; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_builder_free( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + if(!soap_builder) + { + return; + } + if(soap_builder->builder_helper) + { + if(soap_builder->soap_version == AXIOM_SOAP11 && soap_builder->builder_helper) + { + axiom_soap11_builder_helper_free( + (axiom_soap11_builder_helper_t *)(soap_builder->builder_helper), env); + soap_builder->builder_helper = NULL; + } + else if(soap_builder->soap_version == AXIOM_SOAP12 && soap_builder->builder_helper) + { + axiom_soap12_builder_helper_free( + (axiom_soap12_builder_helper_t *)(soap_builder->builder_helper), env); + soap_builder->builder_helper = NULL; + } + } + + if(soap_builder->om_builder) + { + axiom_stax_builder_free(soap_builder->om_builder, env); + soap_builder->om_builder = NULL; + } + + if(soap_builder->mime_body_parts) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + const void *key = NULL; + for(hi = axutil_hash_first(soap_builder->mime_body_parts, env); hi; hi = axutil_hash_next( + env, hi)) + { + axutil_hash_this(hi, &key, NULL, &val); + + if(key) + { + AXIS2_FREE(env->allocator, (char *)key); + } + + val = NULL; + key = NULL; + } + + axutil_hash_free(soap_builder->mime_body_parts, env); + soap_builder->mime_body_parts = NULL; + } + + if(soap_builder->mime_parser) + { + axiom_mime_parser_free(soap_builder->mime_parser, env); + soap_builder->mime_parser = NULL; + } + + if(soap_builder->callback_ctx) + { + axis2_callback_info_t *callback_info = NULL; + + callback_info = (axis2_callback_info_t *)(soap_builder->callback_ctx); + if(callback_info) + { + if(callback_info->chunked_stream) + { + axutil_http_chunked_stream_free(callback_info->chunked_stream, env); + callback_info->chunked_stream = NULL; + } + + AXIS2_FREE(env->allocator, callback_info); + callback_info = NULL; + soap_builder->callback_ctx = NULL; + } + } + + if(soap_builder) + { + AXIS2_FREE(env->allocator, soap_builder); + soap_builder = NULL; + } + + return; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axiom_soap_builder_get_soap_envelope( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(!soap_builder) + { + return NULL; + } + if(!(soap_builder->om_builder)) + { + return NULL; + } + while(!(soap_builder->soap_envelope) && !axiom_stax_builder_is_complete( + soap_builder->om_builder, env)) + { + status = axiom_soap_builder_next(soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + + return soap_builder->soap_envelope; +} + +AXIS2_EXTERN axiom_document_t *AXIS2_CALL axiom_soap_builder_get_document( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + if (!soap_builder) + { + return NULL; + } + if (soap_builder->om_builder) + { + return axiom_stax_builder_get_document(soap_builder->om_builder, env); + } + else + return NULL; +} + +/** + * Builds next element of the OM structure + * @param builder pointer to the SOAP Builder struct + * @param env Environment. MUST NOT be NULL + * @return AXIS2_SUCCESS if the next element is present else AXIS2_FAILURE + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_builder_next( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + int current_event = AXIS2_MAX_EVENT; + int status = AXIS2_SUCCESS; + + if((!soap_builder) || (soap_builder->done) || (!soap_builder->om_builder)) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid soap builder"); + return AXIS2_FAILURE; + } + + /* Get the status of previous node before building next node. We need the previous state of the + * node to identify very first element, which is SOAP Envelope. If last_node_status is + * AXIS2_BUILDER_LAST_NODE_NULL, then it means next node is SOAP Envelope + */ + if(axiom_stax_builder_get_lastnode(soap_builder->om_builder, env)) + { + soap_builder->last_node_status = AXIS2_BUILDER_LAST_NODE_NOT_NULL; + } + else + { + soap_builder->last_node_status = AXIS2_BUILDER_LAST_NODE_NULL; + } + + current_event = axiom_stax_builder_next_with_token(soap_builder->om_builder, env); + if(current_event == AXIOM_XML_READER_START_ELEMENT + || current_event == AXIOM_XML_READER_EMPTY_ELEMENT) + { + axiom_node_t *current_node = axiom_stax_builder_get_lastnode(soap_builder->om_builder, env); + if(current_node) + { + status = axiom_soap_builder_construct_node(soap_builder, env, current_node); + } + else + { + /* there is an error. So, don't continue building it */ + soap_builder->done = AXIS2_TRUE; + status = AXIS2_FAILURE; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occurred when building node"); + } + } + else if(current_event == -1) + { + /* there is an error. So, don't continue building it */ + soap_builder->done = AXIS2_TRUE; + status = AXIS2_FAILURE; + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error occurred when building node"); + } + + /* for any other event types, return AXIS2_SUCCESS as the return value. */ + + return status; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_builder_get_document_element( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + axiom_node_t *document_node = NULL; + if(soap_builder->soap_envelope) + { + document_node = axiom_soap_envelope_get_base_node(soap_builder->soap_envelope, env); + } + + return document_node; +} + +static axis2_status_t +axiom_soap_builder_construct_node( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axiom_node_t * om_element_node) +{ + axiom_element_t *om_element = NULL; + const axis2_char_t *ele_localname = NULL; + int element_level = 0; + int status = AXIS2_SUCCESS; + axiom_node_t *parent = NULL; + + /* get OM element struct from node */ + om_element = (axiom_element_t *)axiom_node_get_data_element(om_element_node, env); + if(!om_element) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot construct node. Invalid element"); + return AXIS2_FAILURE; + } + + /* get element local name */ + ele_localname = axiom_element_get_localname(om_element, env); + if(!ele_localname) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot construct node. Invalid element name"); + return AXIS2_FAILURE; + } + + parent = axiom_node_get_parent(om_element_node, env); + if(!parent) + { + /* parent node doesn't exist means, this should be SOAP Envelope */ + if(soap_builder->last_node_status != AXIS2_BUILDER_LAST_NODE_NULL) + { + /* this means, there are two elements in the first level */ + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_MESSAGE_FIRST_ELEMENT_MUST_CONTAIN_LOCAL_NAME, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Soap message can contain only one SOAP Envelope as the top level element"); + return AXIS2_FAILURE; + } + + if(axutil_strcasecmp(ele_localname, AXIOM_SOAP_ENVELOPE_LOCAL_NAME) != 0) + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_MESSAGE_FIRST_ELEMENT_MUST_CONTAIN_LOCAL_NAME, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SOAP message first element must be Envelope"); + return AXIS2_FAILURE; + } + + /** create a null soap envelope struct */ + soap_builder->soap_envelope = axiom_soap_envelope_create_null(env); + if(!soap_builder->soap_envelope) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create SOAP Envelope"); + return AXIS2_FAILURE; + } + + /** wrap this OM node in it */ + axiom_soap_envelope_set_base_node(soap_builder->soap_envelope, env, om_element_node); + axiom_soap_envelope_set_builder(soap_builder->soap_envelope, env, soap_builder); + status = axiom_soap_builder_process_namespace_data(soap_builder, env, om_element_node); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SOAP Envelope is having invalid namespace"); + } + + return status; + } + + /** a parent node exist , so not soap envelope. Can be either header/body/children of them */ + + /* get element level of this OM element. Envelope will be in element_level 1. Body and Header + * will be in element level 2. SOAP fault will be child of Body, so it will be in level 3*/ + element_level = axiom_stax_builder_get_element_level(soap_builder->om_builder, env); + if(axiom_stax_builder_get_current_event(soap_builder->om_builder, env) + == AXIOM_XML_READER_EMPTY_ELEMENT) + { + /* if it is an empty element, increase the element level. This is because the element level + * is incremented by STAX builder only if <element> tag is identified. It will not be + * incremented if <element/> tag is seen. But for our logic, even empty element should be + * considered as full element. so, <element/> = <element> </element>. */ + ++element_level; + } + + if(element_level == 2) + { + /* At this level, we can only have soap:Header or soap:Body */ + status = axiom_soap_builder_process_namespace_data(soap_builder, env, om_element_node); + if(status != AXIS2_SUCCESS) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invalid SOAP namespace"); + return AXIS2_FAILURE; + } + + if(axutil_strcmp(ele_localname, AXIOM_SOAP_HEADER_LOCAL_NAME) == 0) + { + /* this is the soap header element */ + status = axiom_soap_builder_construct_soap_header(soap_builder, env, om_element_node); + } + else if(axutil_strcmp(ele_localname, AXIOM_SOAP_BODY_LOCAL_NAME) == 0) + { + /* This is the SOAP Body element */ + status = axiom_soap_builder_construct_soap_body(soap_builder, env, om_element_node); + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_BUILDER_ENVELOPE_CAN_HAVE_ONLY_HEADER_AND_BODY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "SOAP builder found a child element other than header or body in envelope element"); + return AXIS2_FAILURE; + } + } + else if(element_level == 3) + { + axiom_element_t *parent_ele = NULL; + axis2_char_t *parent_localname = NULL; + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent, env); + if(parent_ele) + { + parent_localname = axiom_element_get_localname(parent_ele, env); + } + + if(!parent_localname) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot identify parent element local name"); + return AXIS2_FAILURE; + } + + if(axutil_strcasecmp(parent_localname, AXIOM_SOAP_HEADER_LOCAL_NAME) == 0) + { + axiom_soap_header_block_t *header_block = NULL; + axiom_soap_header_t *soap_header = NULL; + + soap_header = axiom_soap_envelope_get_header(soap_builder->soap_envelope, env); + if(!soap_header) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get SOAP Header from OM Envelope"); + return AXIS2_FAILURE; + } + + header_block = axiom_soap_header_block_create(env); + if(!header_block) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create SOAP Header block"); + return AXIS2_FAILURE; + } + + axiom_soap_header_block_set_base_node(header_block, env, om_element_node); + axiom_soap_header_set_header_block(soap_header, env, header_block); + axiom_soap_header_block_set_soap_version(header_block, env, soap_builder->soap_version); + } + else if(axutil_strcasecmp(parent_localname, AXIOM_SOAP_BODY_LOCAL_NAME) == 0) + { + /* if the node is <xop:Include> or MTOM message */ + if(axutil_strcmp(ele_localname, AXIS2_XOP_INCLUDE) == 0) + { + return axiom_soap_builder_construct_xop_include(soap_builder, env, om_element_node); + } + + if(axutil_strcasecmp(ele_localname, AXIOM_SOAP_BODY_FAULT_LOCAL_NAME) == 0) + { + return axiom_soap_builder_construct_soap_fault(soap_builder, env, om_element_node); + } + + /* We don't need to process any other children of SOAP Body. */ + } + else + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_BUILDER_ENVELOPE_CAN_HAVE_ONLY_HEADER_AND_BODY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "SOAP builder found a child element other than header or body in envelope element"); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; + } + else if(element_level > 3) + { + if(soap_builder->processing_fault) + { + if(soap_builder->soap_version == AXIOM_SOAP11) + { + status = axiom_soap11_builder_helper_handle_event((axiom_soap11_builder_helper_t *) + soap_builder->builder_helper, env, om_element_node, element_level); + } + else if(soap_builder->soap_version == AXIOM_SOAP12) + { + status = axiom_soap12_builder_helper_handle_event((axiom_soap12_builder_helper_t *) + soap_builder->builder_helper, env, om_element_node, element_level); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unknown SOAP Version"); + status = AXIS2_FAILURE; + } + } + + /* if the node is <xop:Include> or MTOM message */ + else if(axutil_strcmp(ele_localname, AXIS2_XOP_INCLUDE) == 0) + { + return axiom_soap_builder_construct_xop_include(soap_builder, env, om_element_node); + } + + /* we don't need to consider any other elements at this level. */ + } + return status; +} + +static axis2_status_t +axiom_soap_builder_construct_soap_header( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_node) +{ + axiom_soap_header_t *soap_header = NULL; + if(soap_builder->header_present) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_BUILDER_MULTIPLE_HEADERS_ENCOUNTERED, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SOAP builder encountered multiple headers"); + return AXIS2_FAILURE; + } + if(soap_builder->body_present) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_BUILDER_HEADER_BODY_WRONG_ORDER, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "SOAP builder encountered body element first and header next"); + return AXIS2_FAILURE; + } + + soap_builder->header_present = AXIS2_TRUE; + soap_header = axiom_soap_header_create(env); + if(!soap_header) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create SOAP Header"); + return AXIS2_FAILURE; + } + + axiom_soap_header_set_base_node(soap_header, env, om_node); + axiom_soap_envelope_set_header(soap_builder->soap_envelope, env, soap_header); + axiom_soap_header_set_builder(soap_header, env, soap_builder); + axiom_soap_header_set_soap_version(soap_header, env, soap_builder->soap_version); + + return AXIS2_SUCCESS; +} + +static axis2_status_t +axiom_soap_builder_construct_soap_body( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_node) +{ + axiom_soap_body_t *soap_body = NULL; + if(soap_builder->body_present) + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_SOAP_BUILDER_MULTIPLE_BODY_ELEMENTS_ENCOUNTERED, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "SOAP builder multiple body elements encountered"); + return AXIS2_FAILURE; + } + + soap_builder->body_present = AXIS2_TRUE; + soap_body = axiom_soap_body_create(env); + if(!soap_body) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create SOAP Body"); + return AXIS2_FAILURE; + } + + axiom_soap_body_set_base_node(soap_body, env, om_node); + axiom_soap_body_set_builder(soap_body, env, soap_builder); + axiom_soap_envelope_set_body(soap_builder->soap_envelope, env, soap_body); + + return AXIS2_SUCCESS; +} + +static axis2_status_t +axiom_soap_builder_construct_soap_fault( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_node) +{ + axiom_soap_body_t *soap_body = NULL; + axiom_soap_fault_t *soap_fault = NULL; + axiom_namespace_t *env_ns = NULL; + + env_ns = axiom_soap_envelope_get_namespace(soap_builder->soap_envelope, env); + if(!env_ns) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get soap envelope namespace"); + return AXIS2_FAILURE; + } + + soap_body = axiom_soap_envelope_get_body(soap_builder->soap_envelope, env); + if(!soap_body) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get soap body from OM Envelope"); + return AXIS2_FAILURE; + } + + soap_fault = axiom_soap_fault_create(env); + if(!soap_fault) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create SOAP Fault structure"); + return AXIS2_FAILURE; + } + + axiom_soap_fault_set_base_node(soap_fault, env, om_node); + axiom_soap_body_set_fault(soap_body, env, soap_fault); + axiom_soap_fault_set_builder(soap_fault, env, soap_builder); + soap_builder->processing_fault = AXIS2_TRUE; + soap_builder->processing_mandatory_fault_elements = AXIS2_TRUE; + + if(axutil_strcmp(AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, + axiom_namespace_get_uri(env_ns, env)) == 0) + { + soap_builder->builder_helper = axiom_soap12_builder_helper_create(env, soap_builder); + } + else if(axutil_strcmp(AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI, + axiom_namespace_get_uri(env_ns, env)) == 0) + { + soap_builder->builder_helper = axiom_soap11_builder_helper_create( + env, soap_builder,soap_builder->om_builder); + } + + if(!soap_builder->builder_helper) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create soap builder helper"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +static axis2_status_t +axiom_soap_builder_construct_xop_include( + axiom_soap_builder_t *soap_builder, + const axutil_env_t *env, + axiom_node_t *om_element_node) +{ + axiom_namespace_t *ns = NULL; + axis2_char_t *uri = NULL; + axiom_element_t *om_element = NULL; + axutil_qname_t *qname = NULL; + axis2_char_t *id = NULL; + + om_element = (axiom_element_t *)axiom_node_get_data_element(om_element_node, env); + ns = axiom_element_get_namespace(om_element, env, om_element_node); + if(!ns) + { + /* this is not a xop:include element. so, we can safely return success */ + return AXIS2_SUCCESS; + } + + uri = axiom_namespace_get_uri(ns, env); + if((!uri) || (axutil_strcmp(uri, AXIS2_XOP_NAMESPACE_URI) != 0)) + { + /* this is not a xop:include element. so, we can safely return success */ + return AXIS2_SUCCESS; + } + + qname = axutil_qname_create(env, "href", NULL, NULL); + if(!qname) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create qname with value href"); + return AXIS2_FAILURE; + } + + id = axiom_element_get_attribute_value(om_element, env, qname); + axutil_qname_free(qname, env); + if(!id) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get href ID of the xop:include element"); + return AXIS2_FAILURE; + } + + if(!axutil_strstr(id, "cid:")) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "ID of xop:include doesn't include 'cid:' part"); + return AXIS2_FAILURE; + } + + /* everything looks fine, so recursively build the OM tree, so that we can get data handlers */ + while(!axiom_node_is_complete(om_element_node, env)) + { + axiom_stax_builder_next_with_token(soap_builder->om_builder, env); + } + + if(soap_builder->mime_body_parts) + { + axiom_data_handler_t *data_handler = NULL; + axis2_char_t *id_decoded = NULL; + axiom_text_t *data_text = NULL; + axiom_node_t *data_om_node = NULL; + axiom_node_t *parent = NULL; + + /* Get the value of href id, after "cid:" */ + id += 4; + id_decoded = axutil_strdup(env, id); + axutil_url_decode(env, id_decoded, id_decoded); + + /* Find the data handler of given xop:include */ + data_handler = (axiom_data_handler_t *)axutil_hash_get( + soap_builder-> mime_body_parts, (void *)id_decoded, AXIS2_HASH_KEY_STRING); + if(!data_handler) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Cannot find data handler corresponding to id %s", id_decoded); + AXIS2_FREE(env->allocator, id_decoded); + return AXIS2_FAILURE; + } + + /* remove the <xop:Include> element, and add the data handler as the child of + * xop:include's parent */ + parent = axiom_node_get_parent(om_element_node, env); + axiom_node_free_tree(om_element_node, env); + data_text = axiom_text_create_with_data_handler(env, parent, data_handler, &data_om_node); + axiom_text_set_content_id(data_text, env, id_decoded); + axiom_stax_builder_set_lastnode(soap_builder->om_builder,env, parent); + AXIS2_FREE(env->allocator, id_decoded); + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find mime_body_part in soap builder"); + return AXIS2_FAILURE; + } + + return AXIS2_SUCCESS; +} + +/* check whether the namespace of given node is either SOAP11 or SOAP12 namespace */ +static axis2_status_t +axiom_soap_builder_process_namespace_data( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axiom_node_t * om_node) +{ + axiom_element_t *om_ele = NULL; + axiom_namespace_t *om_ns = NULL; + + om_ele = (axiom_element_t *)axiom_node_get_data_element(om_node, env); + om_ns = axiom_element_get_namespace(om_ele, env, om_node); + if(om_ns) + { + axis2_char_t *ns_uri = NULL; + ns_uri = axiom_namespace_get_uri(om_ns, env); + if(ns_uri) + { + if((axutil_strcmp(ns_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI) == 0) + || (axutil_strcmp(ns_uri, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI) == 0)) + { + return AXIS2_SUCCESS; + } + } + } + + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOAP_NAMESPACE_URI, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid SOAP Namespace URI"); + return AXIS2_FAILURE; +} + +static axis2_status_t +axiom_soap_builder_identify_soap_version( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + const axis2_char_t * soap_version_uri_from_transport) +{ + axiom_namespace_t *om_ns = NULL; + axiom_node_t *envelope_node = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *ns_uri = NULL; + + AXIS2_PARAM_CHECK(env->error, soap_version_uri_from_transport, AXIS2_FAILURE); + if(!soap_builder) + { + return AXIS2_FAILURE; + } + soap_builder->soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + + if(soap_builder->soap_envelope == NULL) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOAP_MESSAGE_DOES_NOT_CONTAIN_AN_ENVELOPE, + AXIS2_FAILURE); + AXIS2_LOG_CRITICAL(env->log, AXIS2_LOG_SI, + "SOAP message does not have a SOAP envelope element "); + return AXIS2_FAILURE; + } + + envelope_node = axiom_soap_envelope_get_base_node(soap_builder->soap_envelope, env); + + if(!envelope_node) + { + return AXIS2_FAILURE; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(envelope_node, env); + if(!om_ele) + { + return AXIS2_FAILURE; + } + om_ns = axiom_element_get_namespace(om_ele, env, envelope_node); + if(!om_ns) + { + return AXIS2_FAILURE; + } + ns_uri = axiom_namespace_get_uri(om_ns, env); + + if(ns_uri) + { + if(soap_version_uri_from_transport + && axutil_strcmp(soap_version_uri_from_transport, ns_uri) != 0) + { + AXIS2_ERROR_SET(env->error, + AXIS2_ERROR_TRANSPORT_LEVEL_INFORMATION_DOES_NOT_MATCH_WITH_SOAP, AXIS2_FAILURE); + + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "AXIS2_ERROR_TRANSPORT_LEVEL_INFORMATION_DOES_NOT_MATCH_WITH_SOAP"); + return AXIS2_FAILURE; + } + if(axutil_strcmp(AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI, ns_uri) == 0) + { + soap_builder->soap_version = AXIOM_SOAP11; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Identified soap version is soap11"); + + axiom_soap_envelope_set_soap_version_internal(soap_builder-> soap_envelope, env, + soap_builder-> soap_version); + + return AXIS2_SUCCESS; + } + else if(axutil_strcmp(AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, ns_uri) == 0) + { + soap_builder->soap_version = AXIOM_SOAP12; + + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "identified soap version is soap12"); + + axiom_soap_envelope_set_soap_version_internal(soap_builder-> soap_envelope, env, + soap_builder-> soap_version); + + return AXIS2_SUCCESS; + } + } + return AXIS2_FAILURE; +} + +static axis2_status_t +axiom_soap_builder_parse_headers( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + axiom_node_t *om_node = NULL; + axiom_soap_header_t *soap_header = NULL; + int status = AXIS2_SUCCESS; + if(!soap_builder) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Soap Builder is NULL"); + return AXIS2_FAILURE; + } + if(!soap_builder->soap_envelope) + { + return AXIS2_FAILURE; + } + soap_header = axiom_soap_envelope_get_header(soap_builder->soap_envelope, env); + + if(soap_header) + { + om_node = axiom_soap_header_get_base_node(soap_header, env); + if(om_node) + { + while(!axiom_node_is_complete(om_node, env)) + { + status = axiom_soap_builder_next(soap_builder, env); + if(status == AXIS2_FAILURE) + return AXIS2_FAILURE; + } + /*HACK: to fix AXIS2C-129 - Samisa */ + /* + axiom_stax_builder_set_element_level( + soap_builder->om_builder, env, 1); + */ + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_builder_set_bool_processing_mandatory_fault_elements( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axis2_bool_t value) +{ + soap_builder->processing_mandatory_fault_elements = value; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_builder_set_processing_detail_elements( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axis2_bool_t value) +{ + soap_builder->processing_detail_elements = value; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_soap_builder_is_processing_detail_elements( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + return soap_builder->processing_detail_elements; +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_soap_builder_get_soap_version( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + return soap_builder->soap_version; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_builder_set_mime_body_parts( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env, + axutil_hash_t * map) +{ + soap_builder->mime_body_parts = map; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_soap_builder_get_mime_body_parts( + axiom_soap_builder_t * builder, + const axutil_env_t * env) +{ + return builder->mime_body_parts; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_builder_set_mime_parser( + axiom_soap_builder_t * builder, + const axutil_env_t * env, + axiom_mime_parser_t *mime_parser) +{ + builder->mime_parser = mime_parser; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_builder_set_callback_function( + axiom_soap_builder_t * builder, + const axutil_env_t * env, + AXIS2_READ_INPUT_CALLBACK callback) +{ + builder->callback = callback; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_builder_set_callback_ctx( + axiom_soap_builder_t * builder, + const axutil_env_t * env, + void *callback_ctx) +{ + builder->callback_ctx = callback_ctx; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_builder_create_attachments( + axiom_soap_builder_t * builder, + const axutil_env_t * env, + void *user_param, + axis2_char_t *callback_name) +{ + axutil_hash_t *attachments_map = NULL; + axis2_char_t *mime_boundary = NULL; + + if(builder->mime_parser) + { + if(builder->callback_ctx) + { + mime_boundary = axiom_mime_parser_get_mime_boundary(builder->mime_parser, env); + + if(mime_boundary) + { + if(callback_name) + { + axiom_mime_parser_set_caching_callback_name(builder->mime_parser, env, + callback_name); + } + attachments_map = axiom_mime_parser_parse_for_attachments(builder->mime_parser, + env, builder->callback, builder->callback_ctx, mime_boundary, user_param); + + if(attachments_map) + { + builder->mime_body_parts = attachments_map; + return AXIS2_SUCCESS; + } + else + { + return AXIS2_FAILURE; + } + } + else + { + return AXIS2_FAILURE; + } + } + else + { + return AXIS2_FAILURE; + } + } + else + { + return AXIS2_FAILURE; + } +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_soap_builder_replace_xop( + axiom_soap_builder_t * builder, + const axutil_env_t * env, + axiom_node_t *om_element_node, + axiom_element_t *om_element) +{ + axiom_namespace_t *ns = NULL; + axis2_bool_t is_replaced = AXIS2_FALSE; + + ns = axiom_element_get_namespace(om_element, env, om_element_node); + if(ns) + { + axis2_char_t *uri = axiom_namespace_get_uri(ns, env); + if(uri) + { + if(axutil_strcmp(uri, AXIS2_XOP_NAMESPACE_URI) == 0) + { + axutil_qname_t *qname = NULL; + qname = axutil_qname_create(env, "href", NULL, NULL); + if(qname) + { + axis2_char_t *id = NULL; + id = axiom_element_get_attribute_value(om_element, env, qname); + if(id) + { + axis2_char_t *pos = NULL; + pos = axutil_strstr(id, "cid:"); + if(pos) + { + axiom_data_handler_t *data_handler = NULL; + id += 4; + + if(builder->mime_body_parts) + { + + axis2_char_t *id_decoded = NULL; + + id_decoded = axutil_strdup(env, id); + + axutil_url_decode(env, id_decoded, id_decoded); + + data_handler = (axiom_data_handler_t *)axutil_hash_get( + builder-> mime_body_parts, (void *)id_decoded, + AXIS2_HASH_KEY_STRING); + if(data_handler) + { + axiom_text_t *data_text = NULL; + axiom_node_t *data_om_node = NULL; + axiom_node_t *parent = NULL; + + parent = axiom_node_get_parent(om_element_node, env); + + /*remove the <xop:Include> element */ + axiom_node_free_tree(om_element_node, env); + + data_text = axiom_text_create_with_data_handler(env, parent, + data_handler, &data_om_node); + + axiom_text_set_content_id(data_text, env, id_decoded); + /*axiom_stax_builder_set_lastnode + (soap_builder->om_builder, env, + parent);*/ + is_replaced = AXIS2_TRUE; + } + if(id_decoded) + { + AXIS2_FREE(env->allocator, id_decoded); + } + } + } + } + } + axutil_qname_free(qname, env); + } + } + } + + return is_replaced; +} + +AXIS2_EXTERN axiom_stax_builder_t *AXIS2_CALL +axiom_soap_builder_get_om_builder( + axiom_soap_builder_t * soap_builder, + const axutil_env_t * env) +{ + if(!soap_builder) + { + return NULL; + } + return soap_builder->om_builder; +} + diff --git a/axiom/src/soap/soap_envelope.c b/axiom/src/soap/soap_envelope.c new file mode 100644 index 0000000..48e10f7 --- /dev/null +++ b/axiom/src/soap/soap_envelope.c @@ -0,0 +1,631 @@ +/* + * 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_soap_envelope.h" +#include <axiom_soap_body.h> +#include <axiom_soap_header.h> +#include <axiom_soap_header_block.h> +#include <axutil_hash.h> +#include <axiom_soap_const.h> +#include <axiom_soap_builder.h> +#include <axiom_soap_fault_code.h> +#include <axiom_soap_fault_reason.h> +#include <axiom_soap_fault_detail.h> +#include <axiom_soap_fault_role.h> +#include <axiom_soap_fault_value.h> +#include <axiom_soap_fault_text.h> +#include <axiom_namespace_internal.h> + +struct axiom_soap_envelope +{ + /* corresponding om element node */ + axiom_node_t *om_ele_node; + /* soap version */ + int soap_version; + /* soap header */ + axiom_soap_header_t *header; + /* soap body */ + axiom_soap_body_t *body; + /* pointer to soap builder */ + axiom_soap_builder_t *soap_builder; + int ref; +}; +static axis2_status_t +check_and_set_soap_version( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_namespace_t * ns); + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axiom_soap_envelope_create_null( + const axutil_env_t * env) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + + soap_envelope = (axiom_soap_envelope_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_envelope_t)); + if(!soap_envelope) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create a SOAP Envelope"); + return NULL; + } + soap_envelope->om_ele_node = NULL; + soap_envelope->soap_version = AXIOM_SOAP12; + soap_envelope->header = NULL; + soap_envelope->body = NULL; + soap_envelope->ref = 1; + soap_envelope->soap_builder = NULL; + + return soap_envelope; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axiom_soap_envelope_create( + const axutil_env_t * env, + axiom_namespace_t * ns) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_element_t *ele = NULL; + int status = AXIS2_SUCCESS; + + AXIS2_PARAM_CHECK(env->error, ns, NULL); + + soap_envelope = axiom_soap_envelope_create_null(env); + if(!soap_envelope) + { + return NULL; + } + status = check_and_set_soap_version(soap_envelope, env, ns); + if(status == AXIS2_FAILURE) + { + AXIS2_FREE(env->allocator, soap_envelope); + return NULL; + } + + ele = axiom_element_create(env, NULL, AXIOM_SOAP_ENVELOPE_LOCAL_NAME, ns, + &(soap_envelope->om_ele_node)); + if(!ele) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create a SOAP element"); + axiom_soap_envelope_free(soap_envelope, env); + return NULL; + } + return soap_envelope; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axiom_soap_envelope_create_with_soap_version_prefix( + const axutil_env_t * env, + int soap_version, + const axis2_char_t * prefix) +{ + axiom_namespace_t *ns = NULL; + const axis2_char_t *ns_prefix = NULL; + const axis2_char_t *ns_uri = NULL; + + if(soap_version == AXIOM_SOAP11) + { + ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + else if(soap_version == AXIOM_SOAP12) + { + ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + else + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOAP_VERSION, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invalid SOAP version"); + return NULL; + } + if(!prefix || axutil_strcmp(prefix, "") == 0) + { + ns_prefix = AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX; + } + else + { + ns_prefix = prefix; + } + + ns = axiom_namespace_create(env, ns_uri, ns_prefix); + if(!ns) + return NULL; + return axiom_soap_envelope_create(env, ns); +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_envelope_free( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + if(--(soap_envelope->ref) > 0) + { + return; + } + if(soap_envelope->header) + { + axiom_soap_header_free(soap_envelope->header, env); + } + if(soap_envelope->body) + { + axiom_soap_body_free(soap_envelope->body, env); + } + if(soap_envelope->om_ele_node) + { + if(soap_envelope->soap_builder) + { + axiom_soap_builder_free(soap_envelope->soap_builder, env); + soap_envelope->om_ele_node = NULL; + } + else + { + axiom_node_free_tree(soap_envelope->om_ele_node, env); + } + } + + AXIS2_FREE(env->allocator, soap_envelope); + return; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_envelope_get_base_node( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + return soap_envelope->om_ele_node; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_set_base_node( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + soap_envelope->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_soap_envelope_get_soap_version( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + return soap_envelope->soap_version; +} + +/** this is an internal function */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_set_soap_version_internal( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + int soap_version) +{ + soap_envelope->soap_version = soap_version; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_soap_header_t *AXIS2_CALL +axiom_soap_envelope_get_header( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(soap_envelope->header) + { + return soap_envelope->header; + } + else if(soap_envelope->soap_builder) + { + while(!(soap_envelope->header) && !(soap_envelope->body) && !axiom_node_is_complete( + soap_envelope->om_ele_node, env)) + { + status = axiom_soap_builder_next(soap_envelope->soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + + return soap_envelope->header; +} + +AXIS2_EXTERN axiom_soap_header_block_t *AXIS2_CALL +axiom_soap_envelope_add_header( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axis2_char_t * namespace_uri, + axis2_char_t * name) +{ + axiom_namespace_t *ns = NULL; + + if(!soap_envelope->header) + { + return NULL; + } + if(namespace_uri) + { + ns = axiom_namespace_create(env, namespace_uri, NULL); + } + + return axiom_soap_header_block_create_with_parent(env, name, ns, soap_envelope->header); +} + +AXIS2_EXTERN axiom_soap_body_t *AXIS2_CALL +axiom_soap_envelope_get_body( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(soap_envelope->body) + { + return soap_envelope->body; + } + else if(soap_envelope->soap_builder) + { + while(!(soap_envelope->body) && !axiom_node_is_complete(soap_envelope->om_ele_node, env)) + { + status = axiom_soap_builder_next(soap_envelope->soap_builder, env); + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + } + return soap_envelope->body; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_serialize( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_output_t * om_output, + axis2_bool_t cache) +{ + AXIS2_PARAM_CHECK(env->error, soap_envelope, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + + /* + if soap version is soap11 we modify the soap fault part. + This is done because the builder construct a soap12 fault all + the time. So when serializing if the soap version is soap11 + we should convert it back to soap11 fault + */ + if(soap_envelope->soap_version == AXIOM_SOAP11) + { + axiom_soap_body_t *soap_body = NULL; + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + axiom_soap_body_convert_fault_to_soap11(soap_body, env); + } + /* write the xml version and encoding + These should be set to om output before calling the serialize function + Otherwise default values will be written + */ + axiom_output_get_content_type(om_output, env); + return axiom_node_serialize(soap_envelope->om_ele_node, env, om_output); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_set_body( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_soap_body_t * body) +{ + + if(!(soap_envelope->body)) + { + soap_envelope->body = body; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "trying to set a soap bedy to soap_envelope when a soap body alrady exists"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_set_header( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_soap_header_t * header) +{ + + if(!(soap_envelope->header)) + { + soap_envelope->header = header; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + " trying to set a soap header to soap_envelope when a soap header alrady exists"); + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL +axiom_soap_envelope_get_namespace( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + + if(soap_envelope->om_ele_node) + { + axiom_element_t *ele = NULL; + if(axiom_node_get_node_type(soap_envelope->om_ele_node, env) == AXIOM_ELEMENT) + { + ele = (axiom_element_t *)axiom_node_get_data_element(soap_envelope-> om_ele_node, env); + if(ele) + { + return axiom_element_get_namespace(ele, env, soap_envelope->om_ele_node); + } + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_set_builder( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_soap_builder_t * soap_builder) +{ + AXIS2_PARAM_CHECK(env->error, soap_builder, AXIS2_FAILURE); + soap_envelope->soap_builder = soap_builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_soap_builder_t *AXIS2_CALL +axiom_soap_envelope_get_builder( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env) +{ + if(!soap_envelope) + { + return NULL; + } + return soap_envelope->soap_builder; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axiom_soap_envelope_create_default_soap_envelope( + const axutil_env_t * env, + int soap_version) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_header_t *soap_header = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_namespace_t *om_ns = NULL; + + if(soap_version == AXIOM_SOAP11) + { + om_ns = axiom_namespace_create(env, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI, + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX); + if(!om_ns) + { + return NULL; + } + soap_envelope = axiom_soap_envelope_create(env, om_ns); + + soap_header = axiom_soap_header_create_with_parent(env, soap_envelope); + soap_body = axiom_soap_body_create_with_parent(env, soap_envelope); + soap_envelope->body = soap_body; + soap_envelope->header = soap_header; + return soap_envelope; + } + else if(soap_version == AXIOM_SOAP12) + { + om_ns = axiom_namespace_create(env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX); + if(!om_ns) + { + return NULL; + } + soap_envelope = axiom_soap_envelope_create(env, om_ns); + + soap_header = axiom_soap_header_create_with_parent(env, soap_envelope); + soap_body = axiom_soap_body_create_with_parent(env, soap_envelope); + soap_envelope->body = soap_body; + soap_envelope->header = soap_header; + return soap_envelope; + } + + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_SOAP_VERSION, AXIS2_FAILURE); + return NULL; +} + +AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL +axiom_soap_envelope_create_default_soap_fault_envelope( + const axutil_env_t * env, + const axis2_char_t * code_value, + const axis2_char_t * reason_text, + const int soap_version, + axutil_array_list_t * sub_codes, + axiom_node_t * detail_node) +{ + axiom_soap_envelope_t *soap_envelope = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_soap_fault_t *fault = NULL; + + if(AXIOM_SOAP11 != soap_version && AXIOM_SOAP12 != soap_version) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_SOAP_VERSION, AXIS2_FAILURE); + return NULL; + } + + soap_envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version); + if(!soap_envelope) + { + return NULL; + } + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + if(!soap_body) + { + axiom_soap_envelope_free(soap_envelope, env); + return NULL; + } + fault = axiom_soap_fault_create_default_fault(env, soap_body, code_value, reason_text, + soap_version); + if(!fault) + { + axiom_soap_envelope_free(soap_envelope, env); + return NULL; + } + + if(sub_codes) + { + int i = 0; + axiom_soap_fault_code_t *fault_code = NULL; + fault_code = axiom_soap_fault_get_code(fault, env); + if(fault_code) + { + for(i = 0; i < axutil_array_list_size(sub_codes, env); i++) + { + axis2_char_t *sub_code = (axis2_char_t *)axutil_array_list_get(sub_codes, env, i); + if(sub_code) + { + axiom_soap_fault_sub_code_create_with_parent_value(env, fault_code, sub_code); + } + } + } + } + + if(detail_node) + { + axiom_soap_fault_detail_t *detail = axiom_soap_fault_detail_create_with_parent(env, fault); + if(detail) + { + axiom_soap_fault_detail_add_detail_entry(detail, env, detail_node); + } + } + + return soap_envelope; + +} + +static axis2_status_t +check_and_set_soap_version( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + axiom_namespace_t * ns) +{ + axis2_char_t *uri = NULL; + if(!soap_envelope) + { + return AXIS2_FAILURE; + } + if(!ns) + { + return AXIS2_FAILURE; + } + uri = axiom_namespace_get_uri(ns, env); + if(!uri) + { + return AXIS2_FAILURE; + } + if(axutil_strcmp(uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI) == 0) + { + soap_envelope->soap_version = AXIOM_SOAP11; + return AXIS2_SUCCESS; + } + else if(axutil_strcmp(uri, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI) == 0) + { + soap_envelope->soap_version = AXIOM_SOAP12; + return AXIS2_SUCCESS; + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_SOAP_NAMESPACE_URI, AXIS2_FAILURE); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_set_soap_version( + axiom_soap_envelope_t * soap_envelope, + const axutil_env_t * env, + int soap_version) +{ + axiom_element_t *env_ele = NULL; + axiom_namespace_t *env_ns = NULL; + const axis2_char_t *ns_uri = NULL; + int status = AXIS2_SUCCESS; + + if(soap_version == AXIOM_SOAP11) + { + ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + else if(soap_version == AXIOM_SOAP12) + { + ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + else + { + return AXIS2_FAILURE; + } + + env_ele = (axiom_element_t *)axiom_node_get_data_element(soap_envelope->om_ele_node, env); + if(!env_ele) + { + return AXIS2_FAILURE; + } + + env_ns = axiom_element_get_namespace(env_ele, env, soap_envelope->om_ele_node); + if(!env_ns) + { + return AXIS2_FAILURE; + } + status = axiom_namespace_set_uri(env_ns, env, ns_uri); + if(status == AXIS2_SUCCESS) + { + axiom_soap_envelope_set_soap_version_internal(soap_envelope, env, soap_version); + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_envelope_increment_ref( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env) +{ + envelope->ref++; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN struct axiom_soap_builder *AXIS2_CALL +axiom_soap_envelope_get_soap_builder( + axiom_soap_envelope_t * envelope, + const axutil_env_t * env) +{ + return envelope->soap_builder; +} + diff --git a/axiom/src/soap/soap_fault.c b/axiom/src/soap/soap_fault.c new file mode 100644 index 0000000..7ee69a8 --- /dev/null +++ b/axiom/src/soap/soap_fault.c @@ -0,0 +1,630 @@ +/* + * 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_soap_fault.h" +#include <axiom_soap_const.h> +#include "_axiom_soap_body.h" +#include <axiom_node.h> +#include <axiom_element.h> +#include <axiom_soap_fault_code.h> +#include <axiom_soap_fault_detail.h> +#include <axiom_soap_fault_value.h> +#include <axiom_soap_fault_text.h> +#include <axiom_soap_fault_reason.h> +#include <axiom_soap_fault_role.h> +#include <axiom_soap_fault_node.h> +#include <axiom_soap_builder.h> + +struct axiom_soap_fault +{ + /* om element node corresponding to soap soap_fault */ + axiom_node_t *om_ele_node; + + /* soap soap_fault code sub element */ + axiom_soap_fault_code_t *fcode; + /* soap soap_fault reason sub element */ + axiom_soap_fault_reason_t *freason; + /* soap soap_fault node sub element */ + axiom_soap_fault_node_t *fnode; + /* soap soap_fault role sub element */ + axiom_soap_fault_role_t *frole; + /* soap soap_fault detail sub element */ + axiom_soap_fault_detail_t *fdetail; + + axis2_char_t *exception; + /* reference to soap builder */ + axiom_soap_builder_t *soap_builder; + + int soap_version; +}; + +AXIS2_EXTERN axiom_soap_fault_t *AXIS2_CALL +axiom_soap_fault_create( + const axutil_env_t * env) +{ + axiom_soap_fault_t *soap_fault = NULL; + soap_fault = (axiom_soap_fault_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_soap_fault_t)); + if(!soap_fault) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create a SOAP fault"); + return NULL; + } + soap_fault->exception = NULL; + soap_fault->fcode = NULL; + soap_fault->fdetail = NULL; + soap_fault->fnode = NULL; + soap_fault->freason = NULL; + soap_fault->frole = NULL; + soap_fault->om_ele_node = NULL; + soap_fault->soap_builder = NULL; + soap_fault->soap_version = -1; + return soap_fault; +} + +AXIS2_EXTERN axiom_soap_fault_t *AXIS2_CALL +axiom_soap_fault_create_with_parent( + const axutil_env_t * env, + axiom_soap_body_t * body) +{ + axiom_soap_fault_t *soap_fault = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axiom_namespace_t *parent_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, body, NULL); + + soap_fault = axiom_soap_fault_create(env); + if(!soap_fault) + { + return NULL; + } + parent_node = axiom_soap_body_get_base_node(body, env); + if(!parent_node) + { + AXIS2_FREE(env->allocator, soap_fault); + return NULL; + } + soap_fault->soap_version = axiom_soap_body_get_soap_version(body, env); + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + AXIS2_FREE(env->allocator, soap_fault); + return NULL; + } + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP_FAULT_LOCAL_NAME, parent_ns, + &this_node); + if(!this_ele) + { + AXIS2_FREE(env->allocator, soap_fault); + return NULL; + } + + soap_fault->om_ele_node = this_node; + axiom_soap_body_set_fault(body, env, soap_fault); + return soap_fault; +} + +AXIS2_EXTERN axiom_soap_fault_t *AXIS2_CALL +axiom_soap_fault_create_with_exception( + const axutil_env_t * env, + axiom_soap_body_t * body, + axis2_char_t * exception) +{ + axiom_soap_fault_t *soap_fault = NULL; + axis2_status_t status = AXIS2_SUCCESS; + AXIS2_PARAM_CHECK(env->error, body, NULL); + AXIS2_PARAM_CHECK(env->error, exception, NULL); + soap_fault = axiom_soap_fault_create_with_parent(env, body); + if(!soap_fault) + { + return NULL; + } + status = axiom_soap_fault_set_exception(soap_fault, env, exception); + if(status == AXIS2_FAILURE) + { + axiom_soap_fault_free(soap_fault, env); + return NULL; + } + return soap_fault; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_free( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + + if(soap_fault->fcode) + { + axiom_soap_fault_code_free(soap_fault->fcode, env); + soap_fault->fcode = NULL; + } + if(soap_fault->fdetail) + { + axiom_soap_fault_detail_free(soap_fault->fdetail, env); + soap_fault->fdetail = NULL; + } + if(soap_fault->fnode) + { + axiom_soap_fault_node_free(soap_fault->fnode, env); + soap_fault->fnode = NULL; + } + if(soap_fault->freason) + { + axiom_soap_fault_reason_free(soap_fault->freason, env); + soap_fault->freason = NULL; + } + if(soap_fault->frole) + { + axiom_soap_fault_role_free(soap_fault->frole, env); + soap_fault->frole = NULL; + } + AXIS2_FREE(env->allocator, soap_fault); + soap_fault = NULL; + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_code( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_soap_fault_code_t * code) +{ + AXIS2_PARAM_CHECK(env->error, code, AXIS2_FAILURE); + if(!(soap_fault->fcode)) + { + soap_fault->fcode = code; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "tring to set multiple code elements to soap_fault "); + + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_soap_fault_code_t *AXIS2_CALL +axiom_soap_fault_get_code( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + if(soap_fault->fcode) + { + return soap_fault->fcode; + } + else if(soap_fault->soap_builder) + { + while(!(soap_fault->fcode) && !(axiom_node_is_complete(soap_fault->om_ele_node, env))) + { + status = axiom_soap_builder_next(soap_fault->soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return soap_fault->fcode; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_reason( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_soap_fault_reason_t * reason) +{ + AXIS2_PARAM_CHECK(env->error, reason, AXIS2_FAILURE); + if(!(soap_fault->freason)) + { + soap_fault->freason = reason; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "tring to set soap_fault reason twice"); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_soap_fault_reason_t *AXIS2_CALL +axiom_soap_fault_get_reason( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + if(soap_fault->freason) + { + return soap_fault->freason; + } + else if(soap_fault->soap_builder) + { + while(!(soap_fault->freason) && !(axiom_node_is_complete(soap_fault->om_ele_node, env))) + { + status = axiom_soap_builder_next(soap_fault->soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return soap_fault->freason; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_node( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_soap_fault_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + if(!(soap_fault->fnode)) + { + soap_fault->fnode = node; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "tring to set soap_fault node more than once"); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_soap_fault_node_t *AXIS2_CALL +axiom_soap_fault_get_node( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(soap_fault->fnode) + { + return soap_fault->fnode; + } + else if(soap_fault->soap_builder) + { + while(!(soap_fault->fnode) && !(axiom_node_is_complete(soap_fault->om_ele_node, env))) + { + status = axiom_soap_builder_next(soap_fault->soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return soap_fault->fnode; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_role( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_soap_fault_role_t * role) +{ + AXIS2_PARAM_CHECK(env->error, role, AXIS2_FAILURE); + + if(!(soap_fault->frole)) + { + soap_fault->frole = role; + return AXIS2_FAILURE; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "tring to set soap_fault role more than once "); + } + return AXIS2_FAILURE; + +} + +AXIS2_EXTERN axiom_soap_fault_role_t *AXIS2_CALL +axiom_soap_fault_get_role( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + if(soap_fault->frole) + { + return soap_fault->frole; + } + else if(soap_fault->soap_builder) + { + while(!(soap_fault->frole) && !(axiom_node_is_complete(soap_fault->om_ele_node, env))) + { + status = axiom_soap_builder_next(soap_fault->soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return soap_fault->frole; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_detail( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_soap_fault_detail_t * detail) +{ + AXIS2_PARAM_CHECK(env->error, detail, AXIS2_FAILURE); + + if(!(soap_fault->fdetail)) + { + soap_fault->fdetail = detail; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, " tring to set soap_fault detail more than once"); + + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_soap_fault_detail_t *AXIS2_CALL +axiom_soap_fault_get_detail( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + if(soap_fault->fdetail) + { + return soap_fault->fdetail; + } + else if(soap_fault->soap_builder) + { + while(!(soap_fault->fdetail) && !(axiom_node_is_complete(soap_fault->om_ele_node, env))) + { + status = axiom_soap_builder_next(soap_fault->soap_builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return soap_fault->fdetail; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_base_node( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + soap_fault->om_ele_node = node; + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_fault_get_base_node( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + return soap_fault->om_ele_node; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_soap_fault_get_exception( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + axiom_soap_fault_detail_t *detail = NULL; + axiom_node_t *detail_node = NULL; + axiom_element_t *detail_ele = NULL; + axiom_node_t *exception_node = NULL; + axiom_element_t *exception_ele = NULL; + axutil_qname_t *qn = NULL; + axis2_char_t *excep = NULL; + + detail = axiom_soap_fault_get_detail(soap_fault, env); + if(!detail) + { + return NULL; + } + detail_node = axiom_soap_fault_detail_get_base_node(detail, env); + if(detail_node) + { + detail_ele = (axiom_element_t *)axiom_node_get_data_element(detail_node, env); + + qn = axutil_qname_create(env, AXIOM_SOAP_FAULT_DETAIL_EXCEPTION_ENTRY, NULL, NULL); + if(qn) + { + exception_ele = axiom_element_get_first_child_with_qname(detail_ele, env, qn, + detail_node, &exception_node); + axutil_qname_free(qn, env); + if(exception_ele) + { + excep = axiom_element_get_text(exception_ele, env, exception_node); + } + return excep; + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_exception( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axis2_char_t * exception) +{ + axiom_soap_fault_detail_t *detail = NULL; + axiom_node_t *fault_detail_entry_node = NULL; + axiom_element_t *fault_detail_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, exception, AXIS2_FAILURE); + + detail = axiom_soap_fault_get_detail(soap_fault, env); + + if(!detail) + { + detail = axiom_soap_fault_detail_create_with_parent(env, soap_fault); + if(!detail) + { + return AXIS2_FAILURE; + } + } + + /** create an om element with the exception enrty */ + + fault_detail_ele = axiom_element_create(env, NULL, AXIOM_SOAP_FAULT_DETAIL_EXCEPTION_ENTRY, + NULL, &fault_detail_entry_node); + if(!fault_detail_ele) + { + return AXIS2_FAILURE; + } + + /** set the exception string as a text node of newly created om element */ + axiom_element_set_text(fault_detail_ele, env, exception, fault_detail_entry_node); + + /** now add this om element as a child of soap soap_fault detail om element node */ + return axiom_soap_fault_detail_add_detail_entry(detail, env, fault_detail_entry_node); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_builder( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + axiom_soap_builder_t * builder) +{ + AXIS2_PARAM_CHECK(env->error, builder, AXIS2_FAILURE); + soap_fault->soap_builder = builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_soap_fault_t *AXIS2_CALL +axiom_soap_fault_create_default_fault( + const axutil_env_t * env, + struct axiom_soap_body * parent, + const axis2_char_t * code_value, + const axis2_char_t * reason_text, + const int soap_version) +{ + axiom_soap_fault_t *soap_fault = NULL; + axiom_node_t *fault_node = NULL; + + axiom_soap_fault_code_t *soap_fault_code = NULL; + axiom_soap_fault_value_t *soap_fault_value = NULL; + + axiom_soap_fault_reason_t *soap_fault_reason = NULL; + axiom_soap_fault_text_t *soap_fault_text = NULL; + + axiom_node_t *value_node = NULL; + axiom_element_t *value_ele = NULL; + + axiom_node_t *text_node = NULL; + axiom_element_t *text_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, code_value, NULL); + AXIS2_PARAM_CHECK(env->error, reason_text, NULL); + + soap_fault = axiom_soap_fault_create_with_parent(env, parent); + if(!soap_fault) + { + return NULL; + } + fault_node = axiom_soap_fault_get_base_node(soap_fault, env); + if(!fault_node) + { + axiom_soap_fault_free(soap_fault, env); + return NULL; + } + + soap_fault_code = axiom_soap_fault_code_create_with_parent(env, soap_fault); + if(!soap_fault_code) + { + axiom_soap_fault_free(soap_fault, env); + axiom_node_free_tree(fault_node, env); + return NULL; + } + soap_fault_reason = axiom_soap_fault_reason_create_with_parent(env, soap_fault); + if(!soap_fault_reason) + { + axiom_soap_fault_free(soap_fault, env); + axiom_node_free_tree(fault_node, env); + return NULL; + } + + soap_fault_value = axiom_soap_fault_value_create_with_code(env, soap_fault_code); + if(!soap_fault_value) + { + axiom_soap_fault_free(soap_fault, env); + axiom_node_free_tree(fault_node, env); + return NULL; + } + + value_node = axiom_soap_fault_value_get_base_node(soap_fault_value, env); + if(!value_node) + { + return NULL; + } + value_ele = (axiom_element_t *)axiom_node_get_data_element(value_node, env); + + axiom_element_set_text(value_ele, env, code_value, value_node); + + soap_fault_text = axiom_soap_fault_text_create_with_parent(env, soap_fault_reason); + if(!soap_fault_text) + { + axiom_soap_fault_free(soap_fault, env); + axiom_node_free_tree(fault_node, env); + return NULL; + } + axiom_soap_fault_text_set_lang(soap_fault_text, env, "en"); + + text_node = axiom_soap_fault_text_get_base_node(soap_fault_text, env); + if(!text_node) + { + return NULL; + } + text_ele = (axiom_element_t *)axiom_node_get_data_element(text_node, env); + + axiom_element_set_text(text_ele, env, reason_text, text_node); + + return soap_fault; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_set_soap_version( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env, + int soap_version) +{ + soap_fault->soap_version = soap_version; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_soap_fault_get_soap_version( + axiom_soap_fault_t * soap_fault, + const axutil_env_t * env) +{ + return soap_fault->soap_version; +} diff --git a/axiom/src/soap/soap_fault_code.c b/axiom/src/soap/soap_fault_code.c new file mode 100644 index 0000000..b0ded55 --- /dev/null +++ b/axiom/src/soap/soap_fault_code.c @@ -0,0 +1,308 @@ +/* + * 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_soap_fault_code.h" +#include <axiom_soap_fault_sub_code.h> +#include <axiom_soap_fault_value.h> +#include <axiom_soap_builder.h> +#include "_axiom_soap_fault.h" + +struct axiom_soap_fault_code +{ + axiom_node_t *om_ele_node; + + axiom_soap_fault_sub_code_t *subcode; + + axiom_soap_fault_value_t *value; + + axiom_soap_builder_t *builder; + + int soap_version; + +}; + +AXIS2_EXTERN axiom_soap_fault_code_t *AXIS2_CALL +axiom_soap_fault_code_create( + const axutil_env_t * env) +{ + axiom_soap_fault_code_t *fault_code = NULL; + fault_code = (axiom_soap_fault_code_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_code_t)); + + if(!fault_code) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP fault code"); + return NULL; + } + + fault_code->om_ele_node = NULL; + fault_code->subcode = NULL; + fault_code->value = NULL; + fault_code->builder = NULL; + fault_code->soap_version = AXIOM_SOAP_VERSION_NOT_SET; + + return fault_code; +} + +AXIS2_EXTERN axiom_soap_fault_code_t *AXIS2_CALL +axiom_soap_fault_code_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_t * fault) +{ + axiom_soap_fault_code_t *fault_code = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + + axiom_namespace_t *parent_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, fault, NULL); + + fault_code = axiom_soap_fault_code_create(env); + if(!fault_code) + { + return NULL; + } + + parent_node = axiom_soap_fault_get_base_node(fault, env); + if(!parent_node) + { + axiom_soap_fault_code_free(fault_code, env); + return NULL; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + + if(!parent_ele) + { + axiom_soap_fault_code_free(fault_code, env); + return NULL; + } + fault_code->soap_version = axiom_soap_fault_get_soap_version(fault, env); + if(fault_code->soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_CODE_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_code_free(fault_code, env); + return NULL; + } + + fault_code->om_ele_node = this_node; + + axiom_soap_fault_set_code(fault, env, fault_code); + + return fault_code; +} + +AXIS2_EXTERN axiom_soap_fault_code_t *AXIS2_CALL +axiom_soap_fault_code_create_with_parent_value( + const axutil_env_t * env, + axiom_soap_fault_t * fault, + axis2_char_t * value) +{ + axiom_soap_fault_code_t *fault_code = NULL; + axiom_soap_fault_value_t *fault_value = NULL; + AXIS2_PARAM_CHECK(env->error, value, NULL); + + fault_code = axiom_soap_fault_code_create_with_parent(env, fault); + if(!fault_code) + { + return NULL; + } + + fault_value = axiom_soap_fault_value_create_with_code(env, fault_code); + if(!fault_value) + { + axiom_soap_fault_code_free(fault_code, env); + return NULL; + } + axiom_soap_fault_value_set_text(fault_value, env, value); + return fault_code; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_code_free( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env) +{ + + if(fault_code->subcode) + { + axiom_soap_fault_sub_code_free(fault_code->subcode, env); + } + if(fault_code->value) + { + axiom_soap_fault_value_free(fault_code->value, env); + } + + AXIS2_FREE(env->allocator, fault_code); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_code_set_value( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + axiom_soap_fault_value_t * fault_val) +{ + + AXIS2_PARAM_CHECK(env->error, fault_val, AXIS2_FAILURE); + + if(!(fault_code->value)) + { + fault_code->value = fault_val; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "trying to set fault value to fault code more than once"); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_code_set_sub_code( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + axiom_soap_fault_sub_code_t * fault_subcode) +{ + AXIS2_PARAM_CHECK(env->error, fault_subcode, AXIS2_FAILURE); + + if(!(fault_code->subcode)) + { + fault_code->subcode = fault_subcode; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "trying to set fault subcode to fault code more than once "); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_soap_fault_sub_code_t *AXIS2_CALL +axiom_soap_fault_code_get_sub_code( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(fault_code->subcode) + { + return fault_code->subcode; + } + else if(fault_code->builder) + { + while(!(fault_code->subcode) && !(axiom_node_is_complete(fault_code->om_ele_node, env))) + { + status = axiom_soap_builder_next(fault_code->builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return fault_code->subcode; +} + +AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL +axiom_soap_fault_code_get_value( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(fault_code->value) + { + return fault_code->value; + } + else if(fault_code->builder) + { + while(!(fault_code->value) && !(axiom_node_is_complete(fault_code->om_ele_node, env))) + { + status = axiom_soap_builder_next(fault_code->builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return fault_code->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_code_set_base_node( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + fault_code->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_fault_code_get_base_node( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env) +{ + return fault_code->om_ele_node; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_code_set_builder( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + axiom_soap_builder_t * soap_builder) +{ + AXIS2_PARAM_CHECK(env->error, soap_builder, AXIS2_FAILURE); + fault_code->builder = soap_builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axiom_soap_fault_code_get_soap_version( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env) +{ + return fault_code->soap_version; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_code_set_soap_version( + axiom_soap_fault_code_t * fault_code, + const axutil_env_t * env, + int soap_version) +{ + fault_code->soap_version = soap_version; + return AXIS2_SUCCESS; +} diff --git a/axiom/src/soap/soap_fault_detail.c b/axiom/src/soap/soap_fault_detail.c new file mode 100644 index 0000000..0375767 --- /dev/null +++ b/axiom/src/soap/soap_fault_detail.c @@ -0,0 +1,160 @@ +/* + * 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_soap_fault.h" +#include <axiom_element.h> +#include <axiom_node.h> +#include "_axiom_soap_fault_detail.h" + +struct axiom_soap_fault_detail +{ + axiom_node_t *om_ele_node; +}; + +AXIS2_EXTERN axiom_soap_fault_detail_t *AXIS2_CALL +axiom_soap_fault_detail_create( + const axutil_env_t * env) +{ + axiom_soap_fault_detail_t *fault_detail = NULL; + + fault_detail = (axiom_soap_fault_detail_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_detail_t)); + if(!fault_detail) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create a fault detail"); + return NULL; + } + + fault_detail->om_ele_node = NULL; + + return fault_detail; +} + +AXIS2_EXTERN axiom_soap_fault_detail_t *AXIS2_CALL +axiom_soap_fault_detail_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_t * fault) +{ + axiom_soap_fault_detail_t *fault_detail = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axiom_namespace_t *parent_ns = NULL; + int soap_version = -1; + + AXIS2_PARAM_CHECK(env->error, fault, NULL); + + fault_detail = axiom_soap_fault_detail_create(env); + if(!fault_detail) + { + return NULL; + } + parent_node = axiom_soap_fault_get_base_node(fault, env); + if(!parent_node) + { + return NULL; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + return NULL; + } + soap_version = axiom_soap_fault_get_soap_version(fault, env); + if(soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_DETAIL_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_detail_free(fault_detail, env); + return NULL; + } + fault_detail->om_ele_node = this_node; + axiom_soap_fault_set_detail(fault, env, fault_detail); + return fault_detail; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_detail_free( + axiom_soap_fault_detail_t * fault_detail, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, fault_detail); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_detail_add_detail_entry( + axiom_soap_fault_detail_t * fault_detail, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_OM_ELEMENT_EXPECTED, AXIS2_FAILURE); + + return AXIS2_FAILURE; + } + + axiom_node_add_child(fault_detail->om_ele_node, env, node); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_children_iterator_t *AXIS2_CALL +axiom_soap_fault_detail_get_all_detail_entries( + axiom_soap_fault_detail_t * fault_detail, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + if(fault_detail->om_ele_node) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(fault_detail->om_ele_node, env); + return axiom_element_get_children(om_ele, env, fault_detail->om_ele_node); + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_detail_set_base_node( + axiom_soap_fault_detail_t * fault_detail, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + fault_detail->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_soap_fault_detail_get_base_node( + axiom_soap_fault_detail_t * fault_detail, + const axutil_env_t * env) +{ + return fault_detail->om_ele_node; +} diff --git a/axiom/src/soap/soap_fault_node.c b/axiom/src/soap/soap_fault_node.c new file mode 100644 index 0000000..143bc87 --- /dev/null +++ b/axiom/src/soap/soap_fault_node.c @@ -0,0 +1,176 @@ +/* + * 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_soap_fault_node.h" +#include <axiom_node.h> +#include <axiom_element.h> +#include "_axiom_soap_fault.h" + +struct axiom_soap_fault_node +{ + axiom_node_t *om_ele_node; +}; + +AXIS2_EXTERN axiom_soap_fault_node_t *AXIS2_CALL +axiom_soap_fault_node_create( + const axutil_env_t * env) +{ + axiom_soap_fault_node_t *fault_node = NULL; + + fault_node = (axiom_soap_fault_node_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_node_t)); + + if(!fault_node) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create a SOAP fault node"); + return NULL; + } + fault_node->om_ele_node = NULL; + + return fault_node; +} + +AXIS2_EXTERN axiom_soap_fault_node_t *AXIS2_CALL +axiom_soap_fault_node_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_t * fault) +{ + axiom_soap_fault_node_t *fault_node = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + + axiom_namespace_t *parent_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, fault, NULL); + + fault_node = axiom_soap_fault_node_create(env); + if(!fault_node) + { + return NULL; + } + parent_node = axiom_soap_fault_get_base_node(fault, env); + if(!parent_node) + { + axiom_soap_fault_node_free(fault_node, env); + return NULL; + } + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + axiom_soap_fault_node_free(fault_node, env); + return NULL; + } + + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_NODE_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_node_free(fault_node, env); + return NULL; + } + + fault_node->om_ele_node = this_node; + + axiom_soap_fault_set_node(fault, env, fault_node); + + return fault_node; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_node_free( + axiom_soap_fault_node_t * fault_node, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, fault_node); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_node_set_value( + axiom_soap_fault_node_t * fault_node, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axiom_element_t *om_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + + if(fault_node->om_ele_node) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(fault_node-> om_ele_node, env); + + if(om_ele) + { + return axiom_element_set_text(om_ele, env, uri, fault_node->om_ele_node); + } + } + + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_soap_fault_node_get_value( + axiom_soap_fault_node_t * fault_node, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + + if(fault_node->om_ele_node) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(fault_node-> om_ele_node, env); + if(om_ele) + { + return axiom_element_get_text(om_ele, env, fault_node->om_ele_node); + } + + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_node_set_base_node( + axiom_soap_fault_node_t * fault_node, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + fault_node->om_ele_node = node; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_fault_node_get_base_node( + axiom_soap_fault_node_t * fault_node, + const axutil_env_t * env) +{ + return fault_node->om_ele_node; +} diff --git a/axiom/src/soap/soap_fault_reason.c b/axiom/src/soap/soap_fault_reason.c new file mode 100644 index 0000000..516d58c --- /dev/null +++ b/axiom/src/soap/soap_fault_reason.c @@ -0,0 +1,386 @@ +/* + * 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_soap_fault_reason.h> +#include "_axiom_soap_fault.h" +#include <axiom_element.h> +#include <axiom_soap_fault_text.h> +#include <axiom_soap_builder.h> +#include <axiom_soap_builder.h> + +struct axiom_soap_fault_reason +{ + /* corresponding om element node */ + axiom_node_t *om_ele_node; + + axutil_array_list_t *fault_texts; + /* pointer to soap builder */ + axiom_soap_builder_t *soap_builder; + + int soap_version; +}; + +static axis2_bool_t +axiom_soap_fault_reason_lang_exists( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axis2_char_t * lang); + +AXIS2_EXTERN axiom_soap_fault_reason_t *AXIS2_CALL +axiom_soap_fault_reason_create( + const axutil_env_t * env) +{ + axiom_soap_fault_reason_t *fault_reason = NULL; + fault_reason = (axiom_soap_fault_reason_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_reason_t)); + if(!fault_reason) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP fault reason"); + return NULL; + } + + fault_reason->om_ele_node = NULL; + fault_reason->fault_texts = NULL; + fault_reason->soap_version = -1; + return fault_reason; +} + +AXIS2_EXTERN axiom_soap_fault_reason_t *AXIS2_CALL +axiom_soap_fault_reason_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_t * fault) +{ + axiom_soap_fault_reason_t *fault_reason = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axiom_namespace_t *parent_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, fault, NULL); + + fault_reason = axiom_soap_fault_reason_create(env); + if(!fault_reason) + { + return NULL; + } + parent_node = axiom_soap_fault_get_base_node(fault, env); + if(!parent_node) + { + return NULL; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + return NULL; + } + fault_reason->soap_version = axiom_soap_fault_get_soap_version(fault, env); + if(fault_reason->soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_REASON_LOCAL_NAME, + parent_ns, &this_node); + if(!this_ele) + { + return NULL; + } + + fault_reason->om_ele_node = this_node; + + axiom_soap_fault_set_reason(fault, env, fault_reason); + return fault_reason; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_reason_free( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env) +{ + + if(fault_reason->fault_texts) + { + int size = 0; + int i = 0; + size = axutil_array_list_size(fault_reason->fault_texts, env); + + for(i = 0; i < size; i++) + { + axiom_soap_fault_text_t *fault_text = NULL; + void *value = NULL; + value = axutil_array_list_get(fault_reason->fault_texts, env, i); + if(value) + { + fault_text = (axiom_soap_fault_text_t *)value; + axiom_soap_fault_text_free(fault_text, env); + fault_text = NULL; + } + } + axutil_array_list_free(fault_reason->fault_texts, env); + fault_reason->fault_texts = NULL; + } + + AXIS2_FREE(env->allocator, fault_reason); + + fault_reason = NULL; + + return; +} + +AXIS2_EXTERN axiom_soap_fault_text_t *AXIS2_CALL +axiom_soap_fault_reason_get_soap_fault_text( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axis2_char_t * lang) +{ + int status = AXIS2_SUCCESS; + int size = 0; + int i = 0; + + AXIS2_PARAM_CHECK(env->error, fault_reason, NULL); + if(!lang || (axutil_strcmp(lang, "") == 0)) + { + return NULL; + } + /** Here we have to build the soap fault reason element completly */ + if(!fault_reason->fault_texts) + { + + if(fault_reason->soap_builder && !(axiom_node_is_complete(fault_reason->om_ele_node, env))) + { + while(!(axiom_node_is_complete(fault_reason->om_ele_node, env))) + { + status = axiom_soap_builder_next(fault_reason->soap_builder, env); + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + } + } + + if(!fault_reason->fault_texts) + { + return NULL; + } + /** iterate the array list */ + size = axutil_array_list_size(fault_reason->fault_texts, env); + for(i = 0; i < size; i++) + { + axiom_soap_fault_text_t *fault_text = NULL; + void *value = NULL; + + value = axutil_array_list_get(fault_reason->fault_texts, env, i); + if(value) + { + axis2_char_t *fault_lang = NULL; + fault_text = (axiom_soap_fault_text_t *)value; + fault_lang = axiom_soap_fault_text_get_lang(fault_text, env); + if(fault_lang && axutil_strcmp(lang, fault_lang) == 0) + { + return fault_text; + } + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_reason_set_base_node( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + fault_reason->om_ele_node = node; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_soap_fault_reason_get_base_node( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env) +{ + return fault_reason->om_ele_node; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_reason_set_builder( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axiom_soap_builder_t * builder) +{ + AXIS2_PARAM_CHECK(env->error, builder, AXIS2_FAILURE); + + fault_reason->soap_builder = builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axiom_soap_fault_reason_get_all_soap_fault_texts( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(!(fault_reason->fault_texts) && (fault_reason->soap_builder)) + { + if(!(axiom_node_is_complete(fault_reason->om_ele_node, env))) + { + while(!(axiom_node_is_complete(fault_reason->om_ele_node, env))) + { + status = axiom_soap_builder_next(fault_reason->soap_builder, env); + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + } + } + return fault_reason->fault_texts; +} + +AXIS2_EXTERN axiom_soap_fault_text_t *AXIS2_CALL +axiom_soap_fault_reason_get_first_soap_fault_text( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(!(fault_reason->fault_texts) && (fault_reason->soap_builder)) + { + if(!(axiom_node_is_complete(fault_reason->om_ele_node, env))) + { + while(!(axiom_node_is_complete(fault_reason->om_ele_node, env))) + { + status = axiom_soap_builder_next(fault_reason->soap_builder, env); + if(status == AXIS2_FAILURE) + { + return NULL; + } + } + } + } + if(fault_reason->fault_texts) + { + void *value = NULL; + value = axutil_array_list_get(fault_reason->fault_texts, env, 0); + if(value) + { + return (axiom_soap_fault_text_t *)value; + } + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_reason_add_soap_fault_text( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axiom_soap_fault_text_t * fault_text) +{ + if(!fault_text) + { + return AXIS2_FAILURE; + } + if(!(fault_reason->fault_texts)) + { + fault_reason->fault_texts = axutil_array_list_create(env, 1); + if(!fault_reason->fault_texts) + { + return AXIS2_FAILURE; + } + axutil_array_list_add(fault_reason->fault_texts, env, fault_text); + } + else + { + axis2_char_t *lang = NULL; + axis2_bool_t is_exists = AXIS2_FALSE; + lang = axiom_soap_fault_text_get_lang(fault_text, env); + if(lang) + { + is_exists = axiom_soap_fault_reason_lang_exists(fault_reason, env, lang); + if(is_exists == AXIS2_TRUE) + { + return AXIS2_FAILURE; + } + /** this soap_fault text already exists */ + } + axutil_array_list_add(fault_reason->fault_texts, env, fault_text); + } + return AXIS2_SUCCESS; +} + +static axis2_bool_t +axiom_soap_fault_reason_lang_exists( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + axis2_char_t * lang) +{ + int size = 0; + int i = 0; + + if(!lang || (axutil_strcmp(lang, "") == 0) || !fault_reason->fault_texts) + { + return AXIS2_FALSE; + } + size = axutil_array_list_size(fault_reason->fault_texts, env); + for(i = 0; i < size; i++) + { + axiom_soap_fault_text_t *fault_text = NULL; + void *value = NULL; + value = axutil_array_list_get(fault_reason->fault_texts, env, i); + if(value) + { + axis2_char_t *text_lang = NULL; + fault_text = (axiom_soap_fault_text_t *)value; + + text_lang = axiom_soap_fault_text_get_lang(fault_text, env); + if(text_lang && (axutil_strcmp(lang, text_lang) == 0)) + { + return AXIS2_TRUE; + } + } + } + return AXIS2_FALSE; +} + +/** internal function */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_reason_set_soap_version( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env, + int soap_version) +{ + fault_reason->soap_version = soap_version; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_reason_get_soap_version( + axiom_soap_fault_reason_t * fault_reason, + const axutil_env_t * env) +{ + return fault_reason->soap_version; +} diff --git a/axiom/src/soap/soap_fault_role.c b/axiom/src/soap/soap_fault_role.c new file mode 100644 index 0000000..a438ea4 --- /dev/null +++ b/axiom/src/soap/soap_fault_role.c @@ -0,0 +1,180 @@ +/* + * 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_soap_fault_role.h> +#include "_axiom_soap_fault.h" +#include <axiom_soap_builder.h> +#include <axiom_element.h> + +struct axiom_soap_fault_role +{ + axiom_node_t *om_ele_node; +}; + +AXIS2_EXTERN axiom_soap_fault_role_t *AXIS2_CALL +axiom_soap_fault_role_create( + const axutil_env_t * env) +{ + axiom_soap_fault_role_t *fault_role = NULL; + + fault_role = (axiom_soap_fault_role_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_role_t)); + + if(!fault_role) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP fault role"); + return NULL; + } + + fault_role->om_ele_node = NULL; + + return fault_role; +} + +AXIS2_EXTERN axiom_soap_fault_role_t *AXIS2_CALL +axiom_soap_fault_role_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_t * fault) +{ + axiom_soap_fault_role_t *fault_role = NULL; + int soap_version = -1; + + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + + axiom_namespace_t *parent_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, fault, NULL); + + fault_role = axiom_soap_fault_role_create(env); + if(!fault_role) + { + return NULL; + } + parent_node = axiom_soap_fault_get_base_node(fault, env); + if(!parent_node) + { + axiom_soap_fault_role_free(fault_role, env); + return NULL; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + + if(!parent_ele) + { + axiom_soap_fault_role_free(fault_role, env); + return NULL; + } + soap_version = axiom_soap_fault_get_soap_version(fault, env); + if(soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_ROLE_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_role_free(fault_role, env); + return NULL; + } + + fault_role->om_ele_node = this_node; + + axiom_soap_fault_set_role(fault, env, fault_role); + + return fault_role; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_role_free( + axiom_soap_fault_role_t * fault_role, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, fault_role); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_role_set_role_value( + axiom_soap_fault_role_t * fault_role, + const axutil_env_t * env, + axis2_char_t * uri) +{ + axiom_element_t *role_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE); + + if(!fault_role->om_ele_node) + { + return AXIS2_FAILURE; + } + role_ele = (axiom_element_t *)axiom_node_get_data_element(fault_role->om_ele_node, env); + + if(role_ele) + { + return axiom_element_set_text(role_ele, env, uri, fault_role->om_ele_node); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL axiom_soap_fault_role_get_role_value( + axiom_soap_fault_role_t * fault_role, + const axutil_env_t * env) +{ + axiom_element_t *role_ele = NULL; + + if (!fault_role->om_ele_node) + { + return NULL; + } + role_ele = (axiom_element_t *) axiom_node_get_data_element + (fault_role->om_ele_node, env); + + if (role_ele) + { + return axiom_element_get_text(role_ele, env, fault_role->om_ele_node); + } + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_role_set_base_node( + axiom_soap_fault_role_t * fault_role, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + fault_role->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_soap_fault_role_get_base_node( + axiom_soap_fault_role_t * fault_role, + const axutil_env_t * env) +{ + return fault_role->om_ele_node; +} diff --git a/axiom/src/soap/soap_fault_sub_code.c b/axiom/src/soap/soap_fault_sub_code.c new file mode 100644 index 0000000..904b406 --- /dev/null +++ b/axiom/src/soap/soap_fault_sub_code.c @@ -0,0 +1,298 @@ +/* + * 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_soap_fault_sub_code.h> +#include "_axiom_soap_fault_code.h" +#include <axiom_soap_fault_value.h> +#include <axiom_soap_builder.h> + +struct axiom_soap_fault_sub_code +{ + /* corresponding om element node */ + axiom_node_t *om_ele_node; + /* sub element fault value */ + axiom_soap_fault_value_t *value; + /* sub element fault subcode */ + axiom_soap_fault_sub_code_t *subcode; + /* pointer to soap builder */ + axiom_soap_builder_t *builder; + + int soap_version; +}; + +AXIS2_EXTERN axiom_soap_fault_sub_code_t *AXIS2_CALL +axiom_soap_fault_sub_code_create( + const axutil_env_t * env) +{ + axiom_soap_fault_sub_code_t *fault_sub_code = NULL; + AXIS2_ENV_CHECK(env, NULL); + fault_sub_code = (axiom_soap_fault_sub_code_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_sub_code_t)); + if(!fault_sub_code) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP fault sub-code"); + return NULL; + } + + fault_sub_code->om_ele_node = NULL; + fault_sub_code->value = NULL; + fault_sub_code->subcode = NULL; + fault_sub_code->builder = NULL; + + return fault_sub_code; +} + +AXIS2_EXTERN axiom_soap_fault_sub_code_t *AXIS2_CALL +axiom_soap_fault_sub_code_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_code_t * fault_code) +{ + axiom_soap_fault_sub_code_t *fault_sub_code = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axiom_namespace_t *parent_ns = NULL; + + AXIS2_PARAM_CHECK(env->error, fault_code, NULL); + fault_sub_code = axiom_soap_fault_sub_code_create(env); + + if(!fault_sub_code) + { + return NULL; + } + parent_node = axiom_soap_fault_code_get_base_node(fault_code, env); + if(!parent_node) + { + axiom_soap_fault_sub_code_free(fault_sub_code, env); + return NULL; + } + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + axiom_soap_fault_sub_code_free(fault_sub_code, env); + return NULL; + } + fault_sub_code->soap_version = axiom_soap_fault_code_get_soap_version(fault_code, env); + + if(fault_sub_code->soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_SUB_CODE_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_sub_code_free(fault_sub_code, env); + return NULL; + } + + fault_sub_code->om_ele_node = this_node; + + axiom_soap_fault_code_set_sub_code(fault_code, env, fault_sub_code); + + return fault_sub_code; +} + +AXIS2_EXTERN axiom_soap_fault_sub_code_t *AXIS2_CALL +axiom_soap_fault_sub_code_create_with_parent_value( + const axutil_env_t * env, + axiom_soap_fault_code_t * fault_code, + axis2_char_t * value) +{ + axiom_soap_fault_sub_code_t *fault_sub_code = NULL; + axiom_soap_fault_value_t *fault_value = NULL; + AXIS2_PARAM_CHECK(env->error, value, NULL); + + fault_sub_code = axiom_soap_fault_sub_code_create_with_parent(env, fault_code); + if(!fault_sub_code) + { + return NULL; + } + fault_value = axiom_soap_fault_value_create_with_subcode(env, fault_sub_code); + if(!fault_value) + { + axiom_soap_fault_sub_code_free(fault_sub_code, env); + return NULL; + } + + axiom_soap_fault_value_set_text(fault_value, env, value); + return fault_sub_code; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_sub_code_free( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env) +{ + if(fault_sub_code->value) + { + axiom_soap_fault_value_free(fault_sub_code->value, env); + fault_sub_code->value = NULL; + } + if(fault_sub_code->subcode) + { + axiom_soap_fault_sub_code_free(fault_sub_code->subcode, env); + fault_sub_code->subcode = NULL; + } + AXIS2_FREE(env->allocator, fault_sub_code); + + fault_sub_code = NULL; + + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_sub_code_set_sub_code( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + axiom_soap_fault_sub_code_t * subcode) +{ + AXIS2_PARAM_CHECK(env->error, subcode, AXIS2_FAILURE); + + if(!(fault_sub_code->subcode)) + { + fault_sub_code->subcode = subcode; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "error tring to set fault subcode more than once"); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL +axiom_soap_fault_sub_code_get_value( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(fault_sub_code->builder) + { + while(!(fault_sub_code->value) && !axiom_node_is_complete(fault_sub_code->om_ele_node, env)) + { + status = axiom_soap_builder_next(fault_sub_code->builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return fault_sub_code->value; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_sub_code_set_value( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + axiom_soap_fault_value_t * fault_sub_code_val) +{ + AXIS2_PARAM_CHECK(env->error, fault_sub_code_val, AXIS2_FAILURE); + + if(!(fault_sub_code->value)) + { + fault_sub_code->value = fault_sub_code_val; + return AXIS2_SUCCESS; + } + else + { + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, + "error tring to set fault subcode value more than once"); + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axiom_soap_fault_sub_code_t *AXIS2_CALL +axiom_soap_fault_sub_code_get_subcode( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env) +{ + int status = AXIS2_SUCCESS; + + if(fault_sub_code->builder) + { + while(!(fault_sub_code->subcode) && !axiom_node_is_complete(fault_sub_code->om_ele_node, + env)) + { + status = axiom_soap_builder_next(fault_sub_code->builder, env); + if(status == AXIS2_FAILURE) + { + break; + } + } + } + return fault_sub_code->subcode; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_sub_code_set_base_node( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + fault_sub_code->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_soap_fault_sub_code_get_base_node( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env) +{ + return fault_sub_code->om_ele_node; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_sub_code_set_builder( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + axiom_soap_builder_t * builder) +{ + AXIS2_PARAM_CHECK(env->error, builder, AXIS2_FAILURE); + + fault_sub_code->builder = builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_sub_code_set_soap_version( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env, + int soap_version) +{ + fault_sub_code->soap_version = soap_version; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL axiom_soap_fault_sub_code_get_soap_version( + axiom_soap_fault_sub_code_t * fault_sub_code, + const axutil_env_t * env) +{ + return fault_sub_code->soap_version; +} diff --git a/axiom/src/soap/soap_fault_text.c b/axiom/src/soap/soap_fault_text.c new file mode 100644 index 0000000..9c51821 --- /dev/null +++ b/axiom/src/soap/soap_fault_text.c @@ -0,0 +1,305 @@ +/* + * 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_soap_fault.h> +#include <axiom_element.h> +#include "_axiom_soap_fault_text.h" +#include "_axiom_soap_fault_reason.h" +#include <axiom_namespace.h> +#include <axutil_qname.h> + +struct axiom_soap_fault_text +{ + axiom_attribute_t *lang_attribute; + + axiom_namespace_t *lang_namespace; + + axiom_node_t *om_ele_node; + + axis2_bool_t lang_ns_used; +}; + +AXIS2_EXTERN axiom_soap_fault_text_t *AXIS2_CALL +axiom_soap_fault_text_create( + const axutil_env_t * env) +{ + axiom_soap_fault_text_t *fault_text = NULL; + + fault_text = (axiom_soap_fault_text_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_text_t)); + if(!fault_text) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP fault text"); + return NULL; + } + + fault_text->om_ele_node = NULL; + fault_text->lang_attribute = NULL; + fault_text->lang_namespace = NULL; + fault_text->lang_ns_used = AXIS2_FALSE; + + fault_text->lang_namespace = axiom_namespace_create(env, + AXIOM_SOAP12_SOAP_FAULT_TEXT_LANG_ATTR_NS_URI, + AXIOM_SOAP12_SOAP_FAULT_TEXT_LANG_ATTR_NS_PREFIX); + + if(!(fault_text->lang_namespace)) + { + return NULL; + } + + return fault_text; +} + +AXIS2_EXTERN axiom_soap_fault_text_t *AXIS2_CALL +axiom_soap_fault_text_create_with_parent( + const axutil_env_t * env, + axiom_soap_fault_reason_t * parent) +{ + axiom_soap_fault_text_t *fault_text = NULL; + axiom_element_t *this_ele = NULL; + int soap_version = -1; + axiom_node_t *this_node = NULL; + axiom_namespace_t *parent_ns = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, parent, NULL); + + fault_text = axiom_soap_fault_text_create(env); + + if(!fault_text) + { + return NULL; + } + + parent_node = axiom_soap_fault_reason_get_base_node(parent, env); + if(!parent_node) + { + axiom_soap_fault_text_free(fault_text, env); + return NULL; + } + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + axiom_soap_fault_text_free(fault_text, env); + return NULL; + } + + soap_version = axiom_soap_fault_reason_get_soap_version(parent, env); + if(AXIOM_SOAP12 == soap_version) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_TEXT_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_text_free(fault_text, env); + return NULL; + } + + fault_text->om_ele_node = this_node; + + axiom_soap_fault_reason_add_soap_fault_text(parent, env, fault_text); + + return fault_text; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_text_free( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env) +{ + + if(fault_text->lang_ns_used == AXIS2_FALSE && fault_text->lang_namespace) + { + axiom_namespace_free(fault_text->lang_namespace, env); + fault_text->lang_namespace = NULL; + } + AXIS2_FREE(env->allocator, fault_text); + fault_text = NULL; + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_text_set_lang( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env, + const axis2_char_t * lang) +{ + int status = AXIS2_SUCCESS; + axiom_element_t *om_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, lang, AXIS2_FAILURE); + + if(fault_text->lang_attribute) + { + axis2_char_t *attr_lang = NULL; + attr_lang = axiom_attribute_get_value(fault_text->lang_attribute, env); + if(attr_lang) + { + if(axutil_strcmp(attr_lang, lang) == 0) + { + + /** this attribute already exists */ + return AXIS2_SUCCESS; + } + } + axiom_attribute_set_value(fault_text->lang_attribute, env, lang); + return AXIS2_SUCCESS; + } + + fault_text->lang_attribute = axiom_attribute_create(env, + AXIOM_SOAP12_SOAP_FAULT_TEXT_LANG_ATTR_LOCAL_NAME, lang, fault_text-> lang_namespace); + if(!fault_text->lang_attribute) + { + return AXIS2_FAILURE; + } + + if(!fault_text->om_ele_node) + { + return AXIS2_FAILURE; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(fault_text->om_ele_node, env); + if(!om_ele) + { + return AXIS2_FAILURE; + } + + status = axiom_element_add_attribute(om_ele, env, fault_text->lang_attribute, + fault_text->om_ele_node); + + if(status == AXIS2_SUCCESS) + { + fault_text->lang_ns_used = AXIS2_TRUE; + } + else + { + axiom_attribute_free(fault_text->lang_attribute, env); + fault_text->lang_attribute = NULL; + } + return status; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_soap_fault_text_get_lang( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + axutil_qname_t *tmp_qname = NULL; + + if(!fault_text->om_ele_node) + { + return NULL; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(fault_text->om_ele_node, env); + if(!om_ele) + { + return NULL; + } + if(!(fault_text->lang_attribute)) + { + + /* this logic need to be rechecked */ + tmp_qname = axutil_qname_create(env, AXIOM_SOAP12_SOAP_FAULT_TEXT_LANG_ATTR_LOCAL_NAME, + AXIOM_SOAP12_SOAP_FAULT_TEXT_LANG_ATTR_NS_URI, + AXIOM_SOAP12_SOAP_FAULT_TEXT_LANG_ATTR_NS_PREFIX); + + fault_text->lang_attribute = axiom_element_get_attribute(om_ele, env, tmp_qname); + axutil_qname_free(tmp_qname, env); + } + if(fault_text->lang_attribute) + { + return axiom_attribute_get_value(fault_text->lang_attribute, env); + } + else + return NULL; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_text_set_base_node( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env, + axiom_node_t * node) +{ + + if(node && (axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + fault_text->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_fault_text_get_base_node( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env) +{ + return fault_text->om_ele_node; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_text_set_text( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env, + axis2_char_t * value, + axis2_char_t * lang) +{ + AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE); + + if(fault_text->om_ele_node) + { + axiom_element_t *text_ele = NULL; + text_ele = (axiom_element_t *)axiom_node_get_data_element(fault_text->om_ele_node, env); + if(text_ele) + { + axiom_element_set_text(text_ele, env, value, fault_text->om_ele_node); + if(lang) + { + axiom_soap_fault_text_set_lang(fault_text, env, lang); + } + return AXIS2_SUCCESS; + } + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_soap_fault_text_get_text( + axiom_soap_fault_text_t * fault_text, + const axutil_env_t * env) +{ + axis2_char_t *text = NULL; + + if(fault_text->om_ele_node) + { + axiom_element_t *text_ele = NULL; + text_ele = (axiom_element_t *)axiom_node_get_data_element(fault_text->om_ele_node, env); + if(text_ele) + { + text = axiom_element_get_text(text_ele, env, fault_text->om_ele_node); + return text; + } + } + return NULL; +} diff --git a/axiom/src/soap/soap_fault_value.c b/axiom/src/soap/soap_fault_value.c new file mode 100644 index 0000000..775cba4 --- /dev/null +++ b/axiom/src/soap/soap_fault_value.c @@ -0,0 +1,237 @@ +/* + * 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_soap_fault_value.h> +#include "_axiom_soap_fault_sub_code.h" +#include "_axiom_soap_fault_code.h" +#include <axiom_element.h> +#include <axiom_text.h> + +struct axiom_soap_fault_value +{ + + /** store om element node */ + axiom_node_t *om_ele_node; +}; + +AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL +axiom_soap_fault_value_create( + const axutil_env_t * env) +{ + axiom_soap_fault_value_t *fault_value = NULL; + + fault_value = (axiom_soap_fault_value_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_fault_value_t)); + + if(!fault_value) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP fault value"); + return NULL; + } + + fault_value->om_ele_node = NULL; + + return fault_value; +} + +AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL +axiom_soap_fault_value_create_with_subcode( + const axutil_env_t * env, + axiom_soap_fault_sub_code_t * parent) +{ + axiom_soap_fault_value_t *fault_value = NULL; + + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_namespace_t *parent_ns = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + int soap_version = -1; + + AXIS2_PARAM_CHECK(env->error, parent, NULL); + + fault_value = axiom_soap_fault_value_create(env); + + if(!fault_value) + { + return NULL; + } + + parent_node = axiom_soap_fault_sub_code_get_base_node(parent, env); + + if(!parent_node) + { + axiom_soap_fault_value_free(fault_value, env); + return NULL; + } + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + + if(!parent_ele) + { + axiom_soap_fault_value_free(fault_value, env); + return NULL; + } + soap_version = axiom_soap_fault_sub_code_get_soap_version(parent, env); + if(soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_value_free(fault_value, env); + return NULL; + } + + fault_value->om_ele_node = this_node; + + axiom_soap_fault_sub_code_set_value(parent, env, fault_value); + + return fault_value; +} + +AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL +axiom_soap_fault_value_create_with_code( + const axutil_env_t * env, + axiom_soap_fault_code_t * parent) +{ + axiom_soap_fault_value_t *fault_value = NULL; + int soap_version = -1; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_namespace_t *parent_ns = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, parent, NULL); + + fault_value = axiom_soap_fault_value_create(env); + + if(!fault_value) + { + return NULL; + } + + parent_node = axiom_soap_fault_code_get_base_node(parent, env); + if(!parent_node) + { + axiom_soap_fault_value_free(fault_value, env); + return NULL; + } + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + axiom_soap_fault_value_free(fault_value, env); + return NULL; + } + soap_version = axiom_soap_fault_code_get_soap_version(parent, env); + if(soap_version == AXIOM_SOAP12) + { + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + } + this_ele = axiom_element_create(env, parent_node, AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME, + parent_ns, &this_node); + + if(!this_ele) + { + axiom_soap_fault_value_free(fault_value, env); + return NULL; + } + fault_value->om_ele_node = this_node; + + axiom_soap_fault_code_set_value(parent, env, fault_value); + + return fault_value; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_fault_value_free( + axiom_soap_fault_value_t * fault_value, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, fault_value); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_value_set_base_node( + axiom_soap_fault_value_t * fault_value, + const axutil_env_t * env, + axiom_node_t * node) +{ + + if(node && (axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + fault_value->om_ele_node = node; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_fault_value_get_base_node( + axiom_soap_fault_value_t * fault_value, + const axutil_env_t * env) +{ + return fault_value->om_ele_node; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_soap_fault_value_get_text( + axiom_soap_fault_value_t * fault_value, + const axutil_env_t * env) +{ + axiom_node_t *value_node = NULL; + axiom_element_t *value_element = NULL; + + value_node = axiom_soap_fault_value_get_base_node(fault_value, env); + + if(!value_node) + { + return NULL; + } + value_element = (axiom_element_t *)axiom_node_get_data_element(value_node, env); + + if(!value_element) + { + return NULL; + } + return axiom_element_get_text(value_element, env, value_node); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_fault_value_set_text( + axiom_soap_fault_value_t * fault_value, + const axutil_env_t * env, + axis2_char_t * text) +{ + AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); + if(fault_value->om_ele_node && axiom_node_get_node_type(fault_value->om_ele_node, env) + == AXIOM_ELEMENT) + { + axiom_element_t *om_ele = NULL; + om_ele = (axiom_element_t *)axiom_node_get_data_element(fault_value->om_ele_node, env); + return axiom_element_set_text(om_ele, env, text, fault_value->om_ele_node); + } + return AXIS2_FAILURE; +} diff --git a/axiom/src/soap/soap_header.c b/axiom/src/soap/soap_header.c new file mode 100644 index 0000000..6c6a71c --- /dev/null +++ b/axiom/src/soap/soap_header.c @@ -0,0 +1,655 @@ +/* + * 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_soap_envelope.h" +#include "_axiom_soap_header.h" +#include "_axiom_soap_body.h" +#include <axiom_soap_header_block.h> +#include <axutil_hash.h> +#include <axiom_soap_const.h> +#include <axiom_soap_builder.h> +#include <stdio.h> +#include <axiom_node_internal.h> +#include <axutil_array_list.h> + +struct axiom_soap_header +{ + axiom_node_t *om_ele_node; + + int soap_version; + + axutil_hash_t *header_blocks; + + int hbnumber; + + axiom_soap_builder_t *soap_builder; + + axiom_soap_envelope_t *soap_envelope; + + axutil_array_list_t *header_block_keys; +}; + +static axis2_bool_t AXIS2_CALL axiom_soap_header_qname_matches( + const axutil_env_t * env, + axutil_qname_t * element_qname, + axutil_qname_t * qname_to_match); + +AXIS2_EXTERN axiom_soap_header_t *AXIS2_CALL +axiom_soap_header_create( + const axutil_env_t * env) +{ + axiom_soap_header_t *soap_header = NULL; + + soap_header = (axiom_soap_header_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_soap_header_t)); + if(!soap_header) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP header"); + return NULL; + } + + soap_header->om_ele_node = NULL; + soap_header->soap_envelope = NULL; + soap_header->hbnumber = 0; + soap_header->header_blocks = NULL; + + /** default value */ + soap_header->soap_version = AXIOM_SOAP12; + soap_header->header_block_keys = NULL; + + soap_header->header_block_keys = axutil_array_list_create(env, 10); + if(!soap_header->header_block_keys) + { + AXIS2_FREE(env->allocator, soap_header); + return NULL; + } + + return soap_header; +} + +AXIS2_EXTERN axiom_soap_header_t *AXIS2_CALL +axiom_soap_header_create_with_parent( + const axutil_env_t * env, + axiom_soap_envelope_t * envelope) +{ + axiom_soap_header_t *soap_header = NULL; + + /*axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL;*/ + axiom_node_t *body_node = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + + /*axiom_namespace_t *parent_ns = NULL;*/ + + AXIS2_PARAM_CHECK(env->error, envelope, NULL); + + soap_header = axiom_soap_header_create(env); + if(!soap_header) + { + return NULL; + } + soap_header->soap_version = axiom_soap_envelope_get_soap_version(envelope, env); + + parent_node = axiom_soap_envelope_get_base_node(envelope, env); + + if(!parent_node || axiom_node_get_node_type(parent_node, env) != AXIOM_ELEMENT) + { + axiom_soap_header_free(soap_header, env); + return NULL; + } + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + axiom_soap_header_free(soap_header, env); + return NULL; + } + if(axiom_node_get_first_element(parent_node, env)) + { + body_node = axiom_node_get_first_element(parent_node, env); + axiom_node_detach(body_node, env); + } + + /*parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + this_ele = axiom_element_create(env, parent_node, + AXIOM_SOAP_HEADER_LOCAL_NAME, parent_ns, + &this_node); + if (!this_ele) + { + axiom_soap_header_free(soap_header, env); + return NULL; + } + + soap_header->om_ele_node = this_node;*/ + + axiom_soap_envelope_set_header(envelope, env, soap_header); + + if(body_node) + { + axiom_node_add_child(parent_node, env, body_node); + } + + soap_header->soap_envelope = envelope; + + return soap_header; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_header_free( + axiom_soap_header_t * soap_header, + const axutil_env_t * env) +{ + + if(soap_header->header_blocks) + { + axutil_hash_index_t *hi = NULL; + void *val = NULL; + for(hi = axutil_hash_first(soap_header->header_blocks, env); hi; hi = axutil_hash_next(env, + hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + + if(val) + { + axiom_soap_header_block_free((axiom_soap_header_block_t *)val, env); + val = NULL; + } + } + + axutil_hash_free(soap_header->header_blocks, env); + } + if(soap_header->header_block_keys) + { + int size = 0; + void *val = NULL; + int i = 0; + size = axutil_array_list_size(soap_header->header_block_keys, env); + for(i = 0; i < size; i++) + { + val = axutil_array_list_get(soap_header->header_block_keys, env, i); + if(val) + { + AXIS2_FREE(env->allocator, (char *)val); + val = NULL; + } + } + axutil_array_list_free(soap_header->header_block_keys, env); + soap_header->header_block_keys = NULL; + } + AXIS2_FREE(env->allocator, soap_header); + + soap_header = NULL; + + return; +} + +AXIS2_EXTERN axiom_soap_header_block_t *AXIS2_CALL +axiom_soap_header_add_header_block( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + const axis2_char_t * localname, + axiom_namespace_t * ns) +{ + axiom_soap_header_block_t *header_block = NULL; + + axiom_namespace_t *cloned_ns = NULL; + + axiom_node_t *header_block_node = NULL; + + AXIS2_PARAM_CHECK(env->error, localname, NULL); + AXIS2_PARAM_CHECK(env->error, ns, NULL); + + cloned_ns = axiom_namespace_clone(ns, env); + if(!cloned_ns) + { + return NULL; + } + header_block = axiom_soap_header_block_create_with_parent(env, localname, cloned_ns, + soap_header); + + if(!header_block) + { + return NULL; + } + header_block_node = axiom_soap_header_block_get_base_node(header_block, env); + + if(header_block_node) + { + axiom_node_set_complete(header_block_node, env, AXIS2_TRUE); + + return header_block; + } + else + { + return NULL; + } +} +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL axiom_soap_header_examine_header_blocks( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + axis2_char_t * param_role) +{ + AXIS2_PARAM_CHECK(env->error, param_role, NULL); + + return soap_header->header_blocks; +} + +AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL +axiom_soap_header_examine_all_header_blocks( + axiom_soap_header_t * soap_header, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + + if(!soap_header->om_ele_node) + { + return NULL; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(soap_header-> om_ele_node, env); + + if(om_ele) + { + return axiom_element_get_children_with_qname(om_ele, env, NULL, soap_header->om_ele_node); + } + else + return NULL; +} + +AXIS2_EXTERN axiom_children_with_specific_attribute_iterator_t *AXIS2_CALL +axiom_soap_header_extract_header_blocks( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + axis2_char_t * role) +{ + const axis2_char_t *localname = NULL; + const axis2_char_t *nsuri = NULL; + + axiom_node_t *first_node = NULL; + axiom_element_t *first_ele = NULL; + + axutil_qname_t *qn = NULL; + + axiom_element_t *header_om_ele = NULL; + axiom_children_with_specific_attribute_iterator_t *iter = NULL; + + if(soap_header->soap_version == AXIOM_SOAP_VERSION_NOT_SET) + { + return NULL; + } + if(soap_header->soap_version == AXIOM_SOAP11) + { + localname = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + nsuri = AXIOM_SOAP11_ATTR_ACTOR; + } + if(soap_header->soap_version == AXIOM_SOAP12) + { + localname = AXIOM_SOAP12_SOAP_ROLE; + nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + + qn = axutil_qname_create(env, localname, nsuri, NULL); + if(!qn) + { + return NULL; + } + header_om_ele = (axiom_element_t *)axiom_node_get_data_element(soap_header->om_ele_node, env); + + if(header_om_ele) + { + first_ele = axiom_element_get_first_element(header_om_ele, env, soap_header->om_ele_node, + &first_node); + if(first_node) + { + return axiom_children_with_specific_attribute_iterator_create(env, first_node, qn, + role, AXIS2_TRUE); + } + } + + axutil_qname_free(qn, env); + + return iter; + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_set_base_node( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + + soap_header->om_ele_node = node; + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_soap_header_get_base_node( + axiom_soap_header_t * soap_header, + const axutil_env_t * env) +{ + if(!soap_header->om_ele_node) + { + axiom_node_t *parent_node = NULL; + axiom_element_t *parent_ele = NULL; + axiom_namespace_t *parent_ns = NULL; + axiom_element_t *this_ele = NULL; + axiom_node_t *this_node = NULL; + axiom_soap_body_t *soap_body = NULL; + axiom_node_t *body_node = NULL; + + parent_node = axiom_soap_envelope_get_base_node(soap_header->soap_envelope, env); + + if(!parent_node || axiom_node_get_node_type(parent_node, env) != AXIOM_ELEMENT) + { + axiom_soap_header_free(soap_header, env); + return NULL; + } + + parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env); + if(!parent_ele) + { + axiom_soap_header_free(soap_header, env); + return NULL; + } + + parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node); + this_ele = axiom_element_create(env, NULL, AXIOM_SOAP_HEADER_LOCAL_NAME, parent_ns, + &this_node); + if(!this_ele) + { + axiom_soap_header_free(soap_header, env); + return NULL; + } + + soap_body = axiom_soap_envelope_get_body(soap_header->soap_envelope, env); + if(soap_body) + { + body_node = axiom_soap_body_get_base_node(soap_body, env); + axiom_node_insert_sibling_before(body_node, env, this_node); + } + else + { + axiom_node_add_child(parent_node, env, this_node); + } + soap_header->om_ele_node = this_node; + } + + return soap_header->om_ele_node; +} + +/** + set soap version and get soap version are internal functions + + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_get_soap_version( + axiom_soap_header_t * soap_header, + const axutil_env_t * env) +{ + return soap_header->soap_version; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_set_soap_version( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + int soap_version) +{ + soap_header->soap_version = soap_version; + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_set_header_block( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + struct axiom_soap_header_block * header_block) +{ + axis2_char_t *key = NULL; + AXIS2_PARAM_CHECK(env->error, header_block, AXIS2_FAILURE); + + key = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 10); + + if(!key) + { + return AXIS2_FAILURE; + } + sprintf(key, "%d", soap_header->hbnumber++); + + if(soap_header->header_blocks) + { + axutil_hash_set(soap_header->header_blocks, key, AXIS2_HASH_KEY_STRING, header_block); + } + else + { + soap_header->header_blocks = axutil_hash_make(env); + axutil_hash_set(soap_header->header_blocks, key, AXIS2_HASH_KEY_STRING, header_block); + } + if(soap_header->header_block_keys) + { + axutil_array_list_add(soap_header->header_block_keys, env, key); + } + return AXIS2_SUCCESS; + +} +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_set_builder( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + struct axiom_soap_builder * builder) +{ + AXIS2_PARAM_CHECK(env->error, builder, AXIS2_FAILURE); + + soap_header->soap_builder = builder; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL +axiom_soap_header_get_header_blocks_with_namespace_uri( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + const axis2_char_t * ns_uri) +{ + axutil_array_list_t *header_block_list = NULL; + axutil_hash_index_t *hash_index = NULL; + + axiom_soap_header_block_t *header_block = NULL; + + axiom_node_t *header_block_om_node = NULL; + axiom_element_t *header_block_om_ele = NULL; + + axiom_namespace_t *ns = NULL; + axis2_char_t *hb_namespace_uri = NULL; + + int found = 0; + void *hb = NULL; + + AXIS2_PARAM_CHECK(env->error, ns_uri, NULL); + + if(!(soap_header->header_blocks)) + { + return NULL; + } + header_block_list = axutil_array_list_create(env, 10); + if(!header_block_list) + { + return NULL; + } + for(hash_index = axutil_hash_first(soap_header->header_blocks, env); hash_index; hash_index + = axutil_hash_next(env, hash_index)) + { + axutil_hash_this(hash_index, NULL, NULL, &hb); + if(hb) + { + header_block = (axiom_soap_header_block_t *)hb; + + header_block_om_node = axiom_soap_header_block_get_base_node(header_block, env); + if(header_block_om_node) + { + header_block_om_ele = (axiom_element_t *)axiom_node_get_data_element( + header_block_om_node, env); + if(header_block_om_ele) + { + ns + = axiom_element_get_namespace(header_block_om_ele, env, + header_block_om_node); + if(ns) + { + hb_namespace_uri = axiom_namespace_get_uri(ns, env); + if(axutil_strcmp(hb_namespace_uri, ns_uri) == 0) + { + axutil_array_list_add(header_block_list, env, header_block); + found++; + } + } + } + } + hb = NULL; + header_block = NULL; + header_block_om_ele = NULL; + header_block_om_node = NULL; + ns = NULL; + hb_namespace_uri = NULL; + } + } + if(found > 0) + { + return header_block_list; + } + else + { + axutil_array_list_free(header_block_list, env); + } + return NULL; +} + +AXIS2_EXTERN axutil_hash_t *AXIS2_CALL +axiom_soap_header_get_all_header_blocks( + axiom_soap_header_t * soap_header, + const axutil_env_t * env) +{ + return soap_header->header_blocks; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_remove_header_block( + axiom_soap_header_t * soap_header, + const axutil_env_t * env, + axutil_qname_t * qname) +{ + axis2_char_t *qn_localname = NULL; + axis2_char_t *qname_ns = NULL; + axis2_char_t *qname_prefix = NULL; + axutil_hash_index_t *hi = NULL; + + AXIS2_PARAM_CHECK(env->error, qname, AXIS2_FAILURE); + + qn_localname = axutil_qname_get_localpart(qname, env); + qname_ns = axutil_qname_get_uri(qname, env); + qname_prefix = axutil_qname_get_prefix(qname, env); + + if(!soap_header->header_blocks) + { + return AXIS2_FAILURE; + } + for(hi = axutil_hash_first(soap_header->header_blocks, env); hi; hi = axutil_hash_next(env, hi)) + { + const void *key = NULL; + void *val = NULL; + + axutil_hash_this(hi, &key, NULL, &val); + if(val) + { + axiom_soap_header_block_t *header_block = NULL; + axiom_element_t *ele = NULL; + axiom_node_t *node = NULL; + + header_block = (axiom_soap_header_block_t *)val; + node = axiom_soap_header_block_get_base_node(header_block, env); + if(node) + { + axutil_qname_t *element_qname = NULL; + + ele = (axiom_element_t *)axiom_node_get_data_element(node, env); + element_qname = axiom_element_get_qname(ele, env, node); + if(axiom_soap_header_qname_matches(env, element_qname, qname) == AXIS2_TRUE) + { + axiom_node_detach(node, env); + /* axiom_node_free_tree(node, env); */ + axutil_hash_set(soap_header->header_blocks, key, AXIS2_HASH_KEY_STRING, NULL); + axiom_soap_header_block_free(header_block, env); + axiom_node_free_tree(node, env); + break; + } + } + } + } + + if(hi) + { + AXIS2_FREE(env->allocator, hi); + } + + return AXIS2_SUCCESS; +} + +static axis2_bool_t AXIS2_CALL +axiom_soap_header_qname_matches( + const axutil_env_t * env, + axutil_qname_t * element_qname, + axutil_qname_t * qname_to_match) +{ + int lparts_match = 0; + int uris_match = 0; + axis2_char_t *ele_lpart = NULL; + axis2_char_t *match_lpart = NULL; + axis2_char_t *ele_nsuri = NULL; + axis2_char_t *match_nsuri = NULL; + + if(!(qname_to_match)) + { + return AXIS2_TRUE; + } + if(qname_to_match) + { + match_lpart = axutil_qname_get_localpart(qname_to_match, env); + match_nsuri = axutil_qname_get_uri(qname_to_match, env); + } + if(element_qname) + { + ele_lpart = axutil_qname_get_localpart(element_qname, env); + ele_nsuri = axutil_qname_get_uri(element_qname, env); + } + + lparts_match = (!match_lpart || (axutil_strcmp(match_lpart, "") == 0) || (element_qname + && (axutil_strcmp(ele_lpart, match_lpart) == 0))); + + uris_match = (!match_nsuri || (axutil_strcmp(match_nsuri, "") == 0) || (element_qname + && (axutil_strcmp(ele_nsuri, match_nsuri) == 0))); + + return lparts_match && uris_match; +} diff --git a/axiom/src/soap/soap_header_block.c b/axiom/src/soap/soap_header_block.c new file mode 100644 index 0000000..6f80f3a --- /dev/null +++ b/axiom/src/soap/soap_header_block.c @@ -0,0 +1,460 @@ +/* + * 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_soap_const.h> +#include "_axiom_soap_header_block.h" +#include "_axiom_soap_header.h" +#include <axiom_soap_envelope.h> +#include <axiom_soap_builder.h> + +struct axiom_soap_header_block +{ + + /** om_element node corresponding to this headerblock */ + axiom_node_t *om_ele_node; + + /** soap version */ + int soap_version; + axis2_bool_t processed; +}; + +AXIS2_EXTERN axiom_soap_header_block_t *AXIS2_CALL +axiom_soap_header_block_create( + const axutil_env_t * env) +{ + axiom_soap_header_block_t *header_block = NULL; + AXIS2_ENV_CHECK(env, NULL); + header_block = (axiom_soap_header_block_t *)AXIS2_MALLOC(env->allocator, + sizeof(axiom_soap_header_block_t)); + if(!header_block) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP header block"); + return NULL; + } + + header_block->om_ele_node = NULL; + header_block->soap_version = AXIOM_SOAP_VERSION_NOT_SET; + header_block->processed = AXIS2_FALSE; + + return header_block; +} + +AXIS2_EXTERN axiom_soap_header_block_t *AXIS2_CALL +axiom_soap_header_block_create_with_parent( + const axutil_env_t * env, + const axis2_char_t * localname, + axiom_namespace_t * ns, + axiom_soap_header_t * header) +{ + axiom_soap_header_block_t *header_block = NULL; + axiom_node_t *this_node = NULL; + axiom_node_t *parent_node = NULL; + axiom_element_t *om_ele = NULL; + AXIS2_PARAM_CHECK(env->error, localname, NULL); + + header_block = axiom_soap_header_block_create(env); + if(!header_block) + { + return NULL; + } + parent_node = axiom_soap_header_get_base_node(header, env); + if(!parent_node) + { + return NULL; + } + om_ele = axiom_element_create(env, parent_node, localname, ns, &this_node); + if(!om_ele) + { + axiom_soap_header_block_free(header_block, env); + return NULL; + } + header_block->om_ele_node = this_node; + + axiom_soap_header_set_header_block(header, env, header_block); + + header_block->soap_version = axiom_soap_header_get_soap_version(header, env); + + return header_block; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_soap_header_block_free( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, header_block); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_role( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + axis2_char_t * role_uri) +{ + const axis2_char_t *attr_localname = NULL; + const axis2_char_t *attr_nsuri = NULL; + + if(header_block->soap_version == AXIOM_SOAP_VERSION_NOT_SET) + { + return AXIS2_FAILURE; + } + if(header_block->soap_version == AXIOM_SOAP11) + { + attr_localname = AXIOM_SOAP11_ATTR_ACTOR; + attr_nsuri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + if(header_block->soap_version == AXIOM_SOAP12) + { + attr_localname = AXIOM_SOAP12_SOAP_ROLE; + attr_nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + axiom_soap_header_block_set_attribute(header_block, env, attr_localname, role_uri, attr_nsuri); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL axiom_soap_header_block_get_role( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + const axis2_char_t *attr_localname = NULL; + const axis2_char_t *attr_nsuri = NULL; + + if (header_block->soap_version == AXIOM_SOAP_VERSION_NOT_SET) + { + return NULL; + } + if (header_block->soap_version == AXIOM_SOAP11) + { + attr_localname = AXIOM_SOAP11_ATTR_ACTOR; + attr_nsuri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + if (header_block->soap_version == AXIOM_SOAP12) + { + attr_localname = AXIOM_SOAP12_SOAP_ROLE; + attr_nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + return axiom_soap_header_block_get_attribute(header_block, env, + attr_localname, attr_nsuri); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_must_understand_with_bool( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + axis2_bool_t must_understand) +{ + const axis2_char_t *attr_nsuri = NULL; + const axis2_char_t *attr_value = NULL; + + if(header_block->soap_version == AXIOM_SOAP_VERSION_NOT_SET) + { + return AXIS2_FAILURE; + } + if(header_block->soap_version == AXIOM_SOAP11) + { + attr_nsuri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + if(header_block->soap_version == AXIOM_SOAP12) + { + attr_nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + if(must_understand) + { + attr_value = "1"; + } + else + { + attr_value = "0"; + } + return axiom_soap_header_block_set_attribute(header_block, env, + AXIOM_SOAP_ATTR_MUST_UNDERSTAND, attr_value, attr_nsuri); + +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_must_understand_with_string( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + axis2_char_t * must_understand) +{ + const axis2_char_t *attr_nsuri = NULL; + + AXIS2_PARAM_CHECK(env->error, must_understand, AXIS2_FAILURE); + + if(header_block->soap_version == AXIOM_SOAP_VERSION_NOT_SET) + { + return AXIS2_FAILURE; + } + if(header_block->soap_version == AXIOM_SOAP11) + { + attr_nsuri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + if(header_block->soap_version == AXIOM_SOAP12) + { + attr_nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + + if(axutil_strcmp(AXIOM_SOAP_ATTR_MUST_UNDERSTAND_TRUE, must_understand) == 0 || axutil_strcmp( + AXIOM_SOAP_ATTR_MUST_UNDERSTAND_FALSE, must_understand) == 0 || axutil_strcmp( + AXIOM_SOAP_ATTR_MUST_UNDERSTAND_0, must_understand) == 0 || axutil_strcmp( + AXIOM_SOAP_ATTR_MUST_UNDERSTAND_1, must_understand) == 0) + { + + axiom_soap_header_block_set_attribute(header_block, env, AXIOM_SOAP_ATTR_MUST_UNDERSTAND, + must_understand, attr_nsuri); + return AXIS2_SUCCESS; + } + else + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_MUST_UNDERSTAND_SHOULD_BE_1_0_TRUE_FALSE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_soap_header_block_get_must_understand( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + const axis2_char_t *must_understand = NULL; + const axis2_char_t *attr_nsuri = NULL; + + if(header_block->soap_version == AXIOM_SOAP_VERSION_NOT_SET) + { + return AXIS2_FAILURE; + } + if(header_block->soap_version == AXIOM_SOAP11) + { + attr_nsuri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + if(header_block->soap_version == AXIOM_SOAP12) + { + attr_nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + must_understand = axiom_soap_header_block_get_attribute(header_block, env, + AXIOM_SOAP_ATTR_MUST_UNDERSTAND, attr_nsuri); + if(!must_understand) + { + return AXIS2_FALSE; + } + if(axutil_strcmp(must_understand, AXIOM_SOAP_ATTR_MUST_UNDERSTAND_1) == 0 || axutil_strcmp( + must_understand, AXIOM_SOAP_ATTR_MUST_UNDERSTAND_TRUE) == 0) + { + return AXIS2_TRUE; + } + else if(axutil_strcmp(must_understand, AXIOM_SOAP_ATTR_MUST_UNDERSTAND_0) == 0 + || axutil_strcmp(must_understand, AXIOM_SOAP_ATTR_MUST_UNDERSTAND_FALSE) == 0) + { + return AXIS2_FALSE; + } + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_VALUE_FOUND_IN_MUST_UNDERSTAND, AXIS2_FAILURE); + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_attribute( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + const axis2_char_t * attr_name, + const axis2_char_t * attr_value, + const axis2_char_t * soap_envelope_namespace_uri) +{ + axiom_attribute_t *om_attr = NULL; + axiom_node_t *header_node = NULL; + axiom_element_t *header_ele = NULL; + axiom_namespace_t *header_ns = NULL; + axis2_char_t *prefix = NULL; + axutil_qname_t *qn = NULL; + axiom_namespace_t *om_ns = NULL; + axiom_element_t *om_ele = NULL; + + AXIS2_PARAM_CHECK(env->error, attr_name, AXIS2_FAILURE); + + header_node = axiom_node_get_parent(header_block->om_ele_node, env); + if(!header_node) + { + return AXIS2_FAILURE; + } + if(axiom_node_get_node_type(header_node, env) == AXIOM_ELEMENT) + { + header_ele = (axiom_element_t *)axiom_node_get_data_element(header_node, env); + if(!header_ele) + { + return AXIS2_FAILURE; + } + header_ns = axiom_element_get_namespace(header_ele, env, header_node); + if(!header_ns) + { + return AXIS2_FAILURE; + } + prefix = axiom_namespace_get_prefix(header_ns, env); + } + + qn = axutil_qname_create(env, attr_name, soap_envelope_namespace_uri, prefix); + + if(!qn) + { + return AXIS2_FAILURE; + } + if(!header_block->om_ele_node) + { + return AXIS2_FAILURE; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(header_block-> om_ele_node, env); + + om_attr = axiom_element_get_attribute(om_ele, env, qn); + + axutil_qname_free(qn, env); + if(om_attr) + { + return axiom_attribute_set_value(om_attr, env, attr_value); + } + if(soap_envelope_namespace_uri) + { + if(prefix) + { + om_ns = axiom_namespace_create(env, soap_envelope_namespace_uri, prefix); + } + else + { + om_ns = axiom_namespace_create(env, soap_envelope_namespace_uri, + AXIOM_SOAP_DEFAULT_NAMESPACE_PREFIX); + } + } + om_attr = axiom_attribute_create(env, attr_name, attr_value, om_ns); + if(!om_attr && om_ns) + { + axiom_namespace_free(om_ns, env); + return AXIS2_FAILURE; + } + + return axiom_element_add_attribute(om_ele, env, om_attr, header_block->om_ele_node); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_soap_header_block_get_attribute( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + const axis2_char_t * attr_name, + const axis2_char_t * soap_envelope_namespace_uri) +{ + axiom_attribute_t *om_attr = NULL; + axis2_char_t *attr_value = NULL; + axiom_node_t *header_node = NULL; + axiom_element_t *header_ele = NULL; + axiom_namespace_t *header_ns = NULL; + axis2_char_t *prefix = NULL; + axutil_qname_t *qn = NULL; + axiom_element_t *om_ele = NULL; + AXIS2_PARAM_CHECK(env->error, attr_name, NULL); + AXIS2_PARAM_CHECK(env->error, soap_envelope_namespace_uri, NULL); + + header_node = axiom_node_get_parent(header_block->om_ele_node, env); + if(!header_node) + { + return NULL; + } + if(axiom_node_get_node_type(header_node, env) == AXIOM_ELEMENT) + { + header_ele = (axiom_element_t *)axiom_node_get_data_element(header_node, env); + if(!header_ele) + { + return NULL; + } + header_ns = axiom_element_get_namespace(header_ele, env, header_node); + if(!header_ns) + { + return NULL; + } + prefix = axiom_namespace_get_prefix(header_ns, env); + } + qn = axutil_qname_create(env, attr_name, soap_envelope_namespace_uri, prefix); + if(!qn) + { + return NULL; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(header_block-> om_ele_node, env); + om_attr = axiom_element_get_attribute(om_ele, env, qn); + if(om_attr) + { + attr_value = axiom_attribute_get_value(om_attr, env); + } + axutil_qname_free(qn, env); + return attr_value; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_soap_header_block_is_processed( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + return header_block->processed; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_processed( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + header_block->processed = AXIS2_TRUE; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_base_node( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + axiom_node_t * node) +{ + AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE); + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE); + return AXIS2_FAILURE; + } + header_block->om_ele_node = node; + return AXIS2_SUCCESS; + +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_soap_header_block_get_base_node( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + return header_block->om_ele_node; +} + +AXIS2_EXTERN int AXIS2_CALL axiom_soap_header_block_get_soap_version( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env) +{ + return header_block->soap_version; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axiom_soap_header_block_set_soap_version( + axiom_soap_header_block_t * header_block, + const axutil_env_t * env, + int soap_version) +{ + + header_block->soap_version = soap_version; + return AXIS2_SUCCESS; +} diff --git a/axiom/src/util/Makefile.am b/axiom/src/util/Makefile.am new file mode 100644 index 0000000..ea76b68 --- /dev/null +++ b/axiom/src/util/Makefile.am @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = libaxis2_axiom_util.la +libaxis2_axiom_util_la_SOURCES = om_util.c + +libaxis2_axiom_util_la_LIBADD = +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/parser \ + -I$(top_builddir)/src/om \ + -I ../../../util/include diff --git a/axiom/src/util/om_util.c b/axiom/src/util/om_util.c new file mode 100644 index 0000000..fcdd90b --- /dev/null +++ b/axiom/src/util/om_util.c @@ -0,0 +1,1181 @@ +/* + * 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_node.h> +#include <axiom_element.h> +#include <axiom_document.h> +#include <axutil_array_list.h> +#include <axutil_uri.h> +#include <axiom_util.h> + + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_util_get_child_text( + axiom_node_t *node, + const axutil_env_t * env) +{ + axiom_element_t *ele = NULL; + axis2_char_t *txt = NULL; + + ele = (axiom_element_t*)axiom_node_get_data_element(node, env); + txt = axiom_element_get_text(ele, env, node); + + return txt; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_first_child_element_with_uri( + axiom_node_t * ele_node, + const axutil_env_t * env, + axis2_char_t * uri, + axiom_node_t ** child) +{ + axiom_node_t *child_node = NULL; + + if(!ele_node || !uri) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Element node or uri is NULL"); + return NULL; + } + + child_node = axiom_node_get_first_child(ele_node, env); + while(child_node) + { + if(axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT) + { + axiom_element_t *child_ele = NULL; + axiom_namespace_t *ns = NULL; + + child_ele = (axiom_element_t *)axiom_node_get_data_element(child_node, env); + ns = axiom_element_get_namespace(child_ele, env, child_node); + if(ns) + { + axis2_char_t *child_uri = NULL; + child_uri = axiom_namespace_get_uri(ns, env); + if(child_uri && axutil_strcmp(child_uri, uri) == 0) + { + (*child) = child_node; + return child_ele; + } + } + } + child_node = axiom_node_get_next_sibling(child_node, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_next_sibling_element_with_uri( + axiom_node_t * ele_node, + const axutil_env_t * env, + axis2_char_t * uri, + axiom_node_t ** next_node) +{ + axiom_node_t *next_sib_node = NULL; + if(!ele_node || !uri) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Element node or uri is NULL"); + return NULL; + } + + next_sib_node = axiom_node_get_next_sibling(ele_node, env); + while(next_sib_node) + { + if(axiom_node_get_node_type(next_sib_node, env) == AXIOM_ELEMENT) + { + axiom_element_t *sib_ele = NULL; + axiom_namespace_t *ns = NULL; + + sib_ele = (axiom_element_t *)axiom_node_get_data_element(next_sib_node, env); + ns = axiom_element_get_namespace(sib_ele, env, next_sib_node); + if(ns) + { + axis2_char_t *sib_uri = NULL; + sib_uri = axiom_namespace_get_uri(ns, env); + if(sib_uri && axutil_strcmp(sib_uri, uri) == 0) + { + (*next_node) = next_sib_node; + return sib_ele; + } + } + } + next_sib_node = axiom_node_get_next_sibling(next_sib_node, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_first_child_element( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axiom_node_t ** child_node) +{ + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + + return axiom_element_get_first_element(ele, env, ele_node, child_node); +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_last_child_element( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axiom_node_t ** child_node) +{ + axiom_node_t *last_node = NULL; + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + + last_node = axiom_node_get_last_child(ele_node, env); + while(last_node) + { + if(axiom_node_get_node_type(last_node, env) == AXIOM_ELEMENT) + { + *child_node = last_node; + return (axiom_element_t *)axiom_node_get_data_element(last_node, env); + + } + last_node = axiom_node_get_previous_sibling(ele_node, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_next_sibling_element( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axiom_node_t ** next_node) +{ + axiom_node_t *next_sibling = NULL; + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + + next_sibling = axiom_node_get_next_sibling(ele_node, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + *next_node = next_sibling; + return (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_first_child_element_with_localname( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_node_t *next_sibling = NULL; + axis2_char_t *child_localname = NULL; + axiom_element_t *om_ele = NULL; + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + AXIS2_PARAM_CHECK(env->error, localname, NULL); + + child = axiom_node_get_first_child(ele_node, env); + if(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(child, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && axutil_strcmp(child_localname, localname) == 0) + { + *child_node = child; + return om_ele; + } + } + } + om_ele = NULL; + child_localname = NULL; + } + + next_sibling = axiom_node_get_next_sibling(child, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && axutil_strcmp(child_localname, localname) == 0) + { + *child_node = next_sibling; + return om_ele; + } + + } + om_ele = NULL; + child_localname = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_last_child_element_with_localname( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *child_localname = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, localname, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + + child = axiom_node_get_last_child(ele_node, env); + while(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(ele_node, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && axutil_strcmp(child_localname, localname) == 0) + { + *child_node = child; + return om_ele; + } + + } + om_ele = NULL; + child_localname = NULL; + } + child = axiom_node_get_previous_sibling(child, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_next_siblng_element_with_localname( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axiom_node_t ** next_node) +{ + axiom_node_t *next_sibling = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *ele_localname = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + + next_sibling = axiom_node_get_next_sibling(ele_node, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + ele_localname = axiom_element_get_localname(om_ele, env); + if(ele_localname && axutil_strcmp(localname, ele_localname) == 0) + { + *next_node = next_sibling; + return om_ele; + } + } + om_ele = NULL; + ele_localname = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_first_child_element_with_uri_localname( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axis2_char_t * uri, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_node_t *next_sibling = NULL; + axis2_char_t *child_localname = NULL; + axiom_element_t *om_ele = NULL; + axiom_namespace_t *ns = NULL; + axis2_char_t *ns_uri = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + AXIS2_PARAM_CHECK(env->error, localname, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + + child = axiom_node_get_first_child(ele_node, env); + if(!child) + { + return NULL; + + } + if(axiom_node_get_node_type(ele_node, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(child, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + ns = axiom_element_get_namespace(om_ele, env, child); + if(ns) + { + ns_uri = axiom_namespace_get_uri(ns, env); + } + + if((child_localname) && (axutil_strcmp(child_localname, localname) == 0) && (ns_uri) + && (axutil_strcmp(ns_uri, uri) == 0)) + { + *child_node = child; + return om_ele; + } + } + } + om_ele = NULL; + child_localname = NULL; + ns = NULL; + ns_uri = NULL; + + next_sibling = axiom_node_get_next_sibling(child, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + ns = axiom_element_get_namespace(om_ele, env, next_sibling); + if(ns) + { + ns_uri = axiom_namespace_get_uri(ns, env); + } + + if((child_localname) && (axutil_strcmp(child_localname, localname) == 0) + && (ns_uri) && (axutil_strcmp(ns_uri, uri) == 0)) + { + *child_node = next_sibling; + return om_ele; + } + + } + om_ele = NULL; + child_localname = NULL; + ns = NULL; + ns_uri = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_last_child_element_with_uri_localname( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axis2_char_t * uri, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *child_localname = NULL; + axiom_namespace_t *ns = NULL; + axis2_char_t *ns_uri = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, localname, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + AXIS2_PARAM_CHECK(env->error, uri, NULL); + + child = axiom_node_get_last_child(ele_node, env); + while(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(ele_node, env); + if(om_ele) + { + ns = axiom_element_get_namespace(om_ele, env, ele_node); + if(ns) + { + ns_uri = axiom_namespace_get_uri(ns, env); + } + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && (axutil_strcmp(child_localname, localname) == 0) && (ns_uri) + && (axutil_strcmp(ns_uri, uri) == 0)) + { + *child_node = child; + return om_ele; + } + } + om_ele = NULL; + child_localname = NULL; + ns = NULL; + ns_uri = NULL; + } + child = axiom_node_get_previous_sibling(child, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_next_sibling_element_with_uri_localname( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axis2_char_t * uri, + axiom_node_t ** next_node) +{ + axiom_node_t *next_sibling = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *ele_localname = NULL; + axiom_namespace_t *ns = NULL; + axis2_char_t *ns_uri = NULL; + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + + next_sibling = axiom_node_get_next_sibling(ele_node, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + ns = axiom_element_get_namespace(om_ele, env, next_sibling); + if(ns) + { + ns_uri = axiom_namespace_get_uri(ns, env); + } + ele_localname = axiom_element_get_localname(om_ele, env); + if(ele_localname && (axutil_strcmp(localname, ele_localname) == 0) && (ns) + && (axutil_strcmp(ns_uri, uri) == 0)) + { + *next_node = next_sibling; + return om_ele; + } + } + om_ele = NULL; + ele_localname = NULL; + ns_uri = NULL; + ns = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_first_child_element_with_localnames( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axutil_array_list_t * names, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_node_t *next_sibling = NULL; + axis2_char_t *child_localname = NULL; + axis2_char_t *given_localname = NULL; + axiom_element_t *om_ele = NULL; + int size = 0; + int i = 0; + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + AXIS2_PARAM_CHECK(env->error, names, NULL); + + child = axiom_node_get_first_child(ele_node, env); + if(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(child, env); + if(om_ele) + { + size = axutil_array_list_size(names, env); + child_localname = axiom_element_get_localname(om_ele, env); + + for(i = 0; i < size; i++) + { + given_localname = (axis2_char_t *)axutil_array_list_get(names, env, i); + + if((child_localname) && (NULL != given_localname) && axutil_strcmp( + child_localname, given_localname) == 0) + { + *child_node = child; + return om_ele; + } + given_localname = NULL; + } + } + } + om_ele = NULL; + child_localname = NULL; + given_localname = NULL; + size = 0; + } + + next_sibling = axiom_node_get_next_sibling(child, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + size = axutil_array_list_size(names, env); + child_localname = axiom_element_get_localname(om_ele, env); + for(i = 0; i < size; i++) + { + given_localname = (axis2_char_t *)axutil_array_list_get(names, env, i); + if((child_localname) && (NULL != given_localname) && (axutil_strcmp( + child_localname, given_localname) == 0)) + { + *child_node = next_sibling; + return om_ele; + } + given_localname = NULL; + } + } + om_ele = NULL; + child_localname = NULL; + given_localname = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; + +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_last_child_element_with_localnames( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axutil_array_list_t * names, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *child_localname = NULL; + axis2_char_t *given_localname = NULL; + int size = 0; + int i = 0; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, names, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + + child = axiom_node_get_last_child(ele_node, env); + while(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(ele_node, env); + if(om_ele) + { + size = axutil_array_list_size(names, env); + for(i = 0; i < size; i++) + { + given_localname = (axis2_char_t *)axutil_array_list_get(names, env, i); + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && (NULL != given_localname) && (axutil_strcmp( + child_localname, given_localname) == 0)) + { + *child_node = child; + return om_ele; + } + } + } + om_ele = NULL; + child_localname = NULL; + given_localname = NULL; + } + child = axiom_node_get_previous_sibling(child, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_next_siblng_element_with_localnames( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axutil_array_list_t * names, + axiom_node_t ** next_node) +{ + axiom_node_t *next_sibling = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *ele_localname = NULL; + axis2_char_t *given_localname = NULL; + int size = 0; + int i = 0; + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, names, NULL); + AXIS2_PARAM_CHECK(env->error, next_node, NULL); + + next_sibling = axiom_node_get_next_sibling(ele_node, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + size = axutil_array_list_size(names, env); + for(i = 0; i < size; i++) + { + given_localname = (axis2_char_t *)axutil_array_list_get(names, env, i); + ele_localname = axiom_element_get_localname(om_ele, env); + if((ele_localname) && (NULL != given_localname) && (axutil_strcmp( + given_localname, ele_localname) == 0)) + { + *next_node = next_sibling; + return om_ele; + } + + } + } + om_ele = NULL; + ele_localname = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_first_child_element_with_localname_attr( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axis2_char_t * attr_name, + axis2_char_t * attr_value, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_node_t *next_sibling = NULL; + axis2_char_t *child_localname = NULL; + axiom_element_t *om_ele = NULL; + axiom_attribute_t *om_attr = NULL; + axutil_hash_t *attr_ht = NULL; + axutil_hash_index_t *hi = NULL; + axis2_char_t *om_attr_value = NULL; + axis2_char_t *om_attr_name = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + AXIS2_PARAM_CHECK(env->error, localname, NULL); + AXIS2_PARAM_CHECK(env->error, attr_name, NULL); + AXIS2_PARAM_CHECK(env->error, attr_value, NULL); + + child = axiom_node_get_first_child(ele_node, env); + + if(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(child, env); + if(om_ele) + { + + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && axutil_strcmp(child_localname, localname) == 0) + { + attr_ht = axiom_element_get_all_attributes(om_ele, env); + if(attr_ht) + { + for(hi = axutil_hash_first(attr_ht, env); hi; hi + = axutil_hash_next(env, hi)) + { + void *val = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + om_attr = (axiom_attribute_t *)val; + om_attr_name = axiom_attribute_get_localname(om_attr, env); + + om_attr_value = axiom_attribute_get_value(om_attr, env); + if(om_attr_name && NULL != om_attr_value && axutil_strcmp( + om_attr_name, attr_name) == 0 && axutil_strcmp(om_attr_value, + attr_value) == 0) + { + AXIS2_FREE(env->allocator, hi); + *child_node = child; + return om_ele; + } + om_attr = NULL; + om_attr_name = NULL; + om_attr_value = NULL; + } + } + } + } + } + } + om_ele = NULL; + child_localname = NULL; + hi = NULL; + } + + next_sibling = axiom_node_get_next_sibling(child, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && axutil_strcmp(child_localname, localname) == 0) + { + attr_ht = axiom_element_get_all_attributes(om_ele, env); + if(attr_ht) + { + + for(hi = axutil_hash_first(attr_ht, env); hi; hi + = axutil_hash_next(env, hi)) + { + void *val = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + om_attr = (axiom_attribute_t *)val; + om_attr_name = axiom_attribute_get_localname(om_attr, env); + + om_attr_value = axiom_attribute_get_value(om_attr, env); + + if(om_attr_name && NULL != om_attr_value && axutil_strcmp( + om_attr_name, attr_name) == 0 && axutil_strcmp(om_attr_value, + attr_value) == 0) + { + *child_node = child; + return om_ele; + } + om_attr = NULL; + om_attr_name = NULL; + om_attr_value = NULL; + } + } + } + } + + } + om_ele = NULL; + child_localname = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_last_child_element_with_localname_attr( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axis2_char_t * attr_name, + axis2_char_t * attr_value, + axiom_node_t ** child_node) +{ + axiom_node_t *child = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *child_localname = NULL; + axiom_attribute_t *om_attr = NULL; + axis2_char_t *om_attr_name = NULL; + axis2_char_t *om_attr_value = NULL; + axutil_hash_index_t *hi = NULL; + axutil_hash_t *attr_ht = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + AXIS2_PARAM_CHECK(env->error, localname, NULL); + AXIS2_PARAM_CHECK(env->error, child_node, NULL); + + child = axiom_node_get_last_child(ele_node, env); + while(child) + { + if(axiom_node_get_node_type(child, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(ele_node, env); + if(om_ele) + { + child_localname = axiom_element_get_localname(om_ele, env); + if(child_localname && axutil_strcmp(child_localname, localname) == 0) + { + attr_ht = axiom_element_get_all_attributes(om_ele, env); + if(attr_ht) + { + for(hi = axutil_hash_first(attr_ht, env); hi; hi + = axutil_hash_next(env, hi)) + { + void *val = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + om_attr = (axiom_attribute_t *)val; + om_attr_name = axiom_attribute_get_localname(om_attr, env); + + om_attr_value = axiom_attribute_get_value(om_attr, env); + + if(om_attr_name && NULL != om_attr_value && axutil_strcmp( + om_attr_name, attr_name) == 0 && axutil_strcmp(om_attr_value, + attr_value) == 0) + { + AXIS2_FREE(env->allocator, hi); + *child_node = child; + return om_ele; + } + om_attr = NULL; + om_attr_name = NULL; + om_attr_value = NULL; + } + } + } + } + + } + om_ele = NULL; + child_localname = NULL; + } + child = axiom_node_get_previous_sibling(child, env); + } + return NULL; +} + +AXIS2_EXTERN axiom_element_t *AXIS2_CALL +axiom_util_get_next_siblng_element_with_localname_attr( + axiom_element_t * ele, + const axutil_env_t * env, + axiom_node_t * ele_node, + axis2_char_t * localname, + axis2_char_t * attr_name, + axis2_char_t * attr_value, + axiom_node_t ** child_node) +{ + axiom_node_t *next_sibling = NULL; + axiom_element_t *om_ele = NULL; + axis2_char_t *ele_localname = NULL; + axiom_attribute_t *om_attr = NULL; + axis2_char_t *om_attr_value = NULL; + axis2_char_t *om_attr_name = NULL; + axutil_hash_t *attr_ht = NULL; + axutil_hash_index_t *hi = NULL; + + AXIS2_PARAM_CHECK(env->error, ele_node, NULL); + + next_sibling = axiom_node_get_next_sibling(ele_node, env); + while(next_sibling) + { + if(axiom_node_get_node_type(next_sibling, env) == AXIOM_ELEMENT) + { + om_ele = (axiom_element_t *)axiom_node_get_data_element(next_sibling, env); + if(om_ele) + { + ele_localname = axiom_element_get_localname(om_ele, env); + if(ele_localname && axutil_strcmp(localname, ele_localname) == 0) + { + attr_ht = axiom_element_get_all_attributes(om_ele, env); + if(attr_ht) + { + for(hi = axutil_hash_first(attr_ht, env); hi; hi + = axutil_hash_next(env, hi)) + { + void *val = NULL; + axutil_hash_this(hi, NULL, NULL, &val); + if(val) + { + om_attr = (axiom_attribute_t *)val; + om_attr_name = axiom_attribute_get_localname(om_attr, env); + + om_attr_value = axiom_attribute_get_value(om_attr, env); + + if(om_attr_name && NULL != om_attr_value && axutil_strcmp( + om_attr_name, attr_name) == 0 && axutil_strcmp(om_attr_value, + attr_value) == 0) + { + AXIS2_FREE(env->allocator, hi); + *child_node = next_sibling; + return om_ele; + } + om_attr = NULL; + om_attr_name = NULL; + om_attr_value = NULL; + } + } + } + } + } + om_ele = NULL; + ele_localname = NULL; + } + next_sibling = axiom_node_get_next_sibling(next_sibling, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_util_get_child_node_text( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + if(!om_node) + { + return NULL; + } + if(axiom_node_get_node_type(om_node, env) != AXIOM_ELEMENT) + { + return NULL; + } + + om_ele = (axiom_element_t *)axiom_node_get_data_element(om_node, env); + + if(om_ele) + { + return axiom_element_get_text(om_ele, env, om_node); + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_util_get_localname( + axiom_node_t * node, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if(!node) + { + return NULL; + } + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + return NULL; + } + om_ele = (axiom_element_t *)axiom_node_get_data_element(node, env); + if(om_ele) + { + return axiom_element_get_localname(om_ele, env); + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axiom_util_get_node_namespace_uri( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axiom_element_t *om_ele = NULL; + axiom_namespace_t *om_ns = NULL; + if(!om_node) + { + return NULL; + } + if(axiom_node_get_node_type(om_node, env) == AXIOM_ELEMENT) + { + om_ele = axiom_node_get_data_element(om_node, env); + if(!om_ele) + { + return NULL; + } + om_ns = axiom_element_get_namespace(om_ele, env, om_node); + if(om_ns) + { + return axiom_namespace_get_uri(om_ns, env); + } + } + return NULL; +} + +AXIS2_EXTERN axiom_child_element_iterator_t *AXIS2_CALL +axiom_util_get_child_elements( + axiom_element_t * om_ele, + const axutil_env_t * env, + axiom_node_t * om_node) +{ + axiom_element_t *first_ele = NULL; + axiom_node_t *first_node = NULL; + AXIS2_PARAM_CHECK(env->error, om_node, NULL); + AXIS2_PARAM_CHECK(env->error, om_ele, NULL); + first_ele = axiom_element_get_first_element(om_ele, env, om_node, &first_node); + if(first_ele) + { + return axiom_child_element_iterator_create(env, first_node); + } + return NULL; +} + +AXIS2_EXTERN axiom_document_t *AXIS2_CALL +axiom_util_new_document( + const axutil_env_t * env, + const axutil_uri_t * uri) +{ + axis2_char_t *path = NULL; + axiom_xml_reader_t *reader = NULL; + axiom_stax_builder_t *om_builder = NULL; + axiom_document_t *doc = NULL; + + AXIS2_PARAM_CHECK(env->error, uri, NULL); + /* This is temporary code. Later complete the code to read from uri and build + * the document + */ + if(uri) + { + path = axutil_uri_get_path((axutil_uri_t *)uri, env); + } + else + { + return NULL; + } + if(path) + { + reader = axiom_xml_reader_create_for_file(env, path, NULL); + } + else + { + return NULL; + } + if(reader) + { + om_builder = axiom_stax_builder_create(env, reader); + } + else + { + return NULL; + } + if(om_builder) + { + doc = axiom_stax_builder_get_document(om_builder, env); + } + else + { + return NULL; + } + if(doc) + { + axiom_document_build_all(doc, env); + } + else + { + return NULL; + } + + return doc; +} + +AXIS2_EXTERN axiom_node_t* AXIS2_CALL +axiom_util_get_node_by_local_name( + const axutil_env_t *env, + axiom_node_t *node, + axis2_char_t *local_name) +{ + axis2_char_t *temp_name = NULL; + + if(!node) + { + return NULL; + } + + if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + { + return NULL; + } + + temp_name = axiom_util_get_localname(node, env); + AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[rampart]Checking node %s for %s", temp_name, + local_name); + + if(!axutil_strcmp(temp_name, local_name)) + { + /* Gottcha.. return this node */ + return node; + } + else + { + /* Doesn't match? Get the children and search for them */ + axiom_node_t *temp_node = NULL; + + temp_node = axiom_node_get_first_element(node, env); + while(temp_node) + { + axiom_node_t *res_node = NULL; + res_node = axiom_util_get_node_by_local_name(env, temp_node, local_name); + if(res_node) + { + return res_node; + } + temp_node = axiom_node_get_next_sibling(temp_node, env); + } + } + return NULL; +} + +/** + * Creates a clone of given node + * @param env environment, MUST not be NULL + * @param node node to be cloned + * @return cloned node + */ +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_util_clone_node( + const axutil_env_t *env, + axiom_node_t *node) +{ + axis2_char_t* node_string = NULL; + axiom_node_t *clone = NULL; + + if(!node) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Could not be able to clone the node. Given node is not valid."); + return NULL; + } + + node_string = axiom_node_sub_tree_to_string(node, env); + clone = axiom_node_create_from_buffer(env, node_string); + + if(node_string) + { + AXIS2_FREE(env->allocator, node_string); + } + + return clone; +} diff --git a/axiom/src/xpath/Makefile.am b/axiom/src/xpath/Makefile.am new file mode 100644 index 0000000..5d4f42f --- /dev/null +++ b/axiom/src/xpath/Makefile.am @@ -0,0 +1,22 @@ +lib_LTLIBRARIES = libaxis2_xpath.la +libaxis2_xpath_la_SOURCES = xpath.c \ + xpath_functions.c \ + xpath_internals.c \ + xpath_internals_engine.c \ + xpath_internals_iterators.c \ + xpath_internals_parser.c \ + xpath_streaming.c + +libaxis2_xpath_la_LDFLAGS = -version-info $(VERSION_NO) + +libaxis2_xpath_la_LIBADD = +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/parser \ + -I$(top_builddir)/src/om \ + -I ../../../util/include \ + -I ../../../include + +EXTRA_DIST = xpath_functions.h xpath_internals_engine.h \ + xpath_internals.h xpath_internals_iterators.h \ + xpath_internals_parser.h xpath_streaming.h + diff --git a/axiom/src/xpath/xpath.c b/axiom/src/xpath/xpath.c new file mode 100755 index 0000000..38f422c --- /dev/null +++ b/axiom/src/xpath/xpath.c @@ -0,0 +1,462 @@ +/* + * 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_xpath.h> +#include "xpath_internals.h" +#include "xpath_internals_parser.h" +#include "xpath_internals_engine.h" +#include "xpath_functions.h" +#include "xpath_streaming.h" + +/* Create XPath context */ +AXIS2_EXTERN axiom_xpath_context_t * AXIS2_CALL +axiom_xpath_context_create( + const axutil_env_t *env, + axiom_node_t * root_node) +{ + axiom_xpath_context_t* context; + + /*HACK: xpath impl requires a dummy root node in order to process properly.*/ + axiom_node_t * dummy_root; + dummy_root = axiom_node_create(env); + axiom_node_add_child(dummy_root, env, root_node); + + context = AXIS2_MALLOC(env->allocator, + sizeof(axiom_xpath_context_t)); + + context->env = env; + context->root_node = dummy_root; + context->node = dummy_root; + context->expr = NULL; + context->attribute = NULL; + context->namespaces = NULL; + context->functions = NULL; + + axiom_xpath_register_default_functions_set(context); + + return context; +} + +/* Compile XPath expression */ +AXIS2_EXTERN axiom_xpath_expression_t * AXIS2_CALL +axiom_xpath_compile_expression( + const axutil_env_t *env, + const axis2_char_t* xpath_expr) +{ + axiom_xpath_expression_t* expr; + + expr = AXIS2_MALLOC(env->allocator, + sizeof(axiom_xpath_expression_t)); + + expr->expr_str = axutil_strdup(env, xpath_expr); + + if (axiom_xpath_compile(env, expr) == AXIOM_XPATH_PARSE_ERROR) + { + AXIS2_FREE(env->allocator, expr->expr_str); + AXIS2_FREE(env->allocator, expr); + + return NULL; + } + else + { + return expr; + } +} + +/* Evaluate compiled XPath expression */ +AXIS2_EXTERN axiom_xpath_result_t * AXIS2_CALL +axiom_xpath_evaluate( + axiom_xpath_context_t *context, + axiom_xpath_expression_t *xpath_expr) +{ + axiom_xpath_expression_copy(context, xpath_expr); + + context->streaming = AXIS2_FALSE; + + return axiom_xpath_run(context); +} + +AXIS2_EXTERN axiom_xpath_result_t * AXIS2_CALL +axiom_xpath_evaluate_streaming( + axiom_xpath_context_t *context, + axiom_xpath_expression_t *xpath_expr) +{ + axiom_xpath_result_t *res; + + axiom_xpath_expression_copy(context, xpath_expr); + + if (axiom_xpath_streaming_check(context->env, xpath_expr)) + { + context->streaming = AXIS2_TRUE; + return axiom_xpath_run(context); + } + else + { + res = AXIS2_MALLOC( + context->env->allocator, sizeof(axiom_xpath_result_t)); + res->nodes = NULL; + res->flag = AXIOM_XPATH_ERROR_STREAMING_NOT_SUPPORTED; + + return res; + } +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_register_default_functions_set( + axiom_xpath_context_t *context) +{ + axiom_xpath_register_function( + context, "count", axiom_xpath_function_count); +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_register_function( + axiom_xpath_context_t *context, + axis2_char_t *name, + axiom_xpath_function_t func) +{ + if (name && func) + { + if (!context->functions) + { + context->functions = axutil_hash_make(context->env); + } + + axutil_hash_set(context->functions, name, AXIS2_HASH_KEY_STRING, func); + } +} + +AXIS2_EXTERN axiom_xpath_function_t AXIS2_CALL +axiom_xpath_get_function( + axiom_xpath_context_t *context, + axis2_char_t *name) +{ + axiom_xpath_function_t func = NULL; + + if(context->functions) + { + func = axutil_hash_get(context->functions, name, AXIS2_HASH_KEY_STRING); + } + + return func; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_register_namespace( + axiom_xpath_context_t *context, + axiom_namespace_t *ns) +{ + axis2_char_t *prefix = NULL; + + if (!context->namespaces) + { + context->namespaces = axutil_hash_make(context->env); + } + + prefix = axiom_namespace_get_prefix(ns, context->env); + + if (prefix) + { + axutil_hash_set( + context->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns); + } +} + +AXIS2_EXTERN axiom_namespace_t * AXIS2_CALL +axiom_xpath_get_namespace( + axiom_xpath_context_t *context, + axis2_char_t *prefix) +{ + axiom_namespace_t *ns = NULL; + + if (context->namespaces) + { + ns = axutil_hash_get(context->namespaces, prefix, AXIS2_HASH_KEY_STRING); + } + + return ns; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_clear_namespaces( + axiom_xpath_context_t *context) +{ + axutil_hash_index_t *hi; + void *val; + + if (context->namespaces) + { + for (hi = axutil_hash_first(context->namespaces, context->env); + hi; + hi = axutil_hash_next(context->env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + axiom_namespace_free((axiom_namespace_t *)val, context->env); + } + + axutil_hash_free(context->namespaces, context->env); + } + + context->namespaces = NULL; +} + +/* Cast to boolean */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_xpath_cast_node_to_boolean( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + if(node->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + return *(axis2_bool_t *)node->value; + } + else if(node->type == AXIOM_XPATH_TYPE_NUMBER) + { + /* Cannot evaluate as *(double *)(node->value) == 1e-12 + since there might be an precision error */ + if(*(double *)(node->value) > 1e-12 || *(double *)(node->value) < -1e-12) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + else if(node->value) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } +} + +/* Cast to double */ +AXIS2_EXTERN double AXIS2_CALL +axiom_xpath_cast_node_to_number( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + if (node->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + if (*(axis2_bool_t *)(node->value) == AXIS2_TRUE) + { + return 1.0; + } + else + { + return 0.0; + } + } + else if (node->type == AXIOM_XPATH_TYPE_NUMBER) + { + return *(double *)node->value; + } + else if (node->value) + { + return 1.0; + } + else + { + return 0.0; + } +} + +/* Cast to text */ +AXIS2_EXTERN axis2_char_t * AXIS2_CALL +axiom_xpath_cast_node_to_string( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + axiom_element_t *ele; + axis2_char_t *res; + + if (!node->value) + { + return NULL; + } + + if (node->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + if (*(axis2_bool_t *)(node->value) == AXIS2_TRUE) + { + return axutil_strdup(env, "true"); + } + else + { + return axutil_strdup(env, "false"); + } + } + else if (node->type == AXIOM_XPATH_TYPE_NUMBER) + { + /* Allocate 50 bytes */ + res = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 50); + + sprintf(res, "%lf", *(double *)(node->value)); + + return res; + } + else if (node->type == AXIOM_XPATH_TYPE_TEXT) + { + return (axis2_char_t *)node->value; + } + else if (node->type == AXIOM_XPATH_TYPE_NODE) + { + ele = (axiom_element_t *)axiom_node_get_data_element( + (axiom_node_t *)(node->value), env); + + if (ele) + { + return axiom_element_get_text( + ele, env, (axiom_node_t *)(node->value)); + } + else + { + return NULL; + } + } + else if (node->type == AXIOM_XPATH_TYPE_ATTRIBUTE) + { + return axiom_attribute_get_value( + (axiom_attribute_t *)(node->value), env); + } + else if (node->type == AXIOM_XPATH_TYPE_NAMESPACE) + { + return axiom_namespace_get_prefix( + (axiom_namespace_t *)(node->value), env); + } + + return NULL; +} + +/* Cast to axiom node */ +AXIS2_EXTERN axiom_node_t * AXIS2_CALL +axiom_xpath_cast_node2axiom_node( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + if (node->type == AXIOM_XPATH_TYPE_NODE && node->value) + { + return (axiom_node_t *)node->value; + } + else + { + return NULL; + } +} + +/* Free context */ +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_free_context( + const axutil_env_t *env, + axiom_xpath_context_t *context) +{ + if (context) + { + /* Free the expression if not freed */ + if (context->expr) + { + /* axiom_xpath_free_expression(env, context->expr); */ + + context->expr = NULL; + } + + if (context->root_node) + { + axiom_node_detach(axiom_node_get_first_child(context->root_node, context->env), context->env); + axiom_node_free_tree(context->root_node, context->env); + context->root_node = NULL; + } + + if (context->functions) + { + axutil_hash_free(context->functions, context->env); + context->functions = NULL; + } + + if(context->namespaces) + { + axiom_xpath_clear_namespaces(context); + context->namespaces = NULL; + } + + AXIS2_FREE(env->allocator, context); + } +} + +/* Free expression */ +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_free_expression( + const axutil_env_t *env, + axiom_xpath_expression_t * xpath_expr) +{ + if (xpath_expr) + { + if (xpath_expr->expr_str) + { + AXIS2_FREE(env->allocator, xpath_expr->expr_str); + + xpath_expr->expr_str = NULL; + } + + if (xpath_expr->operations) + { + axutil_array_list_free(xpath_expr->operations, env); + xpath_expr->operations = NULL; + } + + AXIS2_FREE(env->allocator, xpath_expr); + } +} + +/* Free result set */ +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_free_result( + const axutil_env_t *env, + axiom_xpath_result_t* result) +{ + if (result) + { + if (result->nodes) + { + axutil_array_list_free(result->nodes, env); + } + + AXIS2_FREE(env->allocator, result); + } +} + +/* Check if the expression can be evaluated on streaming XML */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_xpath_streaming_check( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axiom_xpath_streaming_t r = AXIOM_XPATH_CHECK(expr->start); + + if(r == AXIOM_XPATH_STREAMING_NOT_SUPPORTED) + { + return AXIS2_FALSE; + } + else + { + return AXIS2_TRUE; + } +} + diff --git a/axiom/src/xpath/xpath_functions.c b/axiom/src/xpath/xpath_functions.c new file mode 100755 index 0000000..bdf65c2 --- /dev/null +++ b/axiom/src/xpath/xpath_functions.c @@ -0,0 +1,46 @@ +/* + * 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_xpath.h> +#include "xpath_functions.h" +#include "xpath_internals_engine.h" + +int +axiom_xpath_function_count( + axiom_xpath_context_t *context, + int np) +{ + axiom_xpath_result_node_t *node; + double * v; + int i; + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + v = AXIS2_MALLOC(context->env->allocator, sizeof(double)); + + *v = np; + node->value = v; + node->type = AXIOM_XPATH_TYPE_NUMBER; + + for(i = 0; i < np; i++) + { + axutil_stack_pop(context->stack, context->env); + } + + axutil_stack_push(context->stack, context->env, node); + + return 1; +} diff --git a/axiom/src/xpath/xpath_functions.h b/axiom/src/xpath/xpath_functions.h new file mode 100755 index 0000000..d44f0a2 --- /dev/null +++ b/axiom/src/xpath/xpath_functions.h @@ -0,0 +1,47 @@ + +/* + * 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. + */ + +#ifndef AXIOM_XPATH_FUNCTIONS_H +#define AXIOM_XPATH_FUNCTIONS_H + +#include <axiom_xpath.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_xpath_functions functions + * @ingroup axiom_xpath + * @{ + */ + + /** + * count(node-set) function + * http://www.w3.org/TR/xpath#function-count + */ + int axiom_xpath_function_count(axiom_xpath_context_t *context, int np); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/axiom/src/xpath/xpath_internals.c b/axiom/src/xpath/xpath_internals.c new file mode 100755 index 0000000..c313baf --- /dev/null +++ b/axiom/src/xpath/xpath_internals.c @@ -0,0 +1,38 @@ +/* + * 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_xpath.h> +#include "xpath_internals.h" + +/* Make a copy of the xpath expression */ +void +axiom_xpath_expression_copy( + axiom_xpath_context_t *context, + axiom_xpath_expression_t* expr) +{ + int i; + axiom_xpath_operation_t *op; + + context->expr = expr; + + /* Set value of pos in every operation to 0 */ + for(i = 0; i < axutil_array_list_size(expr->operations, context->env); i++) + { + op = AXIOM_XPATH_OPR_GET(i); + op->pos = 0; + } +} diff --git a/axiom/src/xpath/xpath_internals.h b/axiom/src/xpath/xpath_internals.h new file mode 100755 index 0000000..891d543 --- /dev/null +++ b/axiom/src/xpath/xpath_internals.h @@ -0,0 +1,199 @@ + +/* + * 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. + */ + +#ifndef AXIOM_XPATH_INTERNALS_H +#define AXIOM_XPATH_INTERNALS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_xpath_internals internals + * @ingroup axiom_xpath + * @{ + */ + + + /** Get operation at index ind */ +#define AXIOM_XPATH_OPR_GET(ind) (axiom_xpath_operation_t *) \ + axutil_array_list_get(context->expr->operations, context->env, ind) + + /** + * An error has occured while parsing + */ +#define AXIOM_XPATH_PARSE_ERROR -2 + + /** + * XPath expression was successfully compiled + */ +#define AXIOM_XPATH_PARSE_SUCCESS 0 + + /** + * End of expression reached + */ +#define AXIOM_XPATH_PARSE_END -1 + + /* Types */ + + /** + * XPath operation + * Contains the operands and parameters + */ + typedef struct axiom_xpath_operation axiom_xpath_operation_t; + + /** + * XPath node test + * Stores the components of a node test + */ + typedef struct axiom_xpath_node_test axiom_xpath_node_test_t; + + /** + * Functions to process a XPath operator + */ + typedef int (*axiom_xpath_operator_t)(axiom_xpath_context_t *context, + axiom_xpath_operation_t * op); + + /** + * Functions to iterate through different XPath axes + */ + typedef int (*axiom_xpath_iterator_t)(axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * XPath node test types + */ + typedef enum axiom_xpath_node_test_type_t + { + AXIOM_XPATH_NODE_TEST_NONE = 0, + AXIOM_XPATH_NODE_TEST_ALL, + AXIOM_XPATH_NODE_TYPE_COMMENT, + AXIOM_XPATH_NODE_TYPE_NODE, + AXIOM_XPATH_NODE_TYPE_PI, + AXIOM_XPATH_NODE_TYPE_TEXT, + AXIOM_XPATH_NODE_TEST_STANDARD + } axiom_xpath_node_test_type_t; + + /** + * XPath operations + */ + typedef enum axiom_xpath_operation_type_t + { + AXIOM_XPATH_OPERATION_ROOT_NODE = 0, + AXIOM_XPATH_OPERATION_CONTEXT_NODE, + AXIOM_XPATH_OPERATION_NODE_TEST, + AXIOM_XPATH_OPERATION_STEP, + AXIOM_XPATH_OPERATION_RESULT, + AXIOM_XPATH_OPERATION_UNION, + AXIOM_XPATH_OPERATION_EQUAL_EXPR, + AXIOM_XPATH_OPERATION_AND_EXPR, + AXIOM_XPATH_OPERATION_OR_EXPR, + AXIOM_XPATH_OPERATION_PREDICATE, + AXIOM_XPATH_OPERATION_LITERAL, + AXIOM_XPATH_OPERATION_NUMBER, + AXIOM_XPATH_OPERATION_PATH_EXPRESSION, + AXIOM_XPATH_OPERATION_FUNCTION_CALL, + AXIOM_XPATH_OPERATION_ARGUMENT + } axiom_xpath_operation_type_t; + + /** + * XPath axes + */ + typedef enum axiom_xpath_axis_t + { + AXIOM_XPATH_AXIS_NONE = -1, + AXIOM_XPATH_AXIS_CHILD, + AXIOM_XPATH_AXIS_DESCENDANT, + AXIOM_XPATH_AXIS_PARENT, + AXIOM_XPATH_AXIS_ANCESTOR, + AXIOM_XPATH_AXIS_FOLLOWING_SIBLING, + AXIOM_XPATH_AXIS_PRECEDING_SIBLING, + AXIOM_XPATH_AXIS_FOLLOWING, + AXIOM_XPATH_AXIS_PRECEDING, + AXIOM_XPATH_AXIS_ATTRIBUTE, + AXIOM_XPATH_AXIS_NAMESPACE, + AXIOM_XPATH_AXIS_SELF, + AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF, + AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF + } axiom_xpath_axis_t; + + /** + * XPath node test structure + */ + struct axiom_xpath_node_test + { + /** Node test type */ + axiom_xpath_node_test_type_t type; + + /** Prefix + * NULL if no prefix + */ + axis2_char_t *prefix; + + /** Name */ + axis2_char_t *name; + + /** Literal for processing instruction (PI) */ + axis2_char_t *lit; + }; + + /** + * XPath operation structure + */ + struct axiom_xpath_operation + { + /** Type of operator */ + axiom_xpath_operation_type_t opr; + + /** Parameters of the operation */ + void *par1; + void *par2; + + /** Position: Used for predicate evaluation + */ + int pos; + + /** Operands pointing to other operations */ + int op1; + int op2; + }; + + /** + * Copies an XPath expression to a context + * + * No data is duplicated just the reference is assigned. + * Some parameters in the expression are reset. + * - pos in every operation + * + * @param context XPath context must not be NULL + * @param expr Expression to be copied + */ + void axiom_xpath_expression_copy( + axiom_xpath_context_t *context, + axiom_xpath_expression_t* expr); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/axiom/src/xpath/xpath_internals_engine.c b/axiom/src/xpath/xpath_internals_engine.c new file mode 100644 index 0000000..3c96d0e --- /dev/null +++ b/axiom/src/xpath/xpath_internals_engine.c @@ -0,0 +1,1203 @@ +/* + * 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_xpath.h> +#include "xpath_internals.h" +#include "xpath_internals_engine.h" +#include "xpath_internals_iterators.h" + +/* Evaluates the expath expression */ +axiom_xpath_result_t * +axiom_xpath_run( + axiom_xpath_context_t *context) +{ + axiom_xpath_result_t* res; + + /* Initialize result ret */ + res = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_t)); + + res->flag = 0; + + res->nodes = axutil_array_list_create(context->env, 0); + + /* Expression is empty */ + if(context->expr->start == AXIOM_XPATH_PARSE_END) + { + return res; + } + + context->stack = axutil_stack_create(context->env); + + axiom_xpath_evaluate_operation(context, context->expr->start); + + /* Add nodes to the result set from the stack */ + while(axutil_stack_size(context->stack, context->env) > 0) + { + axutil_array_list_add(res->nodes, context->env, + axutil_stack_pop(context->stack, context->env)); + } + + axutil_stack_free(context->stack, context->env); + + return res; +} + +/* Casting functions; these make use of the casting functions defined in xpath.h */ +void +axiom_xpath_cast_boolean( + axiom_xpath_result_node_t *node, + axiom_xpath_context_t *context) +{ + axis2_bool_t v = axiom_xpath_cast_node_to_boolean(context->env, node); + + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, v); + + node->type = AXIOM_XPATH_TYPE_BOOLEAN; +} + +void +axiom_xpath_cast_number( + axiom_xpath_result_node_t *node, + axiom_xpath_context_t *context) +{ + double v = axiom_xpath_cast_node_to_number(context->env, node); + + AXIOM_XPATH_CAST_SET_VALUE(double, v); + + node->type = AXIOM_XPATH_TYPE_NUMBER; +} + +void +axiom_xpath_cast_string( + axiom_xpath_result_node_t *node, + axiom_xpath_context_t *context) +{ + node->value = axiom_xpath_cast_node_to_string(context->env, node); + + node->type = AXIOM_XPATH_TYPE_TEXT; +} + +/* Evaluate whether two results are equal + + If either node is a boolean other is casted to a boolean; + Otherwise, if either node is a number other is casted to a number; + Otherwise, both nodes are casted to strings.*/ +axis2_bool_t +axiom_xpath_compare_equal( + axiom_xpath_result_node_t *node1, + axiom_xpath_result_node_t *node2, + axiom_xpath_context_t *context) +{ + if(node1->type == AXIOM_XPATH_TYPE_BOOLEAN || node2->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + axiom_xpath_cast_boolean(node1, context); + axiom_xpath_cast_boolean(node2, context); + + if(*(axis2_bool_t*)(node1->value) == *(axis2_bool_t*)(node2->value)) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + + if(node1->type == AXIOM_XPATH_TYPE_NUMBER || node2->type == AXIOM_XPATH_TYPE_NUMBER) + { + axiom_xpath_cast_number(node1, context); + axiom_xpath_cast_number(node2, context); + + if(*(double *)(node1->value) == *(double *)(node2->value)) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + + axiom_xpath_cast_string(node1, context); + axiom_xpath_cast_string(node2, context); + + if(axutil_strcmp((axis2_char_t *)(node1->value), (axis2_char_t *)(node2->value)) == 0) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } +} + +/* Convert a node set to boolean */ +axis2_bool_t +axiom_xpath_convert_to_boolean( + axutil_array_list_t *node_set, + axiom_xpath_context_t *context) +{ + if(axutil_array_list_size(node_set, context->env) == 0) + { + return AXIS2_FALSE; + } + else if(axutil_array_list_size(node_set, context->env) >= 2) + { + return AXIS2_TRUE; + } + else + { + axiom_xpath_result_node_t *node = axutil_array_list_get(node_set, context->env, 0); + axiom_xpath_cast_boolean(node, context); + + return *(axis2_bool_t *)node->value; + } +} + +/* Operators */ + +/* Literal */ +int +axiom_xpath_literal_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_result_node_t *node; + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + + /* Set the context node to NULL */ + /* This is not required; it gives some problems */ + /* context->node = NULL;*/ + + node->value = op->par1; + node->type = AXIOM_XPATH_TYPE_TEXT; + + axutil_stack_push(context->stack, context->env, node); + + return 1; +} + +/* Number */ +int +axiom_xpath_number_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_result_node_t *node; + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + + /* Set the context node to NULL */ + /* This is not required; it gives some problems */ + /* context->node = NULL;*/ + + node->value = op->par1; + node->type = AXIOM_XPATH_TYPE_NUMBER; + + axutil_stack_push(context->stack, context->env, node); + + return 1; +} + +/* Path Expression */ +int +axiom_xpath_path_expression_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + int filter_res_n, n_nodes = 0; + axiom_xpath_operation_t *rel_loc_op; + axiom_xpath_operator_t rel_loc_func; + axutil_array_list_t *arr; + axiom_xpath_result_node_t *res_node; + int i; + + /* Filter operation */ + if(op->op1 == AXIOM_XPATH_PARSE_END) + { + return 0; + } + + filter_res_n = axiom_xpath_evaluate_operation(context, op->op1); + + /* Relative location path */ + if(op->op2 == AXIOM_XPATH_PARSE_END) + { + return filter_res_n; + } + + rel_loc_op = AXIOM_XPATH_OPR_GET(op->op2); + rel_loc_func = axiom_xpath_get_operator(rel_loc_op); + + /* Array list to add all results from the filter expression */ + arr = axutil_array_list_create(context->env, 0); + + for(i = 0; i < filter_res_n; i++) + { + axutil_array_list_add(arr, context->env, axutil_stack_pop(context->stack, context->env)); + } + + /* Evaluate relative location path for all results from the + filter expression */ + for(i = 0; i < axutil_array_list_size(arr, context->env); i++) + { + res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr, context->env, i); + + if(res_node->type == AXIOM_XPATH_TYPE_NODE) + { + context->node = (axiom_node_t *)res_node->value; + context->position = i + 1; + context->size = filter_res_n; + + n_nodes += rel_loc_func(context, rel_loc_op); + } + + AXIS2_FREE(context->env->allocator, res_node); + } + + axutil_array_list_free(arr, context->env); + + return n_nodes; +} + +/* Or Expression */ +int +axiom_xpath_orexpr_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_result_node_t *node; + axiom_xpath_result_node_t *res_node; + int n_nodes[2]; + int i, j; + int op12[2]; + axutil_array_list_t *arr[2]; + + op12[0] = op->op1; + op12[1] = op->op2; + + /* Evaluate both operands and get number of results */ + for(i = 0; i < 2; i++) + { + if(op12[i] == AXIOM_XPATH_PARSE_END) + { + continue; + } + + n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]); + } + + for(i = 1; i >= 0; i--) + { + arr[i] = axutil_array_list_create(context->env, 0); + + for(j = 0; j < n_nodes[i]; j++) + { + axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack, + context->env)); + } + } + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + + node->type = AXIOM_XPATH_TYPE_BOOLEAN; + node->value = NULL; + + /* Checking equality + - If any node from the first set is equal to any node from the second set + the result is true */ + if(axiom_xpath_convert_to_boolean(arr[0], context) || axiom_xpath_convert_to_boolean(arr[1], + context)) + { + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE); + + axutil_stack_push(context->stack, context->env, node); + } + else + { + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE); + + axutil_stack_push(context->stack, context->env, node); + } + + for (i = 1; i >= 0; i--) + { + for (j = 0; j < n_nodes[i]; j++) + { + res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j); + AXIS2_FREE(context->env->allocator, res_node); + } + + axutil_array_list_free(arr[i], context->env); + } + + return 1; +} + +/* And Expression */ +int +axiom_xpath_andexpr_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_result_node_t *node; + axiom_xpath_result_node_t *res_node; + int n_nodes[2]; + int i, j; + int op12[2]; + axutil_array_list_t *arr[2]; + + op12[0] = op->op1; + op12[1] = op->op2; + + /* Evaluate both operands and get number of results */ + for(i = 0; i < 2; i++) + { + if(op12[i] == AXIOM_XPATH_PARSE_END) + { + continue; + } + + n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]); + } + + for(i = 1; i >= 0; i--) + { + arr[i] = axutil_array_list_create(context->env, 0); + + for(j = 0; j < n_nodes[i]; j++) + { + axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack, + context->env)); + } + } + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + + node->type = AXIOM_XPATH_TYPE_BOOLEAN; + node->value = NULL; + + /* Checking equality + - If any node from the first set is equal to any node from the second set + the result is true */ + if(axiom_xpath_convert_to_boolean(arr[0], context) && axiom_xpath_convert_to_boolean(arr[1], + context)) + { + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE); + + axutil_stack_push(context->stack, context->env, node); + } + else + { + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE); + + axutil_stack_push(context->stack, context->env, node); + } + + for (i = 1; i >= 0; i--) + { + for (j = 0; j < n_nodes[i]; j++) + { + res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j); + AXIS2_FREE(context->env->allocator, res_node); + } + + axutil_array_list_free(arr[i], context->env); + } + + return 1; +} + +/* Equal Expression */ +int +axiom_xpath_equalexpr_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_result_node_t *node; + axiom_xpath_result_node_t *res_node; + int n_nodes[2]; + int i, j; + int op12[2]; + axutil_array_list_t *arr[2]; + + op12[0] = op->op1; + op12[1] = op->op2; + + /* Evaluate both operands and get number of results */ + for(i = 0; i < 2; i++) + { + if(op12[i] == AXIOM_XPATH_PARSE_END) + { + continue; + } + + n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]); + } + + for(i = 1; i >= 0; i--) + { + arr[i] = axutil_array_list_create(context->env, 0); + + for(j = 0; j < n_nodes[i]; j++) + { + axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack, + context->env)); + } + } + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + + node->type = AXIOM_XPATH_TYPE_BOOLEAN; + node->value = NULL; + + /* Checking equality + - If any node from the first set is equal to any node from the second set + the result is true */ + for(i = 0; i < n_nodes[0]; i++) + { + for(j = 0; j < n_nodes[1]; j++) + { + if(axiom_xpath_compare_equal(axutil_array_list_get(arr[0], context->env, i), + axutil_array_list_get(arr[1], context->env, j), context)) + { + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE); + + axutil_stack_push(context->stack, context->env, node); + + break; + } + } + + if(j < n_nodes[1]) + { + break; + } + } + + if(!node->value) + { + AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE); + + axutil_stack_push(context->stack, context->env, node); + } + + for (i = 1; i >= 0; i--) + { + for (j = 0; j < n_nodes[i]; j++) + { + res_node =(axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j); + AXIS2_FREE(context->env->allocator, res_node); + } + + axutil_array_list_free(arr[i], context->env); + } + + return 1; +} + +/* Union */ +int +axiom_xpath_union_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + int n_nodes = 0; + int i; + int op12[2]; + + op12[0] = op->op1; + op12[1] = op->op2; + + for(i = 0; i < 2; i++) + { + if(op12[i] == AXIOM_XPATH_PARSE_END) + { + continue; + } + + n_nodes += axiom_xpath_evaluate_operation(context, op12[i]); + } + + return n_nodes; +} + +/* Set context node depending on whether relative or absolute location path */ +int +axiom_xpath_start_node_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + int n_nodes = 0; + + if(op->op1 == AXIOM_XPATH_PARSE_END) + { + return 0; + } + + if(op->opr == AXIOM_XPATH_OPERATION_ROOT_NODE) + { + context->node = context->root_node; + n_nodes += axiom_xpath_evaluate_operation(context, op->op1); + } + else if(op->opr == AXIOM_XPATH_OPERATION_CONTEXT_NODE) + { + n_nodes += axiom_xpath_evaluate_operation(context, op->op1); + } + + return n_nodes; +} + +/* Step */ +int +axiom_xpath_step_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_operation_t * node_test_op; + axiom_xpath_iterator_t iter; + axiom_xpath_axis_t axis; + + if(op->op1 == AXIOM_XPATH_PARSE_END) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Node test operator empty\n"); +#endif + + return AXIOM_XPATH_EVALUATION_ERROR; + } + + if(op->op2 == AXIOM_XPATH_PARSE_END) + { + return 0; + } + + /* Get the name */ + node_test_op = AXIOM_XPATH_OPR_GET(op->op1); + + /* Get the axis */ + if(!node_test_op->par2) + { +#ifdef AXIOM_XPATH_DEBUG + printf("axis is NULL in the step operator\n"); +#endif + return AXIOM_XPATH_EVALUATION_ERROR; + } + axis = *((axiom_xpath_axis_t *)node_test_op->par2); + + /* Get the iteration for the axis */ + iter = axiom_xpath_get_iterator(axis); + + return iter(context, op->op1 /* node test */, op->op2 /* next step */, node_test_op->op1 /* predicate */); +} + +/* Predicates */ +axis2_bool_t +axiom_xpath_evaluate_predicate_condition( + axiom_xpath_context_t *context, + int n_nodes) +{ + axiom_xpath_result_node_t *res; + int i; + + if(n_nodes <= 0) + { + return AXIS2_FALSE; + } + else if(n_nodes > 1) + { + for(i = 0; i < n_nodes; i++) + { + res = (axiom_xpath_result_node_t *)axutil_stack_pop(context->stack, context->env); + + if (res->type > AXIOM_XPATH_TYPE_NAMESPACE) + { + AXIS2_FREE(context->env->allocator, res->value); + } + + AXIS2_FREE(context->env->allocator, res); + } + + return AXIS2_TRUE; + } + else + { + res = (axiom_xpath_result_node_t *)axutil_stack_pop(context->stack, context->env); + + if(res->type == AXIOM_XPATH_TYPE_NUMBER) + { + if(*(double *)(res->value) == context->position) + { + AXIS2_FREE(context->env->allocator, res); + return AXIS2_TRUE; + } + else + { + AXIS2_FREE(context->env->allocator, res); + return AXIS2_FALSE; + } + } + else if(res->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + if(*(axis2_bool_t *)(res->value)) + { + AXIS2_FREE(context->env->allocator, res); + return AXIS2_TRUE; + } + else + { + AXIS2_FREE(context->env->allocator, res); + return AXIS2_FALSE; + } + } + else + { + AXIS2_FREE(context->env->allocator, res); + return AXIS2_TRUE; + } + } +} + +/* Predicate */ +int +axiom_xpath_evaluate_predicate( + axiom_xpath_context_t *context, + int op_next, + int op_predicate) +{ + int n_res; + axis2_bool_t res; + + axiom_xpath_operation_t * pred_op; + axiom_node_t *context_node = context->node; + + if(op_predicate == AXIOM_XPATH_PARSE_END) + { + return axiom_xpath_evaluate_operation(context, op_next); + } + else + { + pred_op = AXIOM_XPATH_OPR_GET(op_predicate); + + pred_op->pos++; + + /* Evaluate the predicate */ + if(pred_op->op1 != AXIOM_XPATH_PARSE_END) + { + n_res = axiom_xpath_evaluate_operation(context, pred_op->op1); + context->position = pred_op->pos; + + res = axiom_xpath_evaluate_predicate_condition(context, n_res); + } + else + { + res = AXIS2_TRUE; + } + /* A PredicateExpr is evaluated by evaluating the Expr and + converting the result to a boolean. If the result is a number, + the result will be converted to true if the number is equal to the + context position and will be converted to false otherwise; if the + result is not a number, then the result will be converted as if + by a call to the boolean function. */ + + /* Transform the result to number or boolean ? */ + + if(res) + { + context->node = context_node; + + return axiom_xpath_evaluate_predicate(context, op_next, pred_op->op2); + } + } + + return 0; +} + +/* Node test match */ +axis2_bool_t +axiom_xpath_node_test_match( + axiom_xpath_context_t *context, + axiom_xpath_node_test_t *node_test) +{ + axiom_types_t type; + axiom_element_t *element = NULL; + axis2_char_t *name = NULL; + axiom_namespace_t *ns = NULL, *xpath_ns = NULL; + + if(!context->node && !context->attribute && !context->ns) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Both context node and attribute are NULL."); + printf(" May be a literal or a number.\n"); +#endif + return AXIS2_FALSE; + } + else if(context->node) + { + /* Test if the node matches */ + type = axiom_node_get_node_type(context->node, context->env); + + if(type == AXIOM_ELEMENT) + { + element = axiom_node_get_data_element(context->node, context->env); + + name = axiom_element_get_localname(element, context->env); + + ns = axiom_element_get_namespace(element, context->env, context->node); + } + + if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE) + { + return AXIS2_FALSE; + } + else + { + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL || node_test->type + == AXIOM_XPATH_NODE_TEST_STANDARD) + { + if(type != AXIOM_ELEMENT) + { + return AXIS2_FALSE; + } + + /* Check namespace */ + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) + { + if(!ns && node_test->prefix) + { + return AXIS2_FALSE; + } + } + else + { + if((ns && !node_test->prefix) || (!ns && node_test->prefix)) + { + return AXIS2_FALSE; + } + } + + if(ns && node_test->prefix) + { + xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix); + + if(!xpath_ns) + { + return AXIS2_FALSE; + } + + if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env), + axiom_namespace_get_uri(xpath_ns, context->env))) + { + return AXIS2_FALSE; + } + } + + /* Check local name */ + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) + { + return AXIS2_TRUE; + } + else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) + { + if(name && axutil_strcmp(node_test->name, name) == 0) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + } + else if(node_test->type == AXIOM_XPATH_NODE_TYPE_COMMENT) + { + if(type == AXIOM_COMMENT) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + else if(node_test->type == AXIOM_XPATH_NODE_TYPE_PI) + { + if(type == AXIOM_PROCESSING_INSTRUCTION) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + else if(node_test->type == AXIOM_XPATH_NODE_TYPE_NODE) + { + if(type == AXIOM_ELEMENT) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + else if(node_test->type == AXIOM_XPATH_NODE_TYPE_TEXT) + { + if(type == AXIOM_TEXT) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + } + } + /* Attributes */ + else if(context->attribute) + { + name = axiom_attribute_get_localname(context->attribute, context->env); + ns = axiom_attribute_get_namespace(context->attribute, context->env); + + if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE) + { + return AXIS2_FALSE; + } + else + { + /* Check namespace */ + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) + { + if(!ns && node_test->prefix) + { + return AXIS2_FALSE; + } + } + else + { + if((ns && !node_test->prefix) || (!ns && node_test->prefix)) + { + return AXIS2_FALSE; + } + } + + if(ns && node_test->prefix) + { + xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix); + + if(!xpath_ns) + { + return AXIS2_FALSE; + } + + if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env), + axiom_namespace_get_uri(xpath_ns, context->env))) + { + return AXIS2_FALSE; + } + } + + /* Check local name */ + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) + { + return AXIS2_TRUE; + } + else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) + { + if(name && axutil_strcmp(node_test->name, name) == 0) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + } + } + + /* Namespace */ + else if(context->ns) + { + /* Prefix is checked ??? If changed to uri the cast + method in xpath.c needs to be changed as well */ + name = axiom_namespace_get_prefix(context->ns, context->env); + ns = NULL; + + if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE) + { + return AXIS2_FALSE; + } + else + { + /* Check namespace */ + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) + { + if(!ns && node_test->prefix) + { + return AXIS2_FALSE; + } + } + else + { + if((ns && !node_test->prefix) || (!ns && node_test->prefix)) + { + return AXIS2_FALSE; + } + } + + if(ns && node_test->prefix) + { + xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix); + + if(!xpath_ns) + { + return AXIS2_FALSE; + } + + if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env), + axiom_namespace_get_uri(xpath_ns, context->env))) + { + return AXIS2_FALSE; + } + } + + /* Check local name */ + if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) + { + return AXIS2_TRUE; + } + else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) + { + if(name && axutil_strcmp(node_test->name, name) == 0) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + } + } + + return AXIS2_FALSE; +} + +int +axiom_xpath_function_call_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_function_t func = axiom_xpath_get_function(context, op->par1); + int n_args = 0; + + if(!func) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Function %s not found\n", (char *)op->par1); +#endif + + return AXIOM_XPATH_EVALUATION_ERROR; + } + + if(op->op1 != AXIOM_XPATH_PARSE_END) + { + n_args = axiom_xpath_evaluate_operation(context, op->op1); + } + + return func(context, n_args); +} + +int +axiom_xpath_argument_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + int n_args = 0; + + if(op->op1 != AXIOM_XPATH_PARSE_END) + { + n_args += axiom_xpath_evaluate_operation(context, op->op1); + } + + if(op->op2 != AXIOM_XPATH_PARSE_END) + { + n_args += axiom_xpath_evaluate_operation(context, op->op1); + } + + return n_args; +} + +/* Collect the current node to the results list */ +int +axiom_xpath_collect_operator( + axiom_xpath_context_t *context, + axiom_xpath_operation_t * op) +{ + axiom_xpath_result_node_t *node; + + node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); + + if(context->node) + { + node->value = context->node; + node->type = AXIOM_XPATH_TYPE_NODE; + } + else if(context->attribute) + { + node->value = context->attribute; + node->type = AXIOM_XPATH_TYPE_ATTRIBUTE; + } + else if(context->ns) + { + node->value = context->ns; + node->type = AXIOM_XPATH_TYPE_NAMESPACE; + } + + axutil_stack_push(context->stack, context->env, node); + + return 1; +} + +/* Returns a pointer to the respective processing function */ +axiom_xpath_operator_t +axiom_xpath_get_operator( + axiom_xpath_operation_t * op) +{ + switch(op->opr) + { + case AXIOM_XPATH_OPERATION_STEP: + return axiom_xpath_step_operator; + + case AXIOM_XPATH_OPERATION_ROOT_NODE: + case AXIOM_XPATH_OPERATION_CONTEXT_NODE: + return axiom_xpath_start_node_operator; + + case AXIOM_XPATH_OPERATION_RESULT: + return axiom_xpath_collect_operator; + + case AXIOM_XPATH_OPERATION_UNION: + return axiom_xpath_union_operator; + + case AXIOM_XPATH_OPERATION_OR_EXPR: + return axiom_xpath_orexpr_operator; + + case AXIOM_XPATH_OPERATION_AND_EXPR: + return axiom_xpath_andexpr_operator; + + case AXIOM_XPATH_OPERATION_EQUAL_EXPR: + return axiom_xpath_equalexpr_operator; + + case AXIOM_XPATH_OPERATION_LITERAL: + return axiom_xpath_literal_operator; + + case AXIOM_XPATH_OPERATION_NUMBER: + return axiom_xpath_number_operator; + + case AXIOM_XPATH_OPERATION_PATH_EXPRESSION: + return axiom_xpath_path_expression_operator; + + case AXIOM_XPATH_OPERATION_FUNCTION_CALL: + return axiom_xpath_function_call_operator; + + case AXIOM_XPATH_OPERATION_ARGUMENT: + return axiom_xpath_argument_operator; + + default: +#ifdef AXIOM_XPATH_DEBUG + printf("Unidentified operation.\n"); +#endif + + return NULL; + } +} + +/* Returns a pointer to the respective processing function */ +axiom_xpath_iterator_t +axiom_xpath_get_iterator( + axiom_xpath_axis_t axis) +{ + switch(axis) + { + case AXIOM_XPATH_AXIS_CHILD: + return axiom_xpath_child_iterator; + + case AXIOM_XPATH_AXIS_DESCENDANT: + return axiom_xpath_descendant_iterator; + + case AXIOM_XPATH_AXIS_PARENT: + return axiom_xpath_parent_iterator; + + case AXIOM_XPATH_AXIS_ANCESTOR: + return axiom_xpath_ancestor_iterator; + + case AXIOM_XPATH_AXIS_FOLLOWING_SIBLING: + return axiom_xpath_following_sibling_iterator; + + case AXIOM_XPATH_AXIS_PRECEDING_SIBLING: + return axiom_xpath_preceding_sibling_iterator; + + case AXIOM_XPATH_AXIS_FOLLOWING: + return axiom_xpath_following_iterator; + + case AXIOM_XPATH_AXIS_PRECEDING: + return axiom_xpath_preceding_iterator; + + case AXIOM_XPATH_AXIS_ATTRIBUTE: + return axiom_xpath_attribute_iterator; + + case AXIOM_XPATH_AXIS_NAMESPACE: + return axiom_xpath_namespace_iterator; + + case AXIOM_XPATH_AXIS_SELF: + return axiom_xpath_self_iterator; + + case AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF: + return axiom_xpath_descendant_self_iterator; + + case AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF: + return axiom_xpath_ancestor_self_iterator; + + default: +#ifdef AXIOM_XPATH_DEBUG + printf("Unidentified axis.\n"); +#endif + + return NULL; + } +} + +int +axiom_xpath_evaluate_operation( + axiom_xpath_context_t *context, + int op) +{ + axiom_xpath_operation_t * operation; + axiom_xpath_operator_t function; + + /* Get a pointer to the operation */ + operation = AXIOM_XPATH_OPR_GET(op); + + /* Get the funciton which processes the operations */ + function = axiom_xpath_get_operator(operation); + + return function(context, operation); +} diff --git a/axiom/src/xpath/xpath_internals_engine.h b/axiom/src/xpath/xpath_internals_engine.h new file mode 100755 index 0000000..bffc8a7 --- /dev/null +++ b/axiom/src/xpath/xpath_internals_engine.h @@ -0,0 +1,265 @@ + +/* + * 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. + */ + +#ifndef AXIOM_XPATH_INTERNALS_ENGINE_H +#define AXIOM_XPATH_INTERNALS_ENGINE_H + +#include "xpath_internals.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_xpath_engine engine + * @ingroup axiom_xpath + * @{ + */ + + + /* Macros */ + + /** Set node->value to _value */ +#define AXIOM_XPATH_CAST_SET_VALUE(_type, _value) { \ + _type * _var; \ + if(node->value \ + && node->type != AXIOM_XPATH_TYPE_NODE \ + && node->type != AXIOM_XPATH_TYPE_ATTRIBUTE \ + && node->type != AXIOM_XPATH_TYPE_NAMESPACE) \ + { AXIS2_FREE(context->env->allocator, node->value); } \ + _var = AXIS2_MALLOC(context->env->allocator, sizeof(_type)); \ + *_var = _value; \ + node->value = (void *) _var; \ +} + + /* Functions */ + + /** + * Evaluate an XPath context, which containes a parsed expression + * + * @param context XPath context + * @return Result set + */ + axiom_xpath_result_t* axiom_xpath_run(axiom_xpath_context_t *context); + + /** + * Finds the operator function for a given operation + * + * @param op Operation + * @return Pointer to the function which process the given operation + */ + axiom_xpath_operator_t axiom_xpath_get_operator(axiom_xpath_operation_t * op); + + /** + * Get the iterotor for give axis + * + * @param axis XPath axis + * @return Pointer to the function which iterater through the given axis + */ + axiom_xpath_iterator_t axiom_xpath_get_iterator(axiom_xpath_axis_t axis); + + /* Operators */ + + /** + * Select the start node depending on whether it is an absolute or relative location path + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack + */ + int axiom_xpath_start_node_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Add the context node or attribute to the results stack + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack + */ + int axiom_xpath_collect_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Process union operator + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack + */ + int axiom_xpath_union_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Perform or operation + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_orexpr_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Perform and operation + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_andexpr_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Perform equality test operation + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_equalexpr_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Evaluate function call operation + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_function_call_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Evaluate argument operation + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_argument_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Process a path expression + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack + */ + int axiom_xpath_path_expression_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Process a number; push the value to the stack + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_number_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + /** + * Process a literal; push the string to the stack + * + * @param context XPath context + * @param op XPath operation + * @return Number of nodes added to the stack; which is one + */ + int axiom_xpath_literal_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op); + + + /** + * Converts an XPath result to a boolean result + * + * @param node Result + * @param context XPath context + */ + void axiom_xpath_cast_boolean(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context); + + /** + * Converts an XPath result to a number + * + * @param node Result + * @param context XPath context + */ + void axiom_xpath_cast_number(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context); + + /** + * Converts an XPath result to a string + * + * @param node Result + * @param context XPath context + */ + void axiom_xpath_cast_string(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context); + + /* Convert a node set to boolean */ + /** + * Convert a XPath node set to boolean + * + * @param node_set Node set + * @return AXIS2_TRUE if true; AXIS2_FALSE otherwise + */ + axis2_bool_t axiom_xpath_convert_to_boolean(axutil_array_list_t *node_set, axiom_xpath_context_t *context); + + /** + * Test if two result nodes are equal + * + * @param node1 First node + * @param node2 Second node + * @param context XPath context + * @return AXIS2_TRUE if equal; AXIS2_FALSE otherwise + */ + axis2_bool_t axiom_xpath_compare_equal(axiom_xpath_result_node_t *node1, axiom_xpath_result_node_t *node2, axiom_xpath_context_t *context); + + /** + * Test if the axiom node matches node test + * + * @param context XPath context + * @param node_test Node test + * @return AXIS2_TRUE if matches; AXIS2_FALSE otherwise + */ + axis2_bool_t axiom_xpath_node_test_match(axiom_xpath_context_t *context, axiom_xpath_node_test_t *node_test); + + /** + * Evaluate if the predicate is true + * + * @param context XPath context + * @param n_nodes Number of results after evaluating the expression in the predicate + * @return AXIS2_TRUE if matches; AXIS2_FALSE otherwise + */ + axis2_bool_t axiom_xpath_evaluate_predicate_condition(axiom_xpath_context_t *context, int n_nodes); + + /** + * Evaluate if the predicate(s) is true using axiom_xpath_evaluate_predicate_condition and executes the operation op_next + * + * @param context XPath context + * @param op_next The operation to be executed if all predicates are true + * @param op_predicate Reference to predicate + * @return Number of nodes added to the stack + */ + int axiom_xpath_evaluate_predicate(axiom_xpath_context_t *context, int op_next, int op_predicate); + + /** + * Evaluate operation pointed by op + * + * @param context XPath context + * @param op The index of the operation in the operations list + * @return Number of nodes added to the stack + */ + int axiom_xpath_evaluate_operation(axiom_xpath_context_t *context, int op); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/axiom/src/xpath/xpath_internals_iterators.c b/axiom/src/xpath/xpath_internals_iterators.c new file mode 100644 index 0000000..225bea6 --- /dev/null +++ b/axiom/src/xpath/xpath_internals_iterators.c @@ -0,0 +1,588 @@ +/* + * 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_xpath.h> +#include "xpath_internals.h" +#include "xpath_internals_engine.h" +#include "xpath_internals_iterators.h" + + +/* child */ +int +axiom_xpath_child_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes_tot = 0; + int n_nodes; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *cur = NULL; + axiom_node_t *context_node = NULL; + /* For streaming */ + axiom_node_t *prev = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + cur = axiom_node_get_first_child(context->node, context->env); + + while(cur != NULL) + { + n_nodes = 0; + context->node = cur; + prev = cur; + cur = axiom_node_get_next_sibling(cur, context->env); + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes = axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + n_nodes_tot += n_nodes; + } + } + + /* Change the context node back to what it was */ + context->node = context_node; + + return n_nodes_tot; +} + +/* descendant */ +int +axiom_xpath_descendant_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *child = NULL; + axiom_node_t *context_node = NULL; + axutil_stack_t *stack; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + /* Setting up the stack */ + stack = axutil_stack_create(context->env); + + child = axiom_node_get_first_child(context->node, context->env); + while(child) + { + axutil_stack_push(stack, context->env, child); + child = axiom_node_get_first_child(child, context->env); + } + + /* Processing nodes */ + while(axutil_stack_size(stack, context->env) > 0) + { + child = (axiom_node_t *)axutil_stack_pop(stack, context->env); + + context->node = child; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + child = axiom_node_get_next_sibling(child, context->env); + while(child) + { + axutil_stack_push(stack, context->env, child); + child = axiom_node_get_first_child(child, context->env); + } + } + + context->node = context_node; + + axutil_stack_free(stack, context->env); + + return n_nodes; +} + +/* parent */ +int +axiom_xpath_parent_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *parent = NULL; + axiom_node_t *context_node = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + parent = axiom_node_get_parent(context->node, context->env); + + if(parent != NULL) + { + context->node = parent; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes = axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + } + + /* Change the context node back to what it was */ + context->node = context_node; + + return n_nodes; +} + +/* ancestor axis */ +int +axiom_xpath_ancestor_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *cur = NULL; + axiom_node_t *context_node = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + cur = axiom_node_get_parent(context->node, context->env); + + while(cur != NULL) + { + context->node = cur; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + cur = axiom_node_get_parent(cur, context->env); + } + + /* Change the context node back to what it was */ + context->node = context_node; + + return n_nodes; +} + +/* following-sibling axis */ +int +axiom_xpath_following_sibling_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *cur = NULL; + axiom_node_t *context_node = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + cur = axiom_node_get_next_sibling(context->node, context->env); + + while(cur != NULL) + { + context->node = cur; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + cur = axiom_node_get_next_sibling(cur, context->env); + } + + /* Change the context node back to what it was */ + context->node = context_node; + + return n_nodes; +} + +/* preceding-sibling axis */ +int +axiom_xpath_preceding_sibling_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *cur = NULL; + axiom_node_t *context_node = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + cur = axiom_node_get_previous_sibling(context->node, context->env); + + while(cur != NULL) + { + context->node = cur; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + cur = axiom_node_get_previous_sibling(cur, context->env); + } + + /* Change the context node back to what it was */ + context->node = context_node; + + return n_nodes; +} + +/* following */ +int +axiom_xpath_following_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *child = NULL, *parent = NULL; + axiom_node_t *context_node = NULL; + axutil_stack_t *stack; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + /* Setting up the stack */ + stack = axutil_stack_create(context->env); + axutil_stack_push(stack, context->env, context->node); + + parent = context->node; + + while(parent) + { + axutil_stack_push(stack, context->env, parent); + + while(axutil_stack_size(stack, context->env) > 0) + { + child = (axiom_node_t *)axutil_stack_pop(stack, context->env); + + child = axiom_node_get_next_sibling(child, context->env); + + while(child) + { + context->node = child; + if(axiom_xpath_node_test_match(context, + (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + axutil_stack_push(stack, context->env, child); + child = axiom_node_get_first_child(child, context->env); + } + } + parent = axiom_node_get_parent(parent, context->env); + } + + /* Change the context node back to what it was */ + context->node = context_node; + + axutil_stack_free(stack, context->env); + + return n_nodes; +} + +/* preceding */ +int +axiom_xpath_preceding_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *child = NULL, *parent = NULL; + axiom_node_t *context_node = NULL; + axutil_stack_t *stack; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + /* Setting up the stack */ + stack = axutil_stack_create(context->env); + + parent = context->node; + + while(parent) + { + axutil_stack_push(stack, context->env, parent); + + while(axutil_stack_size(stack, context->env) > 0) + { + child = (axiom_node_t *)axutil_stack_pop(stack, context->env); + + child = axiom_node_get_previous_sibling(child, context->env); + + while(child) + { + context->node = child; + if(axiom_xpath_node_test_match(context, + (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + axutil_stack_push(stack, context->env, child); + + child = axiom_node_get_last_child(child, context->env); + } + } + parent = axiom_node_get_parent(parent, context->env); + } + + /* Change the context node back to what it was */ + context->node = context_node; + + axutil_stack_free(stack, context->env); + + return n_nodes; +} + +/* attribute axis */ +int +axiom_xpath_attribute_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_types_t type; + axiom_node_t *context_node = NULL; + axiom_element_t *element; + axutil_hash_t *ht; + axutil_hash_index_t *hi; + + /* void *key; + * axis2_ssize_t klen; + */ + void *attr; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + type = axiom_node_get_node_type(context_node, context->env); + + if(type != AXIOM_ELEMENT) + { + return 0; + } + + element = axiom_node_get_data_element(context_node, context->env); + + context->node = NULL; + + ht = axiom_element_get_all_attributes(element, context->env); + + if(ht) + { + for(hi = axutil_hash_first(ht, context->env); hi; hi = axutil_hash_next(context->env, hi)) + { + attr = &context->attribute; + axutil_hash_this(hi, NULL, NULL, attr); + + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + } + } + + context->node = context_node; + context->attribute = NULL; + + return n_nodes; +} + +/* namespace axis */ +int +axiom_xpath_namespace_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_types_t type; + axiom_node_t *context_node = NULL; + axiom_element_t *element; + axutil_hash_t *ht; + axutil_hash_index_t *hi; + + /* void *key; + * axis2_ssize_t klen; + */ + + void *ns; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + type = axiom_node_get_node_type(context_node, context->env); + + if(type != AXIOM_ELEMENT) + { + return 0; + } + + element = axiom_node_get_data_element(context_node, context->env); + + context->node = NULL; + + ht = axiom_element_get_namespaces(element, context->env); + + if(ht) + { + for(hi = axutil_hash_first(ht, context->env); hi; hi = axutil_hash_next(context->env, hi)) + { + ns = &context->ns; + axutil_hash_this(hi, NULL, NULL, ns); + + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + } + } + + context->node = context_node; + context->ns = NULL; + + return n_nodes; +} + +/* self axis */ +int +axiom_xpath_self_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *context_node = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + context->node = context_node; + + return n_nodes; +} + +/* descendant-or-self axis */ +int +axiom_xpath_descendant_self_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *child = NULL; + axiom_node_t *context_node = NULL; + axutil_stack_t *stack; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + /* Setting up the stack */ + stack = axutil_stack_create(context->env); + + child = axiom_node_get_first_child(context->node, context->env); + while(child) + { + axutil_stack_push(stack, context->env, child); + child = axiom_node_get_first_child(child, context->env); + } + + /* Processing nodes */ + while(axutil_stack_size(stack, context->env) > 0) + { + child = (axiom_node_t *)axutil_stack_pop(stack, context->env); + + context->node = child; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + child = axiom_node_get_next_sibling(child, context->env); + while(child) + { + axutil_stack_push(stack, context->env, child); + child = axiom_node_get_first_child(child, context->env); + } + } + + /* Change the context node back to what it was */ + context->node = context_node; + + axutil_stack_free(stack, context->env); + + return n_nodes; +} + +/* ancestor-or-self axis */ +int +axiom_xpath_ancestor_self_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate) +{ + int n_nodes = 0; + axiom_xpath_operation_t * node_test_op; + axiom_node_t *parent = NULL; + axiom_node_t *context_node = NULL; + + AXIOM_XPATH_ITERATOR_INITIALIZE; + + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + parent = axiom_node_get_parent(context->node, context->env); + + while(parent != NULL) + { + context->node = parent; + if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) + { + n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); + } + + parent = axiom_node_get_parent(parent, context->env); + } + + /* Change the context node back to what it was */ + context->node = context_node; + + return n_nodes; +} diff --git a/axiom/src/xpath/xpath_internals_iterators.h b/axiom/src/xpath/xpath_internals_iterators.h new file mode 100755 index 0000000..67d06c4 --- /dev/null +++ b/axiom/src/xpath/xpath_internals_iterators.h @@ -0,0 +1,298 @@ + +/* + * 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. + */ + +#ifndef AXIOM_XPATH_INTERNALS_ITERATORS_H +#define AXIOM_XPATH_INTERNALS_ITERATORS_H + +#include <axiom_xpath.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_xpath_iterators iterators + * @ingroup axiom_xpath + * @{ + */ + + +#ifdef AXIOM_XPATH_DEBUG +#define AXIOM_XPATH_ITERATOR_INITIALIZE { \ + if(!context->node) { \ + printf("Context node NULL; cannot evaluate self or descendent axis.\n"); \ + return AXIOM_XPATH_EVALUATION_ERROR; } \ + node_test_op = AXIOM_XPATH_OPR_GET(op_node_test); \ + if(!node_test_op) { \ + printf("Node test not present.\n"); \ + return AXIOM_XPATH_EVALUATION_ERROR; } \ + context_node = context->node; \ +} +#else +#define AXIOM_XPATH_ITERATOR_INITIALIZE { \ + if(!context->node) { \ + return AXIOM_XPATH_EVALUATION_ERROR; } \ + node_test_op = AXIOM_XPATH_OPR_GET(op_node_test); \ + if(!node_test_op) { \ + return AXIOM_XPATH_EVALUATION_ERROR; } \ + context_node = context->node; \ +} +#endif + + /** + * Iterate through children + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_child_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through descendents + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_descendant_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through parent node. (Only one node) + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_parent_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through ancestors + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_ancestor_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through siblings following the context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_following_sibling_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through sibling preceding the context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_preceding_sibling_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through all nodes following the context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_following_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through all nodes preceding the context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_preceding_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through attributes + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_attribute_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through namespaces defined in the context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_namespace_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through self node (Only one node) + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_self_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through descendents and context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_descendant_self_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** + * Iterate through ancestors and context node + * + * @param context XPath context + * @param op_node_test Reference to the node test operation + * in the parsed expression + * @param op_next Reference to the next step in the location path, + * in the parsed expression + * @param op_predicate Reference to the first predicate in the + * parsed expression + * @return Number of nodes added to the stack + */ + int axiom_xpath_ancestor_self_iterator( + axiom_xpath_context_t *context, + int op_node_test, + int op_next, + int op_predicate); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/axiom/src/xpath/xpath_internals_parser.c b/axiom/src/xpath/xpath_internals_parser.c new file mode 100755 index 0000000..a1ce79a --- /dev/null +++ b/axiom/src/xpath/xpath_internals_parser.c @@ -0,0 +1,1245 @@ +/* + * 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_xpath.h> +#include "xpath_internals.h" +#include "xpath_internals_parser.h" +#include <ctype.h> + +/* Compile an XPath expression */ +int +axiom_xpath_compile( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + if(!expr || !expr->expr_str) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Expression in NULL.\n"); +#endif + + return AXIS2_FAILURE; + } + + expr->expr_len = (int)axutil_strlen(expr->expr_str); + + expr->operations = axutil_array_list_create(env, 0); + + expr->expr_ptr = 0; + + expr->start = axiom_xpath_compile_orexpr(env, expr); + + if(expr->start == AXIOM_XPATH_PARSE_ERROR) + { + axutil_array_list_free(expr->operations, env); + + return AXIOM_XPATH_PARSE_ERROR; + } + else + { +#ifdef AXIOM_XPATH_DEBUG + printf("Expression successfully parsed\n"); +#endif + + return AXIOM_XPATH_PARSE_SUCCESS; + } +} + +/* Parse Or Expression */ +int +axiom_xpath_compile_orexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_andexpr(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: AndEpxr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + while(AXIOM_XPATH_CURRENT == 'o' && AXIOM_XPATH_NEXT(1) == 'r') + { + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + + op2 = axiom_xpath_compile_andexpr(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: AndEpxr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_OR_EXPR, op1, op2); + + AXIOM_XPATH_SKIP_WHITESPACES; + } + + return op1; +} + +/* Parse And Expression */ +int +axiom_xpath_compile_andexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_equalexpr(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: EqualityExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + while(AXIOM_XPATH_CURRENT == 'a' && AXIOM_XPATH_NEXT(1) == 'n' && AXIOM_XPATH_NEXT(1) == 'd') + { + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + + op2 = axiom_xpath_compile_equalexpr(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: EqualityExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_AND_EXPR, op1, op2); + + AXIOM_XPATH_SKIP_WHITESPACES; + } + + return op1; +} + +/* Parse Equality Expression */ +int +axiom_xpath_compile_equalexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_union(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: UnionExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + while(AXIOM_XPATH_CURRENT == '=') + { + AXIOM_XPATH_SKIP_WHITESPACES; + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + + op2 = axiom_xpath_compile_union(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: UnionExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_EQUAL_EXPR, op1, op2); + + AXIOM_XPATH_SKIP_WHITESPACES; + } + + return op1; +} + +/* Parse Union */ +int +axiom_xpath_compile_union( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_path_expression(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: PathExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT == '|') + { + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + op2 = axiom_xpath_compile_union(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: UnionExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_UNION, op1, op2); + } + + /* Just a location path */ + return op1; +} + +/* Compile Filter expression */ +int +axiom_xpath_compile_filter( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op = AXIOM_XPATH_PARSE_END; + + if(AXIOM_XPATH_CURRENT == '(') + { + AXIOM_XPATH_READ(1); + op = axiom_xpath_compile_orexpr(env, expr); + AXIOM_XPATH_SKIP_WHITESPACES; + if(AXIOM_XPATH_CURRENT == ')') + { + AXIOM_XPATH_READ(1); + return op; + } + else + { + return AXIOM_XPATH_PARSE_ERROR; + } + } + else if(AXIOM_XPATH_CURRENT == '\'' || AXIOM_XPATH_CURRENT == '\"') + { + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_LITERAL, axiom_xpath_compile_literal(env, + expr), NULL, AXIOM_XPATH_PARSE_END); + } + else if(isdigit(AXIOM_XPATH_CURRENT) || (AXIOM_XPATH_CURRENT == '.' && isdigit( + AXIOM_XPATH_NEXT(1)))) + { + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NUMBER, axiom_xpath_compile_number(env, + expr), NULL, AXIOM_XPATH_PARSE_END); + } + else if(AXIOM_XPATH_CURRENT == '$') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Variables are not supported, yet - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + } + else + { + return axiom_xpath_compile_function_call(env, expr); + } + +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Invalid Filter expression - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + /* TODO: functions and variables */ +} + +/* Parse Path expression (not a location path) */ +int +axiom_xpath_path_compile_path_expression_filter( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op_filter, op_next; + + op_filter = axiom_xpath_compile_filter(env, expr); + + if(op_filter == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: FilterExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_NEXT(0) == '/' && AXIOM_XPATH_NEXT(1) == '/') + { + AXIOM_XPATH_READ(2); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op_next = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op_next); + } + else if(AXIOM_XPATH_NEXT(0) == '/') + { + AXIOM_XPATH_READ(1); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + else + { + op_next = AXIOM_XPATH_PARSE_END; + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_PATH_EXPRESSION, op_filter, op_next); +} + +/* Parse Path expression */ +int +axiom_xpath_compile_path_expression( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int temp_ptr = expr->expr_ptr; + axis2_char_t *name; + axis2_char_t *node_types[] = { "comment", "node", "processing-instruction", "text" }; + axis2_char_t filter_start[] = { '$', '\'', '\"', '(' }; + int i; + + /* if | FilterExpr + | FilterExpr '/' RelativeLocationPath + | FilterExpr '//' RelativeLocationPath */ + for(i = 0; i < 4; i++) + { + if(AXIOM_XPATH_CURRENT == filter_start[i]) + { + return axiom_xpath_path_compile_path_expression_filter(env, expr); + } + } + + if(isdigit(AXIOM_XPATH_CURRENT) || (AXIOM_XPATH_CURRENT == '.' && isdigit(AXIOM_XPATH_NEXT(1)))) + { + return axiom_xpath_path_compile_path_expression_filter(env, expr); + } + + /* Funciton calls */ + name = axiom_xpath_compile_ncname(env, expr); + AXIOM_XPATH_SKIP_WHITESPACES; + + if(name != NULL && AXIOM_XPATH_CURRENT == '(') + { + expr->expr_ptr = temp_ptr; + for(i = 0; i < 4; i++) + { + /* If node type */ + if(axutil_strcmp(name, node_types[i]) == 0) + { + return axiom_xpath_compile_location_path(env, expr); + } + } + + return axiom_xpath_path_compile_path_expression_filter(env, expr); + } + + expr->expr_ptr = temp_ptr; + + return axiom_xpath_compile_location_path(env, expr); +} + +/* Parses Location Path */ +int +axiom_xpath_compile_location_path( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1; + axiom_xpath_operation_type_t opr; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + if(AXIOM_XPATH_CURRENT == '/') + { + /* Descendent */ + if(AXIOM_XPATH_NEXT(1) == '/') + { + opr = AXIOM_XPATH_OPERATION_CONTEXT_NODE; + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + + op1 = axiom_xpath_compile_relative_location(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op1); + } + else + { + opr = AXIOM_XPATH_OPERATION_ROOT_NODE; + AXIOM_XPATH_READ(1); + + op1 = axiom_xpath_compile_relative_location(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + } + else + { + opr = AXIOM_XPATH_OPERATION_CONTEXT_NODE; + + op1 = axiom_xpath_compile_relative_location(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH(opr, op1, AXIOM_XPATH_PARSE_END); +} + +/* Parses Relative Location Path */ +int +axiom_xpath_compile_relative_location( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op_step, op_next; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op_step = axiom_xpath_compile_step(env, expr); + op_next = AXIOM_XPATH_PARSE_END; /* Will change if there are more steps */ + + if(op_step == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Step expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_NEXT(0) == '/' && AXIOM_XPATH_NEXT(1) == '/') + { + AXIOM_XPATH_READ(2); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op_next = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op_next); + } + else if(AXIOM_XPATH_NEXT(0) == '/') + { + AXIOM_XPATH_READ(1); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + + /* End of the location path */ + if(op_next == AXIOM_XPATH_PARSE_END) + { + op_next = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_RESULT, AXIOM_XPATH_PARSE_END, + AXIOM_XPATH_PARSE_END); + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_STEP, op_step, op_next); +} + +/* Parses Step */ +int +axiom_xpath_compile_step( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op_predicate = AXIOM_XPATH_PARSE_END; + axiom_xpath_node_test_t *node_test; + int temp_ptr; + axis2_char_t *name = NULL; + axiom_xpath_axis_t axis = AXIOM_XPATH_AXIS_NONE; + + AXIOM_XPATH_SKIP_WHITESPACES; + + /* . and .. */ + if(AXIOM_XPATH_CURRENT == '.') + { + if(AXIOM_XPATH_NEXT(1) == '.') + { + AXIOM_XPATH_READ(2); + axis = AXIOM_XPATH_AXIS_PARENT; + } + else + { + AXIOM_XPATH_READ(1); + axis = AXIOM_XPATH_AXIS_SELF; + } + + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NODE_TEST, + axiom_xpath_create_node_test_node(env), axiom_xpath_create_axis(env, axis), + op_predicate); + } + else if(AXIOM_XPATH_CURRENT == '@') + { + axis = AXIOM_XPATH_AXIS_ATTRIBUTE; + + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + } + else + { + temp_ptr = expr->expr_ptr; + + name = axiom_xpath_compile_ncname(env, expr); + + if(name) + { + AXIOM_XPATH_SKIP_WHITESPACES; + + /* An axis */ + if(AXIOM_XPATH_CURRENT == ':' && AXIOM_XPATH_NEXT(1) == ':') + { + axis = axiom_xpath_get_axis(env, name); + + if(axis == AXIOM_XPATH_AXIS_NONE) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Parse error: Invalid axis - %s\n", name); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + } + else + { + axis = AXIOM_XPATH_AXIS_CHILD; + + expr->expr_ptr = temp_ptr; + } + } + else + { + axis = AXIOM_XPATH_AXIS_CHILD; + + expr->expr_ptr = temp_ptr; + } + } + + node_test = axiom_xpath_compile_node_test(env, expr); + + if(!node_test) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NodeTest expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op_predicate = axiom_xpath_compile_predicate(env, expr); + + if(op_predicate == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Predicate expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NODE_TEST, node_test, + axiom_xpath_create_axis(env, axis), op_predicate); +} + +axiom_xpath_node_test_t* +axiom_xpath_compile_node_test( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t* name; + axiom_xpath_node_test_t *node_test; + + node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t)); + node_test->type = AXIOM_XPATH_NODE_TEST_NONE; + node_test->prefix = NULL; + node_test->name = NULL; + node_test->lit = NULL; + + if(AXIOM_XPATH_CURRENT == '*') + { + AXIOM_XPATH_READ(1); + + node_test->type = AXIOM_XPATH_NODE_TEST_ALL; + + return node_test; + } + + name = axiom_xpath_compile_ncname(env, expr); + + if(!name) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NCName expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + AXIS2_FREE(env->allocator, node_test); + + return NULL; + } + + /* Node type */ + + if(AXIOM_XPATH_CURRENT == '(') + { + AXIOM_XPATH_READ(1); + + if(axutil_strcmp(name, "comment") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_COMMENT; + } + if(axutil_strcmp(name, "node") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_NODE; + } + if(axutil_strcmp(name, "processing-instruction") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_PI; + + node_test->lit = axiom_xpath_compile_literal(env, expr); + } + if(axutil_strcmp(name, "text") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_TEXT; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE || AXIOM_XPATH_CURRENT != ')') + { +#ifdef AXIOM_XPATH_DEBUG + printf("Parse error: Invalid node type - %s\n", name); +#endif + + AXIS2_FREE(env->allocator, node_test); + + return NULL; + } + + AXIOM_XPATH_READ(1); + } + else + { + node_test->type = AXIOM_XPATH_NODE_TEST_STANDARD; + + if(AXIOM_XPATH_CURRENT == ':') + { + AXIOM_XPATH_READ(1); + + node_test->prefix = name; + + if(AXIOM_XPATH_CURRENT == '*') + { + AXIOM_XPATH_READ(1); + + node_test->type = AXIOM_XPATH_NODE_TEST_ALL; + + return node_test; + } + + node_test->name = axiom_xpath_compile_ncname(env, expr); + + if(!node_test->name) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NCName expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + AXIS2_FREE(env->allocator, node_test); + + return NULL; + } + } + else + { + node_test->name = name; + } + } + + return node_test; +} + +int +axiom_xpath_compile_function_call( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t *name; + int op1 = AXIOM_XPATH_PARSE_END; + + name = axiom_xpath_compile_ncname(env, expr); + + if(!name) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NCName expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + if(AXIOM_XPATH_CURRENT != '(') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: '(' expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(1); + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT != ')') + { + op1 = axiom_xpath_compile_argument(env, expr); + } + + if(AXIOM_XPATH_CURRENT != ')') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: ')' expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(1); + + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_FUNCTION_CALL, name, NULL, op1); +} + +int +axiom_xpath_compile_argument( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1 = AXIOM_XPATH_PARSE_END; + int op2 = AXIOM_XPATH_PARSE_END; + + op1 = axiom_xpath_compile_orexpr(env, expr); + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT == ',') + { + op2 = axiom_xpath_compile_argument(env, expr); + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_ARGUMENT, op1, op2); +} + +axiom_xpath_node_test_t* +axiom_xpath_create_node_test_all( + const axutil_env_t *env) +{ + axiom_xpath_node_test_t *node_test; + + node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t)); + node_test->type = AXIOM_XPATH_NODE_TEST_ALL; + node_test->prefix = NULL; + node_test->name = NULL; + node_test->lit = NULL; + + return node_test; +} + +axiom_xpath_node_test_t* +axiom_xpath_create_node_test_node( + const axutil_env_t *env) +{ + axiom_xpath_node_test_t *node_test; + + node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t)); + node_test->type = AXIOM_XPATH_NODE_TYPE_NODE; + node_test->prefix = NULL; + node_test->name = NULL; + node_test->lit = NULL; + + return node_test; +} + +double* +axiom_xpath_compile_number( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + double *ret = AXIS2_MALLOC(env->allocator, sizeof(double)); + double res = 0, dec = 0.1; + axis2_bool_t dot = AXIS2_FALSE; + + *ret = 0; + + while(1) + { + if(isdigit(AXIOM_XPATH_CURRENT)) + { + if(!dot) + { + res = res * 10 + (AXIOM_XPATH_CURRENT - '0'); + } + else + { + res += dec * (AXIOM_XPATH_CURRENT - '0'); + dec /= 10; + } + } + else if(AXIOM_XPATH_CURRENT == '.') + { + if(dot) + { + return ret; + } + else + { + dot = AXIS2_TRUE; + dec = 0.1; + } + } + else + { + break; + } + + AXIOM_XPATH_READ(1); + } + + *ret = res; + return ret; +} + +axis2_char_t* +axiom_xpath_compile_literal( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t lit[255]; + int i = 0; + axis2_char_t del; + + if(AXIOM_XPATH_CURRENT == '\"') + { + del = '\"'; + } + else if(AXIOM_XPATH_CURRENT == '\'') + { + del = '\''; + } + else + return NULL; + + AXIOM_XPATH_READ(1); + + while(AXIOM_XPATH_HAS_MORE && AXIOM_XPATH_CURRENT != del) + { + lit[i] = AXIOM_XPATH_CURRENT; + AXIOM_XPATH_READ(1); + ++i; + } + + if(AXIOM_XPATH_HAS_MORE) + { + AXIOM_XPATH_READ(1); + } + + lit[i] = '\0'; + + return axutil_strdup(env, lit); + +} + +/* Get axis for name */ +axiom_xpath_axis_t +axiom_xpath_get_axis( + const axutil_env_t *env, + axis2_char_t* name) +{ + if(axutil_strcmp(name, "child") == 0) + { + return AXIOM_XPATH_AXIS_CHILD; + } + else if(axutil_strcmp(name, "descendant") == 0) + { + return AXIOM_XPATH_AXIS_DESCENDANT; + } + else if(axutil_strcmp(name, "parent") == 0) + { + return AXIOM_XPATH_AXIS_PARENT; + } + else if(axutil_strcmp(name, "ancestor") == 0) + { + return AXIOM_XPATH_AXIS_ANCESTOR; + } + else if(axutil_strcmp(name, "following-sibling") == 0) + { + return AXIOM_XPATH_AXIS_FOLLOWING_SIBLING; + } + else if(axutil_strcmp(name, "preceding-sibling") == 0) + { + return AXIOM_XPATH_AXIS_PRECEDING_SIBLING; + } + else if(axutil_strcmp(name, "following") == 0) + { + return AXIOM_XPATH_AXIS_FOLLOWING; + } + else if(axutil_strcmp(name, "preceding") == 0) + { + return AXIOM_XPATH_AXIS_PRECEDING; + } + else if(axutil_strcmp(name, "attribute") == 0) + { + return AXIOM_XPATH_AXIS_ATTRIBUTE; + } + else if(axutil_strcmp(name, "namespace") == 0) + { + return AXIOM_XPATH_AXIS_NAMESPACE; + } + else if(axutil_strcmp(name, "self") == 0) + { + return AXIOM_XPATH_AXIS_SELF; + } + else if(axutil_strcmp(name, "descendant-or-self") == 0) + { + return AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF; + } + else if(axutil_strcmp(name, "ancestor-or-self") == 0) + { + return AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF; + } + else + { +#ifdef AXIOM_XPATH_DEBUG + printf("Unidentified axis name.\n"); +#endif + + return AXIOM_XPATH_AXIS_NONE; + } +} + +/* Parse Predicate */ +int +axiom_xpath_compile_predicate( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op_next_predicate; + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(!AXIOM_XPATH_HAS_MORE || AXIOM_XPATH_CURRENT != '[') + { + return AXIOM_XPATH_PARSE_END; + } + + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + + /* A PredicateExpr is evaluated by evaluating the Expr and converting the result to a boolean. + If the result is a number, the result will be converted to true if the number is equal to the + context position and will be converted to false otherwise; if the result is not a number, + then the result will be converted as if by a call to the boolean function. */ + + op1 = axiom_xpath_compile_orexpr(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: EqualExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT != ']') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: ] expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(1); + + op_next_predicate = axiom_xpath_compile_predicate(env, expr); + + if(op_next_predicate == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Predicate expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_PREDICATE, op1, op_next_predicate); +} + +/* Parse Node Test */ +axis2_char_t * +axiom_xpath_compile_ncname( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t name[255]; + int i = 0; + + if(!isalpha(AXIOM_XPATH_CURRENT) && AXIOM_XPATH_CURRENT != '_') + { + return NULL; + } + + /* TODO: Add CombiningChar and Extender + * Link http://www.w3.org/TR/REC-xml/#NT-NameChar */ + while(AXIOM_XPATH_HAS_MORE && (isalnum(AXIOM_XPATH_CURRENT) || AXIOM_XPATH_CURRENT == '_' + || AXIOM_XPATH_CURRENT == '.' || AXIOM_XPATH_CURRENT == '-')) + { + name[i] = AXIOM_XPATH_CURRENT; + AXIOM_XPATH_READ(1); + ++i; + } + + name[i] = '\0'; + + return axutil_strdup(env, name); +} + +/* Supporting functions */ +int +axiom_xpath_add_operation( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + axiom_xpath_operation_type_t op_type, + int op1, + int op2, + void *par1, + void *par2) +{ + axiom_xpath_operation_t *op; + + op = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_operation_t)); + op->opr = op_type; + op->op1 = op1; + op->op2 = op2; + + op->pos = 0; + + op->par1 = par1; + op->par2 = par2; + + axutil_array_list_add(expr->operations, env, op); + + return axutil_array_list_size(expr->operations, env) - 1; +} + +axiom_xpath_axis_t * +axiom_xpath_create_axis( + const axutil_env_t *env, + axiom_xpath_axis_t axis) +{ + axiom_xpath_axis_t *axis_p = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_axis_t)); + + *axis_p = axis; + return axis_p; +} diff --git a/axiom/src/xpath/xpath_internals_parser.h b/axiom/src/xpath/xpath_internals_parser.h new file mode 100755 index 0000000..7d1a2d0 --- /dev/null +++ b/axiom/src/xpath/xpath_internals_parser.h @@ -0,0 +1,421 @@ + +/* + * 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. + */ + +#ifndef AXIOM_XPATH_INTERNALS_PARSER_H +#define AXIOM_XPATH_INTERNALS_PARSER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_xpath_parser parser + * @ingroup axiom_xpath + * @{ + */ + + + /* Macros */ + + /** Get the current character in the expression */ +#define AXIOM_XPATH_CURRENT (expr->expr_ptr < expr->expr_len ? \ + expr->expr_str[expr->expr_ptr] : -1) + + /** Get a character after the current */ +#define AXIOM_XPATH_NEXT(ind) (expr->expr_ptr + ind < expr->expr_len ? \ + expr->expr_str[expr->expr_ptr + ind] : -1) + + /** Increment the pointer to the expression */ +#define AXIOM_XPATH_READ(n) (expr->expr_ptr += n) + + /** Check if expression has finished parsing */ +#define AXIOM_XPATH_HAS_MORE (expr->expr_ptr < expr->expr_len) + + /** Skip white spaces */ +#define AXIOM_XPATH_SKIP_WHITESPACES \ + { while(AXIOM_XPATH_CURRENT == ' ') \ + AXIOM_XPATH_READ(1); \ + } + + /** Wrape an operation in a self_or_descendent step; used to handle '//' */ +#define AXIOM_XPATH_WRAP_SELF_DESCENDANT(_op2) \ + axiom_xpath_add_operation(env, expr, AXIOM_XPATH_OPERATION_STEP, \ + axiom_xpath_add_operation(env, expr, AXIOM_XPATH_OPERATION_NODE_TEST, \ + AXIOM_XPATH_PARSE_END, AXIOM_XPATH_PARSE_END, \ + axiom_xpath_create_node_test_node(env), \ + axiom_xpath_create_axis(env, AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF)), \ + _op2, NULL, NULL) + + /** Adds an operation */ +#define AXIOM_XPATH_PUSH(_opr, _op1, _op2) axiom_xpath_add_operation( \ + env, expr, _opr, _op1, _op2, NULL, NULL) + + /** Adds an operation with parameters */ +#define AXIOM_XPATH_PUSH_PAR(_opr, _par1, _par2, _op1) axiom_xpath_add_operation( \ + env, expr, _opr, _op1, AXIOM_XPATH_PARSE_END, (void *)_par1, (void *)_par2) + + /* Functions */ + + /** + * Add an operation to the operations array + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @param op_type Type of the operation + * @param op1 First operand + * @param op2 Second operand + * @param par1 First parameter + * @param par2 Second parameter + * @return Index of the operation in the array + */ + int axiom_xpath_add_operation( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + axiom_xpath_operation_type_t op_type, + int op1, + int op2, + void *par1, + void *par2); + + /** + * Compile a XPath expression + * + * [14] Expr ::= OrExpr + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the main operation in the array + */ + int axiom_xpath_compile( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile an equals expression + * + * ***Not completed*** + * [23] EqualityExpr ::= UnionExpr '=' UnionExpr + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_equalexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile an union + * + * [18] UnionExpr ::= PathExpr + * | UnionExpr '|' PathExpr + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_union( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a path expression + * + * [19] PathExpr ::= LocationPath + * | FilterExpr + * | FilterExpr '/' RelativeLocationPath + * | FilterExpr '//' RelativeLocationPath + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_path_expression( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a path expression with a filter + * + * [19] PathExpr ::= FilterExpr + * | FilterExpr '/' RelativeLocationPath + * | FilterExpr '//' RelativeLocationPath + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_path_compile_path_expression_filter( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a filter expression + * + * 20] FilterExpr ::= PrimaryExpr + * | FilterExpr Predicate + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_filter( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a location path + * + * [1] LocationPath ::= RelativeLocationPath + * | AbsoluteLocationPath + * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? + * | AbbreviatedAbsoluteLocationPath + * + * [10] AbbreviatedAbsoluteLocationPath ::= '//' RelativeLocationPath + * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_location_path( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a relative location + * + * [3] RelativeLocationPath ::= Step + * | RelativeLocationPath '/' Step + * | AbbreviatedRelativeLocationPath + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_relative_location( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a step + * + * [4] Step ::= AxisSpecifier NodeTest Predicate* + * | AbbreviatedStep + * [5] AxisSpecifier ::= AxisName '::' + * | AbbreviatedAxisSpecifier + * + * [12] AbbreviatedStep ::= '.' | '..' + * [13] AbbreviatedAxisSpecifier ::= '@'? + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_step( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compiles an OrExpr. + * + * [21] OrExpr ::= AndExpr + * | OrExpr 'or' AndExpr + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_orexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compiles an AndExpr. + * + * [22] AndExpr ::= EqualityExpr + * | AndExpr 'and' EqualityExpr + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_andexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + + /** + * Compiles a FunctionCall + * + * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument )* )? ')' + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_function_call( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compiles an Argument. + * + * [17] Argument ::= Expr + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_argument( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a node test + * + * [7] NodeTest ::= NameTest + * | NodeType '(' ')' + * | 'processing-instruction' '(' Literal ')' + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + axiom_xpath_node_test_t* axiom_xpath_compile_node_test( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a predicate(s) + * + * [8] Predicate ::= '[' PredicateExpr ']' + * [9] PredicateExpr ::= Expr + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return Index of the operation in the array + */ + int axiom_xpath_compile_predicate( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + + + /** + * Compile a literal + * + * [29] Literal ::= '"' [^"]* '"' + * | "'" [^']* "'" + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return The literal parsed + */ + axis2_char_t* axiom_xpath_compile_literal( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a number + * + * [30] Number ::= Digits ('.' Digits?)? + * | '.' Digits + * [31] Digits ::= [0-9]+ + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return The number parsed + */ + double* axiom_xpath_compile_number( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + /** + * Compile a ncname + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @return The ncname parsed + */ + axis2_char_t* axiom_xpath_compile_ncname( + const axutil_env_t *env, + axiom_xpath_expression_t* expr); + + + + /** + * Get the XPath axis by axis name + * + * [6] AxisName ::= 'ancestor' + * | 'ancestor-or-self' + * | 'attribute' + * | 'child' + * | 'descendant' + * | 'descendant-or-self' + * | 'following' + * | 'following-sibling' + * | 'namespace' + * | 'parent' + * | 'preceding' + * | 'preceding-sibling' + * | 'self' + * + * @param env Environment must not be null + * @param name Name of the axis + * @return XPath axis; returns AXIOM_XPATH_AXIS_NONE if invalid name + */ + axiom_xpath_axis_t axiom_xpath_get_axis( + const axutil_env_t *env, + axis2_char_t* name); + + /** + * Create a node test which matches all nodes (*) + * + * @param env Environment must not be null + * @return Node test + */ + axiom_xpath_node_test_t* axiom_xpath_create_node_test_all( + const axutil_env_t *env); + + /** + * Create a node test which matches all nodes (nodes()) + * + * @param env Environment must not be null + * @return Node test + */ + axiom_xpath_node_test_t* axiom_xpath_create_node_test_node( + const axutil_env_t *env); + + /** + * Create a pointer to an axis; allocate memory using the allocator + * + * @param env Environment must not be null + * @param axis XPath axis + * @return Pointer to the axis created + */ + axiom_xpath_axis_t *axiom_xpath_create_axis( + const axutil_env_t *env, + axiom_xpath_axis_t axis); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/axiom/src/xpath/xpath_streaming.c b/axiom/src/xpath/xpath_streaming.c new file mode 100755 index 0000000..0488d5f --- /dev/null +++ b/axiom/src/xpath/xpath_streaming.c @@ -0,0 +1,213 @@ +/* + * 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_xpath.h> +#include "xpath_streaming.h" +#include "xpath_internals.h" +#include "xpath_internals_engine.h" + +axiom_xpath_streaming_t +axiom_xpath_streaming_check_operation( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + int op_p) +{ + axiom_xpath_operation_t *op; + + if(op_p == AXIOM_XPATH_PARSE_END) + { + return AXIOM_XPATH_STREAMING_CONSTANT; + } + + op = AXIOM_XPATH_OPR_EXPR_GET(op_p); + + switch(op->opr) + { + case AXIOM_XPATH_OPERATION_CONTEXT_NODE: + case AXIOM_XPATH_OPERATION_ROOT_NODE: + return axiom_xpath_streaming_combine_dependent(AXIOM_XPATH_CHECK(op->op1), + AXIOM_XPATH_STREAMING_CONSTANT); + + case AXIOM_XPATH_OPERATION_STEP: + return axiom_xpath_streaming_combine_dependent(AXIOM_XPATH_CHECK(op->op1), + AXIOM_XPATH_CHECK(op->op2)); + + case AXIOM_XPATH_OPERATION_RESULT: + return AXIOM_XPATH_STREAMING_CONSTANT; + + case AXIOM_XPATH_OPERATION_UNION: + return axiom_xpath_streaming_combine_independent(AXIOM_XPATH_CHECK(op->op1), + AXIOM_XPATH_CHECK(op->op2)); + + case AXIOM_XPATH_OPERATION_EQUAL_EXPR: + return axiom_xpath_streaming_combine_independent(AXIOM_XPATH_CHECK(op->op1), + AXIOM_XPATH_CHECK(op->op2)); + + case AXIOM_XPATH_OPERATION_LITERAL: + return AXIOM_XPATH_STREAMING_CONSTANT; + + case AXIOM_XPATH_OPERATION_NUMBER: + return AXIOM_XPATH_STREAMING_CONSTANT; + + case AXIOM_XPATH_OPERATION_PATH_EXPRESSION: + return axiom_xpath_streaming_combine_dependent(AXIOM_XPATH_CHECK(op->op1), + AXIOM_XPATH_CHECK(op->op2)); + + case AXIOM_XPATH_OPERATION_NODE_TEST: + return axiom_xpath_streaming_check_node_test(env, expr, op); + + case AXIOM_XPATH_OPERATION_PREDICATE: + return axiom_xpath_streaming_check_predicate(env, expr, op_p); + + default: +#ifdef AXIOM_XPATH_DEBUG + printf("Unidentified operation.\n"); +#endif + + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } +} + +axiom_xpath_streaming_t +axiom_xpath_streaming_check_predicate( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + int op_p) +{ + axiom_xpath_operation_t *op; + + if(op_p == AXIOM_XPATH_PARSE_END) + { + return AXIOM_XPATH_STREAMING_CONSTANT; + } + + op = AXIOM_XPATH_OPR_EXPR_GET(op_p); + + return axiom_xpath_streaming_combine_dependent(AXIOM_XPATH_CHECK(op->op1), AXIOM_XPATH_CHECK( + op->op2)); +} + +axiom_xpath_streaming_t +axiom_xpath_streaming_check_node_test( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + axiom_xpath_operation_t *op) +{ + axiom_xpath_axis_t axis = AXIOM_XPATH_AXIS_NONE; + axiom_xpath_streaming_t r; + + if(!op->par2) + { +#ifdef AXIOM_XPATH_DEBUG + printf("axis is NULL in the step operator\n"); +#endif + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } + + axis = *((axiom_xpath_axis_t *)op->par2); + + switch(axis) + { + case AXIOM_XPATH_AXIS_ATTRIBUTE: + case AXIOM_XPATH_AXIS_CHILD: + break; + + default: + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } + + r = axiom_xpath_streaming_check_predicate(env, expr, op->op1); + + if(r != AXIOM_XPATH_STREAMING_ATTRIBUTE && r != AXIOM_XPATH_STREAMING_CONSTANT) + { + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } + + if(axis == AXIOM_XPATH_AXIS_ATTRIBUTE) + { + return AXIOM_XPATH_STREAMING_ATTRIBUTE; + } + else + { + return AXIOM_XPATH_STREAMING_SUPPORTED; + } +} + +axiom_xpath_streaming_t +axiom_xpath_streaming_combine_dependent( + axiom_xpath_streaming_t r1, + axiom_xpath_streaming_t r2) +{ + if(r1 == AXIOM_XPATH_STREAMING_NOT_SUPPORTED || r2 == AXIOM_XPATH_STREAMING_NOT_SUPPORTED) + { + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } + else if(r1 == AXIOM_XPATH_STREAMING_SUPPORTED || r2 == AXIOM_XPATH_STREAMING_SUPPORTED) + { + return AXIOM_XPATH_STREAMING_SUPPORTED; + } + else if(r1 == AXIOM_XPATH_STREAMING_ATTRIBUTE || r2 == AXIOM_XPATH_STREAMING_ATTRIBUTE) + { + return AXIOM_XPATH_STREAMING_ATTRIBUTE; + } + else + { + return AXIOM_XPATH_STREAMING_CONSTANT; + } +} + +axiom_xpath_streaming_t +axiom_xpath_streaming_combine_independent( + axiom_xpath_streaming_t r1, + axiom_xpath_streaming_t r2) +{ + if(r1 == AXIOM_XPATH_STREAMING_NOT_SUPPORTED || r2 == AXIOM_XPATH_STREAMING_NOT_SUPPORTED) + { + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } + else if(r1 == AXIOM_XPATH_STREAMING_CONSTANT || r2 == AXIOM_XPATH_STREAMING_CONSTANT) + { + if(r1 == AXIOM_XPATH_STREAMING_SUPPORTED || r2 == AXIOM_XPATH_STREAMING_SUPPORTED) + { + return AXIOM_XPATH_STREAMING_SUPPORTED; + } + else if(r1 == AXIOM_XPATH_STREAMING_ATTRIBUTE || r2 == AXIOM_XPATH_STREAMING_ATTRIBUTE) + { + return AXIOM_XPATH_STREAMING_ATTRIBUTE; + } + else + { + return AXIOM_XPATH_STREAMING_CONSTANT; + } + } + else if(r1 == AXIOM_XPATH_STREAMING_ATTRIBUTE || r2 == AXIOM_XPATH_STREAMING_ATTRIBUTE) + { + if(r1 == AXIOM_XPATH_STREAMING_SUPPORTED || r2 == AXIOM_XPATH_STREAMING_SUPPORTED) + { + return AXIOM_XPATH_STREAMING_SUPPORTED; + } + else + { + return AXIOM_XPATH_STREAMING_ATTRIBUTE; + } + } + else + { + return AXIOM_XPATH_STREAMING_NOT_SUPPORTED; + } +} + diff --git a/axiom/src/xpath/xpath_streaming.h b/axiom/src/xpath/xpath_streaming.h new file mode 100755 index 0000000..63b1ee5 --- /dev/null +++ b/axiom/src/xpath/xpath_streaming.h @@ -0,0 +1,126 @@ + +/* + * 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. + */ + +#ifndef AXIOM_XPATH_STREAMING_H +#define AXIOM_XPATH_STREAMING_H + +#include "xpath_internals.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @defgroup axiom_xpath_streaming streaming + * @ingroup axiom_xpath + * @{ + */ + + + /** + * XPath streaming support + */ + typedef enum axiom_xpath_streaming_t + { + AXIOM_XPATH_STREAMING_NOT_SUPPORTED = 0, + AXIOM_XPATH_STREAMING_SUPPORTED, + AXIOM_XPATH_STREAMING_CONSTANT, + AXIOM_XPATH_STREAMING_ATTRIBUTE + } axiom_xpath_streaming_t; + + /** Check whether the given expression is supported on streaming XML */ +#define AXIOM_XPATH_CHECK(op) axiom_xpath_streaming_check_operation(env, expr, op) + + /** Get an operation from the list of operations */ +#define AXIOM_XPATH_OPR_EXPR_GET(ind) (axiom_xpath_operation_t *) \ + axutil_array_list_get(expr->operations, env, ind) + + /** + * Checks whether the given expression is supported on streaming XML + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @param op_p Index of the operation in the list of operations + * @return Whether the given operation can be evaluated on streaming XML + */ + axiom_xpath_streaming_t axiom_xpath_streaming_check_operation( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + int op_p); + + /** + * Checks whether the predicate is supported on streaming XML. + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @param op_p Index of the operation in the list of operations + * @return Whether the given operation can be evaluated on streaming XML + */ + axiom_xpath_streaming_t axiom_xpath_streaming_check_predicate( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + int op_p); + + /** + * Checks whether the predicate is supported on streaming XML. + * + * @param env Environment must not be null + * @param expr A pointer to the XPath expression + * @param op Index of the operation in the list of operations + * @return Whether the given operation can be evaluated on streaming XML + */ + axiom_xpath_streaming_t axiom_xpath_streaming_check_node_test( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + axiom_xpath_operation_t* op); + + + /** + * Checks whether the two operations can be evaluated on streaming XML + * sequencially (one after the other), where the result of the first + * operation is the context of the next + * + * @param r1 Type of first operation + * @param r2 Type of second operation + * @return Whether the given operations can be evaluated on streaming XML + */ + axiom_xpath_streaming_t axiom_xpath_streaming_combine_dependent( + axiom_xpath_streaming_t r1, + axiom_xpath_streaming_t r2); + + + /** + * Checks whether the two operations can be evaluated on streaming XML + * simultaneousy + * + * @param r1 Type of first operation + * @param r2 Type of second operation + * @return Whether the given operations can be evaluated on streaming XML + */ + axiom_xpath_streaming_t axiom_xpath_streaming_combine_independent( + axiom_xpath_streaming_t r1, + axiom_xpath_streaming_t r2); + + /** @} */ + +#ifdef __cplusplus +} +#endif + +#endif |