From 05d5fe04cce0d3093edf9f1ff586f1fd782e1aff Mon Sep 17 00:00:00 2001 From: miker Date: Mon, 27 Feb 2006 22:29:01 +0000 Subject: [PATCH] adding xml format support to the gateway git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@650 9efc2488-bf62-4759-914b-345cdb29e865 --- src/gateway/Makefile | 8 ++- src/gateway/osrf_json_gateway.c | 78 ++++++++++++++++------ src/objson/Makefile | 7 +- src/objson/json2xml.c | 141 ++++++++++++++++++++++++++++++++++++++++ src/objson/json2xml.h | 11 ++++ 5 files changed, 222 insertions(+), 23 deletions(-) create mode 100644 src/objson/json2xml.c create mode 100644 src/objson/json2xml.h diff --git a/src/gateway/Makefile b/src/gateway/Makefile index 55dd3ae..db7add1 100644 --- a/src/gateway/Makefile +++ b/src/gateway/Makefile @@ -1,5 +1,5 @@ CCFLAGS += -DASSUME_STATELESS -LDLIBS += -lobjson -lxml2 -lopensrf +LDLIBS += -lobjson -lopensrf all: osrf_json_gateway.so copy @@ -11,8 +11,12 @@ copy: cp apachetools.h $(TMPDIR) apachetools.o: apachetools.h apachetools.c + $(CC) -c $(CFLAGS) apachetools.c -o $@ + osrf_json_gateway.o: osrf_json_gateway.c -osrf_json_gateway.so: osrf_json_gateway.o apachetools.o + $(CC) -c $(CFLAGS) osrf_json_gateway.c -o $@ + +osrf_json_gateway.so: copy apachetools.o osrf_json_gateway.o $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -shared -W1 apachetools.o osrf_json_gateway.o -o osrf_json_gateway.so diff --git a/src/gateway/osrf_json_gateway.c b/src/gateway/osrf_json_gateway.c index cf79675..1180048 100644 --- a/src/gateway/osrf_json_gateway.c +++ b/src/gateway/osrf_json_gateway.c @@ -2,6 +2,7 @@ #include "opensrf/osrf_app_session.h" #include "opensrf/osrf_system.h" #include "objson/object.h" +#include "objson/json2xml.h" #define MODULE_NAME "osrf_json_gateway_module" #define GATEWAY_CONFIG "OSRFGatewayConfig" @@ -72,18 +73,32 @@ static int osrf_json_gateway_method_handler (request_rec *r) { char* service = NULL; /* service to connect to */ char* method = NULL; /* method to perform */ - int api_level = 1; /* request api level */ - - ap_set_content_type(r, "text/plain"); + char* format = NULL; /* method to perform */ + char* a_l = NULL; /* request api level */ + int isXML = 0; + int api_level = 1; r->allowed |= (AP_METHOD_BIT << M_GET); r->allowed |= (AP_METHOD_BIT << M_POST); string_array* mparams = NULL; string_array* params = apacheParseParms(r); /* free me */ - service = apacheGetFirstParamValue( params, "service" ); - method = apacheGetFirstParamValue( params, "method" ); - mparams = apacheGetParamValues( params, "param" ); /* free me */ + service = apacheGetFirstParamValue( params, "service" ); + method = apacheGetFirstParamValue( params, "method" ); + format = apacheGetFirstParamValue( params, "format" ); + a_l = apacheGetFirstParamValue( params, "api_level" ); + mparams = apacheGetParamValues( params, "param" ); /* free me */ + + if (a_l) + api_level = atoi(a_l); + + if (format && !strcasecmp(format, "xml" )) { + isXML = 1; + ap_set_content_type(r, "application/xml"); + } else { + ap_set_content_type(r, "text/plain"); + } + if( service && method ) { @@ -95,11 +110,15 @@ static int osrf_json_gateway_method_handler (request_rec *r) { int statuscode = 200; /* kick off the object */ - ap_rputs("{\"payload\":[", r); + if (isXML) + ap_rputs("", r); + else + ap_rputs("{\"payload\":[", r); int morethan1 = 0; char* statusname = NULL; char* statustext = NULL; + char* output = NULL; while((omsg = osrfAppSessionRequestRecv( session, req_id, 60 ))) { @@ -108,10 +127,14 @@ static int osrf_json_gateway_method_handler (request_rec *r) { if( ( res = osrfMessageGetResult(omsg)) ) { - char* json = jsonObjectToJSON( res ); - if( morethan1 ) ap_rputs(",", r); /* comma between JSON array items */ - ap_rputs(json, r); - free(json); + if (isXML) { + output = jsonObjectToXML( res ); + } else { + output = jsonObjectToJSON( res ); + if( morethan1 ) ap_rputs(",", r); /* comma between JSON array items */ + } + ap_rputs(output, r); + free(output); morethan1 = 1; } else { @@ -127,30 +150,47 @@ static int osrf_json_gateway_method_handler (request_rec *r) { if(statusname) break; } - ap_rputs("]",r); /* finish off the payload array */ + if (isXML) + ap_rputs("", r); + else + ap_rputs("]",r); /* finish off the payload array */ if(statusname) { /* add a debug field if the request died */ ap_log_rerror( APLOG_MARK, APLOG_INFO, 0, r, "OpenSRF JSON Request returned error: %s -> %s", statusname, statustext ); - int l = strlen(statusname) + strlen(statustext) + 24; + int l = strlen(statusname) + strlen(statustext) + 32; char buf[l]; bzero(buf,l); - snprintf( buf, l, ",\"debug\":\"%s : %s\"", statusname, statustext ); + + if (isXML) + snprintf( buf, l, "\"%s : %s\"", statusname, statustext ); + else + snprintf( buf, l, ",\"debug\":\"%s : %s\"", statusname, statustext ); + ap_rputs(buf, r); free(statusname); free(statustext); } - /* insert the statu code */ - char buf[24]; - bzero(buf,24); - snprintf(buf, 24, ",\"status\":%d", statuscode ); + /* insert the status code */ + char buf[32]; + bzero(buf,32); + + if (isXML) + snprintf(buf, 32, "%d", statuscode ); + else + snprintf(buf, 32, ",\"status\":%d", statuscode ); + ap_rputs( buf, r ); - ap_rputs( "}", r ); /* finish off the object */ + if (isXML) + ap_rputs("", r); + else + ap_rputs( "}", r ); /* finish off the object */ + osrf_app_session_destroy(session); } diff --git a/src/objson/Makefile b/src/objson/Makefile index 7c38643..5fcac70 100644 --- a/src/objson/Makefile +++ b/src/objson/Makefile @@ -26,12 +26,12 @@ # # -------------------------------------------------------------------- -OBJS = md5.o utils.o object.o json_parser.o +OBJS = md5.o utils.o json2xml.o object.o json_parser.o UTIL_DIR = ../utils DEST_INCLUDE = objson CFLAGS += -DSTRICT_JSON_WRITE #-DSTRICT_JSON_READ -JSON_HEADERS = object.h json_parser.h +JSON_HEADERS = object.h json_parser.h json2xml.h all: test @@ -62,6 +62,9 @@ md5.o: $(UTIL_DIR)/md5.h $(UTIL_DIR)/md5.c cp $(UTIL_DIR)/md5.c . $(CC) -c $(CFLAGS) md5.c -o $@ +json2xml.o: json2xml.h json2xml.c + $(CC) -c $(CFLAGS) json2xml.c -o $@ + clean: /bin/rm -f *.o *.so utils.c utils.h libobjson.so diff --git a/src/objson/json2xml.c b/src/objson/json2xml.c new file mode 100644 index 0000000..918c958 --- /dev/null +++ b/src/objson/json2xml.c @@ -0,0 +1,141 @@ + +#include "json2xml.h" + +static char* _escape_xml (char*); +static int _recurse_jsonObjectToXML(jsonObject*, growing_buffer*); + +char* jsonObjectToXML(jsonObject* obj) { + + growing_buffer * res_xml; + char * output; + + res_xml = buffer_init(1024); + + if (!obj) + return strdup(""); + + _recurse_jsonObjectToXML( obj, res_xml ); + output = buffer_data(res_xml); + + buffer_free(res_xml); + + return output; + +} + +int _recurse_jsonObjectToXML(jsonObject* obj, growing_buffer* res_xml) { + + char * hint = NULL; + char * bool_val = NULL; + int i = 0; + + if (obj->classname) + hint = strdup(obj->classname); + + if(obj->type == JSON_NULL) { + + if (hint) + buffer_fadd(res_xml, "",hint); + else + buffer_add(res_xml, ""); + + } else if(obj->type == JSON_BOOL) { + + if (obj->value.b) + bool_val = strdup("true"); + else + bool_val = strdup("false"); + + if (hint) + buffer_fadd(res_xml, "", bool_val, hint); + else + buffer_fadd(res_xml, "", bool_val); + + free(bool_val); + + } else if (obj->type == JSON_STRING) { + if (hint) { + char * t = _escape_xml(jsonObjectGetString(obj)); + buffer_fadd(res_xml,"%s", hint, t); + free(t); + } else { + char * t = _escape_xml(jsonObjectGetString(obj)); + buffer_fadd(res_xml,"%s", t); + free(t); + } + + } else if(obj->type == JSON_NUMBER) { + double x = jsonObjectGetNumber(obj); + if (hint) { + if (x == (int)x) + buffer_fadd(res_xml,"%d", hint, (int)x); + else + buffer_fadd(res_xml,"%lf", hint, x); + } else { + if (x == (int)x) + buffer_fadd(res_xml,"%d", (int)x); + else + buffer_fadd(res_xml,"%lf", x); + } + + } else if (obj->type == JSON_ARRAY) { + + if (hint) + buffer_fadd(res_xml,"", hint); + else + buffer_add(res_xml,""); + + for ( i = 0; i!= obj->size; i++ ) + _recurse_jsonObjectToXML(jsonObjectGetIndex(obj,i), res_xml); + + buffer_add(res_xml,""); + + } else if (obj->type == JSON_HASH) { + + if (hint) + buffer_fadd(res_xml,"", hint); + else + buffer_add(res_xml,""); + + jsonObjectIterator* itr = jsonNewObjectIterator(obj); + jsonObjectNode* tmp; + while( (tmp = jsonObjectIteratorNext(itr)) ) { + + buffer_fadd(res_xml,"",tmp->key); + + _recurse_jsonObjectToXML(tmp->item, res_xml); + + buffer_add(res_xml,""); + } + jsonObjectIteratorFree(itr); + + buffer_add(res_xml,""); + } + + if (hint) + free(hint); + + return 1; +} + +char* _escape_xml (char* text) { + char* out; + growing_buffer* b = buffer_init(256); + int len = strlen(text); + int i; + for (i = 0; i < len; i++) { + if (text[i] == '&') + buffer_add(b,"&"); + else if (text[i] == '<') + buffer_add(b,"<"); + else if (text[i] == '>') + buffer_add(b,">"); + else + buffer_add_char(b,text[i]); + } + out = buffer_data(b); + buffer_free(b); + return out; +} + + diff --git a/src/objson/json2xml.h b/src/objson/json2xml.h new file mode 100644 index 0000000..47b5a4f --- /dev/null +++ b/src/objson/json2xml.h @@ -0,0 +1,11 @@ + +#include +#include + +/* the JSON parser, so we can read the response we're XMLizing */ +#include "object.h" +#include "json_parser.h" +#include "utils.h" + +char* jsonObjectToXML(jsonObject*); + -- 2.11.0