commting AXIS2C-1645 patch
diff --git a/configure.ac b/configure.ac
index 0d0a308..dd2f3d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -496,6 +496,29 @@
CPPFLAGS="$CPPFLAGS"
)
+AC_MSG_CHECKING(whether to use JSON)
+AC_ARG_ENABLE(json, [ --enable-json
+ enable json support (default=no)],
+[ case "${enableval}" in
+ no)
+ AC_MSG_RESULT(no)
+ CFLAGS="$CFLAGS"
+ CPPFLAGS="$CPPFLAGS"
+ json_enabled=false
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ CFLAGS="$CFLAGS $JSON_CFLAGS -DAXIS2_JSON_ENABLED"
+ CPPFLAGS="$CPPFLAGS $JSON_LIBS -DAXIS2_JSON_ENABLED"
+ json_enabled=true
+ PKG_CHECK_MODULES(JSON, json)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+ CFLAGS="$CFLAGS"
+ CPPFLAGS="$CPPFLAGS"
+)
+
APACHE2INC=$apache2inc
OPENSSLINC=$opensslinc
@@ -529,6 +552,7 @@
AC_SUBST(ZLIBBUILD)
AM_CONDITIONAL(AXIS2_SSL_ENABLED, test x$ssl_enabled = xtrue)
AM_CONDITIONAL(AXIS2_LIBCURL_ENABLED, test x$libcurl_enabled = xtrue)
+AM_CONDITIONAL(AXIS2_JSON_ENABLED, test x$json_enabled = xtrue)
export NTLM_LDFLAGS
export WRAPPER_DIR
diff --git a/include/axis2_http_transport.h b/include/axis2_http_transport.h
index 7bf5c53..f39b7d4 100644
--- a/include/axis2_http_transport.h
+++ b/include/axis2_http_transport.h
@@ -742,6 +742,13 @@
*/
#define AXIS2_HTTP_HEADER_ACCEPT_MULTIPART_RELATED AXIOM_MIME_TYPE_MULTIPART_RELATED
+#ifdef AXIS2_JSON_ENABLED
+ /**
+ * AXIS2_HTTP_HEADER_ACCEPT_JSON
+ */
+#define AXIS2_HTTP_HEADER_ACCEPT_JSON "application/json"
+#endif
+
/**
* HEADER_ACCEPT_APPLICATION_DIME
*/
diff --git a/include/axis2_json_reader.h b/include/axis2_json_reader.h
new file mode 100644
index 0000000..cd8ff04
--- /dev/null
+++ b/include/axis2_json_reader.h
@@ -0,0 +1,186 @@
+/*
+ * Licensed 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 AXIS2_JSON_READER_H
+#define AXIS2_JSON_READER_H
+
+#include <axutil_utils.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct axutil_stream axutil_stream_t;
+typedef struct axiom_node axiom_node_t;
+typedef struct axutil_env axutil_env_t;
+typedef struct axis2_json_reader axis2_json_reader_t;
+
+/**
+ * @brief Creates JSON reader to read data from stream
+ * @param env Environment
+ * @param stream Stream to read data from
+ */
+AXIS2_EXTERN axis2_json_reader_t* AXIS2_CALL
+axis2_json_reader_create_for_stream(
+ const axutil_env_t* env,
+ axutil_stream_t* stream);
+
+
+/**
+ * @brief Creates JSON reader to read data from string
+ * @param env Environment
+ * @param json_string JSON string
+ * @param json_string_size JSON string
+ */
+AXIS2_EXTERN axis2_json_reader_t* AXIS2_CALL
+axis2_json_reader_create_for_memory(
+ const axutil_env_t* env,
+ const axis2_char_t* json_string,
+ int json_string_size);
+
+
+/**
+ * @brief Destroys reader
+ * does not free root node.
+ * user must free axiom tree using axiom_node_free_tree()
+ * @param reader JSON reader
+ * @param env Environment
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_reader_free(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Starts reading from string or stream
+ * @param reader JSON reader
+ * @param env Environment
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_json_reader_read(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Gets root node of parsed data
+ * @param reader JSON reader
+ * @param env Environment
+ */
+AXIS2_EXTERN axiom_node_t* AXIS2_CALL
+axis2_json_reader_get_root_node(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*
+ * Copyright 2013 Utkin Dmitry
+ *
+ * Licensed 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 AXIS2_JSON_READER_H
+#define AXIS2_JSON_READER_H
+
+#include <axutil_utils_defines.h>
+#include <axutil_stream.h>
+#include <axiom_node.h>
+#include <axutil_env.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct axis2_json_reader axis2_json_reader_t;
+
+/**
+ * @brief Creates JSON reader to read data from stream
+ * @param env Environment
+ * @param stream Stream to read data from
+ */
+AXIS2_EXTERN axis2_json_reader_t* AXIS2_CALL
+axis2_json_reader_create_for_stream(
+ const axutil_env_t* env,
+ axutil_stream_t* stream);
+
+
+/**
+ * @brief Creates JSON reader to read data from string
+ * @param env Environment
+ * @param json_string JSON string
+ * @param json_string_size JSON string
+ */
+AXIS2_EXTERN axis2_json_reader_t* AXIS2_CALL
+axis2_json_reader_create_for_memory(
+ const axutil_env_t* env,
+ const axis2_char_t* json_string,
+ int json_string_size);
+
+
+/**
+ * @brief Destroys reader
+ * does not free root node.
+ * user must free axiom tree using axiom_node_free_tree()
+ * @param reader JSON reader
+ * @param env Environment
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_reader_free(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Starts reading from string or stream
+ * @param reader JSON reader
+ * @param env Environment
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_json_reader_read(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Gets root node of parsed data
+ * @param reader JSON reader
+ * @param env Environment
+ */
+AXIS2_EXTERN axiom_node_t* AXIS2_CALL
+axis2_json_reader_get_root_node(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/axis2_json_writer.h b/include/axis2_json_writer.h
new file mode 100644
index 0000000..729bba4
--- /dev/null
+++ b/include/axis2_json_writer.h
@@ -0,0 +1,156 @@
+/*
+ * Licensed 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 AXIS2_JSON_WRITER_H
+#define AXIS2_JSON_WRITER_H
+
+#include <axutil_utils.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct axiom_node axiom_node_t;
+typedef struct axutil_env axutil_env_t;
+typedef struct axis2_json_writer axis2_json_writer_t;
+
+/**
+ * @brief Creates JSON writer
+ * @param env Environment
+ */
+AXIS2_EXTERN axis2_json_writer_t* AXIS2_CALL
+axis2_json_writer_create(
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Destroys writer
+ * @param writer JSON writer
+ * @param env Environment
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_writer_free(
+ axis2_json_writer_t* writer,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Starts writing to JSON
+ * @param writer JSON writer
+ * @param node Source OM node
+ * @param env Environment
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_writer_write(
+ axis2_json_writer_t* writer,
+ const axiom_node_t* node,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Gets resulting JSON string
+ * @param writer JSON writer
+ * @param env Environment
+ */
+AXIS2_EXTERN const axis2_char_t* AXIS2_CALL
+axis2_json_writer_get_json_string(
+ axis2_json_writer_t* writer,
+ const axutil_env_t* env,
+ int* json_string_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*
+ * Copyright 2013 Utkin Dmitry
+ *
+ * Licensed 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 AXIS2_JSON_WRITER_H
+#define AXIS2_JSON_WRITER_H
+
+#include <axutil_utils_defines.h>
+#include <axiom_node.h>
+#include <axutil_env.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct axis2_json_writer axis2_json_writer_t;
+
+/**
+ * @brief Creates JSON writer
+ * @param env Environment
+ */
+AXIS2_EXTERN axis2_json_writer_t* AXIS2_CALL
+axis2_json_writer_create(
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Destroys writer
+ * @param writer JSON writer
+ * @param env Environment
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_writer_free(
+ axis2_json_writer_t* writer,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Starts writing to JSON
+ * @param writer JSON writer
+ * @param node Source OM node
+ * @param env Environment
+ */
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_writer_write(
+ axis2_json_writer_t* writer,
+ const axiom_node_t* node,
+ const axutil_env_t* env);
+
+
+/**
+ * @brief Gets resulting JSON string
+ * @param writer JSON writer
+ * @param env Environment
+ */
+AXIS2_EXTERN const axis2_char_t* AXIS2_CALL
+axis2_json_writer_get_json_string(
+ axis2_json_writer_t* writer,
+ const axutil_env_t* env,
+ int* json_string_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/axis2_msg_ctx.h b/include/axis2_msg_ctx.h
index b1d4d0f..e1b7395 100644
--- a/include/axis2_msg_ctx.h
+++ b/include/axis2_msg_ctx.h
@@ -2088,6 +2088,17 @@
const axutil_env_t * env);
+#ifdef AXIS2_JSON_ENABLED
+ AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+ axis2_msg_ctx_get_doing_json(
+ const axis2_msg_ctx_t *msg_ctx,
+ const axutil_env_t *env);
+
+ AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_msg_ctx_set_doing_json(axis2_msg_ctx_t *msg_ctx,
+ const axutil_env_t *env,
+ const axis2_bool_t doing_json);
+#endif
/** @} */
diff --git a/src/core/context/msg_ctx.c b/src/core/context/msg_ctx.c
index 7a1523e..f4c4a40 100644
--- a/src/core/context/msg_ctx.c
+++ b/src/core/context/msg_ctx.c
@@ -127,6 +127,11 @@
/** Rest through HTTP POST? */
axis2_bool_t do_rest_through_post;
+#ifdef AXIS2_JSON_ENABLED
+ /** are we doing json now? */
+ axis2_bool_t doing_json;
+#endif
+
/** Session management enabled? */
axis2_bool_t manage_session;
@@ -2823,3 +2828,22 @@
}
msg_ctx->mime_parts = mime_parts;
}
+
+#ifdef AXIS2_JSON_ENABLED
+axis2_bool_t AXIS2_CALL
+axis2_msg_ctx_get_doing_json(
+ const axis2_msg_ctx_t *msg_ctx,
+ const axutil_env_t *env)
+{
+ return msg_ctx->doing_json;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+ axis2_msg_ctx_set_doing_json(axis2_msg_ctx_t *msg_ctx,
+ const axutil_env_t *env,
+ const axis2_bool_t doing_json)
+{
+ msg_ctx->doing_json = doing_json;
+ return AXIS2_SUCCESS;
+}
+#endif
diff --git a/src/core/engine/Makefile.am b/src/core/engine/Makefile.am
index 17eb157..ee935c7 100644
--- a/src/core/engine/Makefile.am
+++ b/src/core/engine/Makefile.am
@@ -59,3 +59,6 @@
EXTRA_DIST=axis2_disp_checker.h
+if AXIS2_JSON_ENABLED
+libaxis2_engine_la_LIBADD += $(JSON_LIBS)
+endif
diff --git a/src/core/transport/http/sender/Makefile.am b/src/core/transport/http/sender/Makefile.am
index dd314d3..c0c0375 100644
--- a/src/core/transport/http/sender/Makefile.am
+++ b/src/core/transport/http/sender/Makefile.am
@@ -69,3 +69,10 @@
-I$(top_builddir)/util/include \
-I$(top_builddir)/axiom/include \
$(SSL_INC)
+
+
+if AXIS2_JSON_ENABLED
+libaxis2_http_sender_la_SOURCES += axis2_json_writer.c
+libaxis2_http_sender_la_LIBADD += $(JSON_LIBS)
+INCLUDES += $(JSON_CFLAGS)
+endif
diff --git a/src/core/transport/http/sender/axis2_json_writer.c b/src/core/transport/http/sender/axis2_json_writer.c
new file mode 100644
index 0000000..e9001fe
--- /dev/null
+++ b/src/core/transport/http/sender/axis2_json_writer.c
@@ -0,0 +1,178 @@
+/*
+ * Licensed 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_attribute.h>
+#include <json.h>
+#include "axis2_json_writer.h"
+
+#define AXIS2_JSON_XSI_URI "http://www.w3.org/2001/XMLSchema-instance"
+
+struct axis2_json_writer
+{
+ json_object* json_obj;
+};
+
+axis2_bool_t axis2_json_element_is_nil(axiom_element_t* om_element, const axutil_env_t* env)
+{
+ axiom_attribute_t* attr = NULL;
+ axutil_hash_index_t* index;
+ axutil_hash_t* attr_hash = axiom_element_get_all_attributes(om_element, env);
+
+ if (!attr_hash)
+ return AXIS2_FALSE;
+
+ for (index = axutil_hash_first(attr_hash, env);
+ index; index = axutil_hash_next(env, index))
+ {
+ axutil_hash_this(index, NULL, NULL, (void**)&attr);
+ if (attr && !strcmp(axiom_attribute_get_localname(attr, env), "nil"))
+ {
+ /* found some "nil" attribute, check it namespace */
+ axutil_qname_t* qname =
+ axiom_attribute_get_qname(attr, env);
+ if (qname && !strcmp(axutil_qname_get_uri(qname, env), AXIS2_JSON_XSI_URI))
+ {
+ axis2_char_t* attr_value =
+ axiom_attribute_get_value(attr, env);
+ return (!strcmp(attr_value, "true") || !strcmp(attr_value, "1")) ?
+ AXIS2_TRUE : AXIS2_FALSE;
+ }
+ }
+ }
+
+ return AXIS2_FALSE;
+}
+
+void axis2_json_write_node(json_object* parent, axiom_node_t* om_node, const axutil_env_t* env)
+{
+ axiom_element_t* elem;
+ axiom_node_t* child_node;
+ const axis2_char_t* local_name;
+ json_object* obj;
+ json_object* array = NULL;
+
+ if (!om_node || axiom_node_get_node_type(om_node, env) != AXIOM_ELEMENT)
+ return;
+
+ elem = (axiom_element_t*)axiom_node_get_data_element(om_node, env);
+ local_name = axiom_element_get_localname(elem, env);
+
+ child_node = axiom_node_get_first_element(om_node, env);
+
+ /* find existing object */
+ if (json_object_object_get_ex(parent, local_name, &obj))
+ {
+ /* check that object is array? */
+ if (!json_object_is_type(obj, json_type_array))
+ {
+ /* convert to array */
+ obj = json_object_get(obj);
+ array = json_object_new_array();
+ json_object_array_add(array, obj);
+ json_object_object_del(parent, local_name);
+ json_object_object_add(parent, local_name, array);
+ }
+ else
+ array = obj;
+ }
+
+ if (!child_node)
+ {
+ /* this is a leaf node */
+ json_object* json_value = NULL;
+
+ /* check for nillable */
+ if (!axis2_json_element_is_nil(elem, env))
+ {
+ const axis2_char_t* value =
+ axiom_element_get_text(elem, env, om_node);
+ json_value = json_object_new_string(value ? value : "");
+ }
+
+ if (array)
+ json_object_array_add(array, json_value);
+ else
+ json_object_object_add(parent, local_name, json_value);
+ return;
+ }
+
+ /* iterate through children elements */
+ obj = json_object_new_object();
+ if (array)
+ json_object_array_add(array, obj);
+ else
+ json_object_object_add(parent, local_name, obj);
+
+ for (; child_node; child_node = axiom_node_get_next_sibling(child_node, env))
+ if (axiom_node_get_node_type(child_node, env) == AXIOM_ELEMENT)
+ axis2_json_write_node(obj, child_node, env);
+}
+
+
+AXIS2_EXTERN axis2_json_writer_t* AXIS2_CALL
+axis2_json_writer_create(
+ const axutil_env_t* env)
+{
+ axis2_json_writer_t* writer = (axis2_json_writer_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(struct axis2_json_writer));
+ if (writer)
+ writer->json_obj = NULL;
+
+ return writer;
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_writer_free(
+ axis2_json_writer_t* writer,
+ const axutil_env_t* env)
+{
+ json_object_put(writer->json_obj);
+ AXIS2_FREE(env->allocator, writer);
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_writer_write(
+ axis2_json_writer_t* writer,
+ const axiom_node_t* node,
+ const axutil_env_t* env)
+{
+ /* free existing object */
+ if (writer->json_obj)
+ json_object_put(writer->json_obj);
+
+ writer->json_obj = json_object_new_object();
+ axis2_json_write_node(writer->json_obj, (axiom_node_t*)node, env);
+}
+
+
+AXIS2_EXTERN const axis2_char_t* AXIS2_CALL
+axis2_json_writer_get_json_string(
+ axis2_json_writer_t* writer,
+ const axutil_env_t* env,
+ int* json_string_length)
+{
+ (void)env;
+ const axis2_char_t* result =
+ (const axis2_char_t*)json_object_to_json_string_ext(writer->json_obj,
+ JSON_C_TO_STRING_PLAIN);
+ if (json_string_length)
+ *json_string_length = strlen(result);
+
+ return result;
+}
+
diff --git a/src/core/transport/http/sender/http_transport_sender.c b/src/core/transport/http/sender/http_transport_sender.c
index 6dc43fa..c4b954c 100644
--- a/src/core/transport/http/sender/http_transport_sender.c
+++ b/src/core/transport/http/sender/http_transport_sender.c
@@ -35,6 +35,10 @@
#include "libcurl/axis2_libcurl.h"
#endif
+#ifdef AXIS2_JSON_ENABLED
+#include <axis2_json_writer.h>
+#endif
+
/**
* HTTP Transport Sender struct impl
* Axis2 HTTP Transport Sender impl
@@ -258,6 +262,89 @@
return AXIS2_SUCCESS;
}
+#ifdef AXIS2_JSON_ENABLED
+ if (AXIS2_TRUE == axis2_msg_ctx_get_doing_json(msg_ctx, env))
+ {
+ axis2_json_writer_t* json_writer;
+ axiom_node_t *body_node = NULL;
+ axiom_soap_body_t* soap_body =
+ axiom_soap_envelope_get_body(soap_data_out, env);
+ axutil_stream_t* out_stream =
+ axis2_msg_ctx_get_transport_out_stream(msg_ctx, env);
+
+ if (!soap_body)
+ {
+ AXIS2_ERROR_SET(env->error,
+ AXIS2_ERROR_SOAP_ENVELOPE_OR_SOAP_BODY_NULL,
+ AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s",
+ AXIS2_ERROR_GET_MESSAGE(env->error));
+ return AXIS2_FAILURE;
+ }
+
+ body_node = axiom_soap_body_get_base_node(soap_body, env);
+ if (!body_node)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ data_out = axiom_node_get_first_element(body_node, env);
+ if (!data_out || axiom_node_get_node_type(data_out, env)
+ != AXIOM_ELEMENT)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ json_writer = axis2_json_writer_create(env);
+ if (!json_writer)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Failed to create JSON writer");
+ return AXIS2_FAILURE;
+ }
+
+ axis2_json_writer_write(json_writer, data_out, env);
+
+ buffer = (axis2_char_t*)axis2_json_writer_get_json_string(
+ json_writer, env, &buffer_size);
+ if (!buffer)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Failed to get resulting JSON string");
+ return AXIS2_FAILURE;
+ }
+
+ if (AXIS2_TRUE == axis2_msg_ctx_get_server_side(msg_ctx, env))
+ {
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_http_out_transport_info_t* out_info =
+ (axis2_http_out_transport_info_t *)
+ axis2_msg_ctx_get_out_transport_info(msg_ctx, env);
+
+ if (!out_info)
+ {
+ AXIS2_HANDLE_ERROR(env,
+ AXIS2_ERROR_OUT_TRNSPORT_INFO_NULL,
+ AXIS2_FAILURE);
+ return AXIS2_FAILURE;
+ }
+
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CHAR_ENCODING(
+ out_info, env, char_set_enc);
+ AXIS2_HTTP_OUT_TRANSPORT_INFO_SET_CONTENT_TYPE(
+ out_info, env, AXIS2_HTTP_HEADER_ACCEPT_JSON);
+ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
+ axis2_op_ctx_set_response_written(op_ctx, env, AXIS2_TRUE);
+ }
+
+ axutil_stream_write(out_stream, env, buffer, buffer_size);
+
+ axis2_json_writer_free(json_writer, env);
+
+ return AXIS2_SUCCESS;
+ }
+#endif
+
xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
AXIS2_XML_PARSER_TYPE_BUFFER);
if(!xml_writer)
diff --git a/src/core/transport/http/util/Makefile.am b/src/core/transport/http/util/Makefile.am
index c0411d4..2e0267b 100644
--- a/src/core/transport/http/util/Makefile.am
+++ b/src/core/transport/http/util/Makefile.am
@@ -26,3 +26,9 @@
-I$(top_builddir)/src/core/engine \
-I$(top_builddir)/util/include \
-I$(top_builddir)/axiom/include
+
+if AXIS2_JSON_ENABLED
+libaxis2_http_util_la_SOURCES += axis2_json_reader.c
+libaxis2_http_util_la_LIBADD += $(JSON_LIBS)
+INCLUDES += $(JSON_CFLAGS)
+endif
diff --git a/src/core/transport/http/util/axis2_json_reader.c b/src/core/transport/http/util/axis2_json_reader.c
new file mode 100644
index 0000000..6cae42e
--- /dev/null
+++ b/src/core/transport/http/util/axis2_json_reader.c
@@ -0,0 +1,332 @@
+/*
+ * Licensed 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 <axutil_stream.h>
+#include <axiom_node.h>
+#include <axiom_element.h>
+#include <axiom_attribute.h>
+#include <json.h>
+#include "axis2_json_reader.h"
+
+#define AXIS2_JSON_XSI_URI "http://www.w3.org/2001/XMLSchema-instance"
+
+struct axis2_json_reader
+{
+ json_object* json_obj;
+ axiom_node_t* axiom_node;
+};
+
+const char* json_tokener_error_to_str(enum json_tokener_error error)
+{
+ switch (error)
+ {
+ case json_tokener_success:
+ return "success";
+ case json_tokener_continue:
+ return "continue";
+ case json_tokener_error_depth:
+ return "error_depth";
+ case json_tokener_error_parse_eof:
+ return "error_parse_eof";
+ case json_tokener_error_parse_unexpected:
+ return "error_parse_unexpected";
+ case json_tokener_error_parse_null:
+ return "error_parse_null";
+ case json_tokener_error_parse_boolean:
+ return "error_parse_boolean";
+ case json_tokener_error_parse_number:
+ return "error_parse_number";
+ case json_tokener_error_parse_array:
+ return "error_parse_array";
+ case json_tokener_error_parse_object_key_name:
+ return "error_parse_object_key_name";
+ case json_tokener_error_parse_object_key_sep:
+ return "error_parse_object_key_sep";
+ case json_tokener_error_parse_object_value_sep:
+ return "error_parse_object_value_sep";
+ case json_tokener_error_parse_string:
+ return "error_parse_string";
+ case json_tokener_error_parse_comment:
+ return "error_parse_comment";
+ }
+ return "UNKNOWN";
+}
+
+axis2_status_t
+axis2_json_read_node(
+ json_object* parent,
+ const char* name,
+ axiom_node_t** om_node,
+ const axutil_env_t* env);
+
+
+axis2_status_t
+axis2_json_read_child_node(
+ json_object* child_object,
+ const char* child_name,
+ axiom_node_t* om_node,
+ const axutil_env_t* env)
+{
+ axiom_node_t* child_node = NULL;
+
+ switch (json_object_get_type(child_object))
+ {
+ case json_type_object:
+ {
+ if (axis2_json_read_node(child_object, child_name, &child_node, env) != AXIS2_SUCCESS)
+ return AXIS2_FAILURE;
+ if (axiom_node_add_child(om_node, env, child_node) != AXIS2_SUCCESS)
+ return AXIS2_FAILURE;
+ break;
+ }
+
+ case json_type_array:
+ {
+ int i;
+ int array_len = json_object_array_length(child_object);
+ for (i = 0; i < array_len; ++i)
+ {
+ if (axis2_json_read_child_node(json_object_array_get_idx(child_object, i),
+ child_name, om_node, env) != AXIS2_SUCCESS)
+ return AXIS2_FAILURE;
+ }
+ break;
+ }
+
+ case json_type_int:
+ case json_type_boolean:
+ case json_type_double:
+ case json_type_string:
+ {
+ axiom_node_t* om_child_node = NULL;
+ axiom_node_t* om_text_node = NULL;
+
+ if (!axiom_element_create(env, NULL, child_name, NULL, &om_child_node))
+ return AXIS2_FAILURE;
+
+ if (!axiom_text_create(env, om_child_node, json_object_get_string(child_object),
+ &om_text_node))
+ return AXIS2_FAILURE;
+
+ if (axiom_node_add_child(om_node, env, om_child_node) != AXIS2_SUCCESS)
+ {
+ axiom_node_free_tree(om_text_node, env);
+ return AXIS2_FAILURE;
+ }
+
+ break;
+ }
+
+ case json_type_null:
+ {
+ axiom_element_t* om_child_elem = NULL;
+ axiom_node_t* om_child_node = NULL;
+
+ /* handle as nillable */
+ axiom_attribute_t* attr;
+ axiom_namespace_t* ns =
+ axiom_namespace_create(env, AXIS2_JSON_XSI_URI, "xsi");
+
+ if (!ns)
+ return AXIS2_FAILURE;
+
+ om_child_elem = axiom_element_create(env, NULL, child_name, NULL, &om_child_node);
+ if (!om_child_elem)
+ {
+ axiom_namespace_free(ns, env);
+ return AXIS2_FAILURE;
+ }
+
+ if (axiom_node_add_child(om_node, env, om_child_node) != AXIS2_SUCCESS)
+ {
+ axiom_namespace_free(ns, env);
+ axiom_node_free_tree(om_child_node, env);
+ return AXIS2_FAILURE;
+ }
+
+ attr = axiom_attribute_create(env, "nil", "true", ns);
+ if (!attr)
+ {
+ axiom_attribute_free(attr, env);
+ return AXIS2_FAILURE;
+ }
+
+ if (axiom_element_add_attribute(om_child_elem, env, attr,
+ om_child_node) != AXIS2_SUCCESS)
+ {
+ axiom_attribute_free(attr, env);
+ return AXIS2_FAILURE;
+ }
+
+ break;
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t
+axis2_json_read_node(
+ json_object* parent,
+ const char* name,
+ axiom_node_t** om_node,
+ const axutil_env_t* env)
+{
+ if (!json_object_is_type(parent, json_type_object))
+ return AXIS2_FAILURE;
+
+ axiom_element_create(env, NULL, name, NULL, om_node);
+
+ json_object_object_foreach(parent, child_name, child_object)
+ {
+ if (axis2_json_read_child_node(child_object, child_name, *om_node, env) != AXIS2_SUCCESS)
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_json_reader_t* AXIS2_CALL
+axis2_json_reader_create_for_stream(
+ const axutil_env_t* env,
+ axutil_stream_t* stream)
+{
+ axis2_json_reader_t* reader =
+ (axis2_json_reader_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(struct axis2_json_reader));
+ if (reader)
+ {
+ axis2_char_t buffer[512];
+ int readed;
+ struct json_tokener* tokener = json_tokener_new();
+ enum json_tokener_error error;
+ json_object* json_obj = NULL;
+
+ reader->json_obj = NULL;
+ reader->axiom_node = NULL;
+ do
+ {
+ readed = axutil_stream_read(stream, env, &buffer, sizeof(buffer));
+ if (readed < 0)
+ break;
+
+ json_obj = json_tokener_parse_ex(tokener, buffer, readed);
+
+ } while ((error = json_tokener_get_error(tokener)) == json_tokener_continue);
+
+ if (error != json_tokener_success)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PARAM, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to parse JSON request: %s",
+ json_tokener_error_to_str(tokener->err));
+ if (json_obj)
+ json_object_put(json_obj);
+ json_tokener_free(tokener);
+ free(reader);
+ return NULL;
+ }
+
+ reader->json_obj = json_obj;
+
+ json_tokener_free(tokener);
+ }
+
+ return reader;
+}
+
+
+AXIS2_EXTERN axis2_json_reader_t* AXIS2_CALL
+axis2_json_reader_create_for_memory(
+ const axutil_env_t* env,
+ const axis2_char_t* json_string,
+ int json_string_size)
+{
+ axis2_json_reader_t* reader =
+ (axis2_json_reader_t*)AXIS2_MALLOC(env->allocator,
+ sizeof(struct axis2_json_reader));
+ if (reader)
+ {
+ struct json_tokener* tokener = json_tokener_new();
+
+ reader->axiom_node = NULL;
+ reader->json_obj = json_tokener_parse_ex(tokener, json_string, json_string_size);
+ if (tokener->err != json_tokener_success)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PARAM, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to parse JSON request: %s",
+ json_tokener_error_to_str(tokener->err));
+ if (reader->json_obj)
+ json_object_put(reader->json_obj);
+ json_tokener_free(tokener);
+ free(reader);
+ return NULL;
+ }
+ json_tokener_free(tokener);
+ }
+
+ return reader;
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_json_reader_free(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env)
+{
+ if (reader->json_obj)
+ json_object_put(reader->json_obj);
+ AXIS2_FREE(env->allocator, reader);
+}
+
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_json_reader_read(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env)
+{
+ json_object* json_root = NULL;
+ const char* json_root_name = NULL;
+
+ /* free existing om tree */
+ if (reader->axiom_node)
+ axiom_node_free_tree(reader->axiom_node, env);
+ reader->axiom_node = NULL;
+
+ /* get first child */
+ json_object_object_foreach(reader->json_obj, key, value)
+ {
+ json_root = value;
+ json_root_name = key;
+ break;
+ }
+
+ if (!json_root || !json_root_name)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_PARAM, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed find root JSON node");
+ return AXIS2_FAILURE;
+ }
+
+ return axis2_json_read_node(json_root, json_root_name, &reader->axiom_node, env);
+}
+
+
+AXIS2_EXTERN axiom_node_t* AXIS2_CALL
+axis2_json_reader_get_root_node(
+ axis2_json_reader_t* reader,
+ const axutil_env_t* env)
+{
+ (void)env;
+ return reader->axiom_node;
+}
diff --git a/src/core/transport/http/util/http_transport_utils.c b/src/core/transport/http/util/http_transport_utils.c
index c436da8..a360d88 100644
--- a/src/core/transport/http/util/http_transport_utils.c
+++ b/src/core/transport/http/util/http_transport_utils.c
@@ -44,6 +44,10 @@
#include <axiom_mime_part.h>
#include <axutil_class_loader.h>
+#ifdef AXIS2_JSON_ENABLED
+#include <axis2_json_reader.h>
+#endif
+
#define AXIOM_MIME_BOUNDARY_BYTE 45
/** Size of the buffer to be used when reading a file */
@@ -602,6 +606,50 @@
axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type);
+
+ axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);
+
+#ifdef AXIS2_JSON_ENABLED
+ if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
+ {
+ axis2_json_reader_t* json_reader = NULL;
+ axiom_soap_body_t* soap_body = NULL;
+ axiom_node_t* root_node = NULL;
+
+ json_reader = axis2_json_reader_create_for_stream(env, in_stream);
+ if (!json_reader)
+ {
+ axis2_json_reader_free(json_reader, env);
+ return AXIS2_FAILURE;
+ }
+
+ status = axis2_json_reader_read(json_reader, env);
+ if (status != AXIS2_SUCCESS)
+ {
+ axis2_json_reader_free(json_reader, env);
+ return status;
+ }
+
+ root_node = axis2_json_reader_get_root_node(json_reader, env);
+ if (!root_node)
+ {
+ axis2_json_reader_free(json_reader, env);
+ return AXIS2_FAILURE;
+ }
+
+ axis2_json_reader_free(json_reader, env);
+
+ soap_envelope =
+ axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
+ soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+ axiom_soap_body_add_child(soap_body, env, root_node);
+ axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_POST);
+ }
+ else
+ {
+#endif
xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request,
NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env));
@@ -610,8 +658,6 @@
return AXIS2_FAILURE;
}
- axis2_msg_ctx_set_charset_encoding(msg_ctx, env, char_set_str);
-
om_builder = axiom_stax_builder_create(env, xml_reader);
if(!om_builder)
{
@@ -711,6 +757,9 @@
}
}
}
+#ifdef AXIS2_JSON_ENABLED
+ }
+#endif
if(do_rest)
{
@@ -1058,6 +1107,49 @@
axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
char_set_str = axis2_http_transport_utils_get_charset_enc(env, content_type);
+
+#ifdef AXIS2_JSON_ENABLED
+ if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
+ {
+ axis2_json_reader_t* json_reader = NULL;
+ axiom_soap_body_t* soap_body = NULL;
+ axiom_node_t* root_node = NULL;
+
+ json_reader = axis2_json_reader_create_for_stream(env, in_stream);
+ if (!json_reader)
+ {
+ axis2_json_reader_free(json_reader, env);
+ return AXIS2_FAILURE;
+ }
+
+ status = axis2_json_reader_read(json_reader, env);
+ if (status != AXIS2_SUCCESS)
+ {
+ axis2_json_reader_free(json_reader, env);
+ return status;
+ }
+
+ root_node = axis2_json_reader_get_root_node(json_reader, env);
+ if (!root_node)
+ {
+ axis2_json_reader_free(json_reader, env);
+ return AXIS2_FAILURE;
+ }
+
+ axis2_json_reader_free(json_reader, env);
+
+ soap_envelope =
+ axiom_soap_envelope_create_default_soap_envelope(env, AXIOM_SOAP11);
+ soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+ axiom_soap_body_add_child(soap_body, env, root_node);
+ axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_doing_rest(msg_ctx, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_rest_http_method(msg_ctx, env, AXIS2_HTTP_PUT);
+ }
+ else
+ {
+#endif
+
xml_reader = axiom_xml_reader_create_for_io(env, axis2_http_transport_utils_on_data_request,
NULL, (void *)callback_ctx, axutil_string_get_buffer(char_set_str, env));
@@ -1161,6 +1253,9 @@
return AXIS2_FAILURE;
}
}
+#ifdef AXIS2_JSON_ENABLED
+ }
+#endif
if(run_as_get)
{
@@ -1292,6 +1387,14 @@
axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+#ifdef AXIS2_JSON_ENABLED
+ if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
+ {
+ axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
+ }
+ else
+#endif
if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
{
if(soap_action_header)
@@ -1353,6 +1456,14 @@
axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+#ifdef AXIS2_JSON_ENABLED
+ if (content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
+ {
+ axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
+ }
+ else
+#endif
if(content_type && strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
{
if(soap_action_header)
@@ -1415,6 +1526,14 @@
axis2_msg_ctx_set_to(msg_ctx, env, axis2_endpoint_ref_create(env, request_uri));
axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);
+
+#ifdef AXIS2_JSON_ENABLED
+ if (strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_JSON))
+ {
+ axis2_msg_ctx_set_doing_json(msg_ctx, env, AXIS2_TRUE);
+ }
+ else
+#endif
if(strstr(content_type, AXIS2_HTTP_HEADER_ACCEPT_TEXT_XML))
{
if(soap_action_header)
diff --git a/src/core/util/core_utils.c b/src/core/util/core_utils.c
index 5ae9f31..cc34fcf 100644
--- a/src/core/util/core_utils.c
+++ b/src/core/util/core_utils.c
@@ -102,6 +102,9 @@
axis2_svc_ctx_t *svc_ctx = NULL;
axis2_bool_t doing_rest = AXIS2_FALSE;
axis2_bool_t doing_mtom = AXIS2_FALSE;
+#ifdef AXIS2_JSON_ENABLED
+ axis2_bool_t doing_json = AXIS2_FALSE;
+#endif
axis2_bool_t server_side = AXIS2_FALSE;
axis2_svc_grp_ctx_t *svc_grp_ctx = NULL;
axis2_char_t *msg_uuid = NULL;
@@ -217,6 +220,11 @@
doing_mtom = axis2_msg_ctx_get_doing_mtom(in_msg_ctx, env);
axis2_msg_ctx_set_doing_mtom(new_msg_ctx, env, doing_mtom);
+#ifdef AXIS2_JSON_ENABLED
+ doing_json = axis2_msg_ctx_get_doing_json(in_msg_ctx, env);
+ axis2_msg_ctx_set_doing_json(new_msg_ctx, env, doing_json);
+#endif
+
server_side = axis2_msg_ctx_get_server_side(in_msg_ctx, env);
axis2_msg_ctx_set_server_side(new_msg_ctx, env, server_side);
diff --git a/test/core/transport/http/Makefile.am b/test/core/transport/http/Makefile.am
index 85f24a4..1ba2c8e 100644
--- a/test/core/transport/http/Makefile.am
+++ b/test/core/transport/http/Makefile.am
@@ -36,3 +36,9 @@
-I ../../../../axiom/include \
-I ../../../cutest/include
+if AXIS2_JSON_ENABLED
+test_http_transport_LDADD += $(JSON_LIBS) \
+ $(top_builddir)/src/core/transport/http/common/libaxis2_http_common.la
+
+INCLUDES += $(JSON_CFLAGS)
+endif
diff --git a/test/core/transport/http/test_http_transport.c b/test/core/transport/http/test_http_transport.c
index 0416da8..6295db6 100644
--- a/test/core/transport/http/test_http_transport.c
+++ b/test/core/transport/http/test_http_transport.c
@@ -24,6 +24,13 @@
#include <axis2_http_client.h>
#include <cut_defs.h>
#include <cut_http_server.h>
+#ifdef AXIS2_JSON_ENABLED
+#include <axiom.h>
+#include <axutil_utils.h>
+#include <json.h>
+#include <axis2_json_writer.h>
+#include <axis2_json_reader.h>
+#endif
void
test_http_request_line(
@@ -263,6 +270,152 @@
#endif
}
+#ifdef AXIS2_JSON_ENABLED
+void
+test_json(
+ const axutil_env_t * env)
+{
+ axiom_node_t* root_node = NULL;
+
+ /* JSON_C */
+ axis2_json_writer_t* json_writer;
+ axis2_json_reader_t* json_reader;
+ unsigned i;
+ axis2_char_t* xml_str;
+ const axis2_char_t* result_str;
+ int passed = 0;
+ int failed = 0;
+
+
+ const char* xml_data[] =
+ {
+ "<root><child1>value 1</child1><child2>value 2</child2></root>",
+ "<root> \t\r\n<child1>value 1</child1> <child2>value 2</child2>\n</root>",
+ "<root><child1><sub>value 1</sub></child1><child2>value 2</child2></root>",
+ "<root><child></child><ch>value 1</ch><ch>value 2</ch><ch>value 3</ch></root>",
+ "<root><child></child><ch><sub>11</sub><sub>12</sub></ch><ch><sub>11</sub><sub>12</sub></ch></root>",
+ "<root><ch xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"></ch></root>"
+ };
+
+ const char* json_data_mapped[] =
+ {
+ "{\"root\":{\"child1\":\"value 1\",\"child2\":\"value 2\"}}",
+ "{\"root\":{\"child1\":{\"sub\":\"value 1\"},\"child2\":\"value 2\"}}",
+ "{\"root\":{\"child\":\"\",\"ch\":[\"value 1\",\"value 2\",\"value 3\"]}}",
+ "{\"root\":{\"child\":\"\",\"ch\":[{\"sub\":[\"11\",\"12\"]},{\"sub\":[\"11\",\"12\"]}]}}",
+ "{\"root\":{\"ch\":null}}"
+ };
+
+ int xml2mapped[sizeof(xml_data) / sizeof(xml_data[0])] =
+ {
+ 0, 0, 1, 2, 3, 4
+ };
+
+ int mapped2xml[sizeof(json_data_mapped) / sizeof(json_data_mapped[0])] =
+ {
+ 0, 2, 3, 4, 5
+ };
+
+ printf(" ######################## testing xml -> json ########################## \n");
+
+ for (i = 0; i < sizeof(xml_data) / sizeof(xml_data[0]); ++i)
+ {
+ const char* xml = xml_data[i];
+
+ root_node = axiom_node_create_from_buffer(env, (axis2_char_t*)xml);
+
+ xml_str = axiom_node_to_string(root_node, env);
+
+ printf(" =============== source XML ================\n%s\n"
+ " ===========================================\n",
+ xml_str);
+ AXIS2_FREE(env->allocator, xml_str);
+
+ json_writer = axis2_json_writer_create(env);
+ axis2_json_writer_write(json_writer, root_node, env);
+
+ result_str = axis2_json_writer_get_json_string(json_writer, env, 0);
+ printf(" ============= resulting JSON ==============\n%s\n"
+ " ===========================================\n",
+ result_str);
+
+ if (strcmp(result_str, json_data_mapped[xml2mapped[i]]))
+ {
+ ++failed;
+ printf("TEST FAILED\nexpected result: %s\n", json_data_mapped[xml2mapped[i]]);
+ }
+ else
+ {
+ ++passed;
+ printf("test passed\n\n");
+ }
+
+ axis2_json_writer_free(json_writer, env);
+
+ axiom_node_free_tree(root_node, env);
+ }
+
+
+ printf(" ######################## testing json -> xml ########################## \n");
+
+ for (i = 0; i < sizeof(json_data_mapped) / sizeof(json_data_mapped[0]); ++i)
+ {
+ const char* json = json_data_mapped[i];
+ int length = strlen(json);
+
+ json_reader = axis2_json_reader_create_for_memory(env, json, length);
+ if (!json_reader)
+ {
+ printf("Failed to create json_reader");
+ return;
+ }
+
+ if (axis2_json_reader_read(json_reader, env) != AXIS2_SUCCESS)
+ {
+ printf("Failed to axis2_json_reader_read");
+ return;
+ }
+
+ root_node = axis2_json_reader_get_root_node(json_reader, env);
+ if (!root_node)
+ {
+ printf("Failed to get root_node");
+ return;
+ }
+
+
+ printf(" =============== source JSON ================\n%s\n"
+ " ===========================================\n",
+ json);
+
+
+ xml_str = axiom_node_to_string(root_node, env);
+
+ printf(" =============== resulting XML ================\n%s\n"
+ " ===========================================\n",
+ xml_str);
+
+ if (strcmp(xml_str, xml_data[mapped2xml[i]]))
+ {
+ ++failed;
+ printf("TEST FAILED\nExpected result: %s\n", xml_data[mapped2xml[i]]);
+ }
+ else
+ {
+ ++passed;
+ printf("test passed\n\n");
+ }
+ AXIS2_FREE(env->allocator, xml_str);
+
+ axis2_json_reader_free(json_reader, env);
+ axiom_node_free_tree(root_node, env);
+ }
+
+ printf("JSON tests passed: %d, failed: %d\n", passed, failed);
+}
+#endif
+
+
int
main(
void)
@@ -276,6 +429,9 @@
test_http_client(env);
test_https_client(env);
test_url(env);
+#ifdef AXIS2_JSON_ENABLED
+ test_json(env);
+#endif
axutil_env_free(env);
}
CUT_RETURN_ON_FAILURE(-1);