adding xml format support to the gateway
authormiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Mon, 27 Feb 2006 22:29:01 +0000 (22:29 +0000)
committermiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Mon, 27 Feb 2006 22:29:01 +0000 (22:29 +0000)
git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@650 9efc2488-bf62-4759-914b-345cdb29e865

src/gateway/Makefile
src/gateway/osrf_json_gateway.c
src/objson/Makefile
src/objson/json2xml.c [new file with mode: 0644]
src/objson/json2xml.h [new file with mode: 0644]

index 55dd3ae..db7add1 100644 (file)
@@ -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
 
 
index cf79675..1180048 100644 (file)
@@ -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("<response xmlns=\"http://opensrf.org/-/namespaces/gateway/v1\"><payload>", 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("</payload>", 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, "<debug>\"%s : %s\"</debug>", 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, "<status>%d</status>", statuscode );
+               else
+                       snprintf(buf, 32, ",\"status\":%d", statuscode );
+
                ap_rputs( buf, r );
 
-               ap_rputs( "}", r ); /* finish off the object */
+               if (isXML)
+                       ap_rputs("</response>", r);
+               else
+                       ap_rputs( "}", r ); /* finish off the object */
+
                osrf_app_session_destroy(session);
        }
 
index 7c38643..5fcac70 100644 (file)
 #
 # --------------------------------------------------------------------
 
-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 (file)
index 0000000..918c958
--- /dev/null
@@ -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("<null/>");
+       
+       _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, "<null class_hint=\"%s\"/>",hint);
+               else
+                       buffer_add(res_xml, "<null/>");
+
+       } 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, "<boolean value=\"%s\" class_hint=\"%s\"/>", bool_val, hint);
+               else
+                       buffer_fadd(res_xml, "<boolean value=\"%s\"/>", bool_val);
+
+               free(bool_val);
+                
+       } else if (obj->type == JSON_STRING) {
+               if (hint) {
+                       char * t = _escape_xml(jsonObjectGetString(obj));
+                       buffer_fadd(res_xml,"<string class_hint=\"%s\">%s</string>", hint, t);
+                       free(t);
+               } else {
+                       char * t = _escape_xml(jsonObjectGetString(obj));
+                       buffer_fadd(res_xml,"<string>%s</string>", t);
+                       free(t);
+               }
+
+       } else if(obj->type == JSON_NUMBER) {
+               double x = jsonObjectGetNumber(obj);
+               if (hint) {
+                       if (x == (int)x)
+                               buffer_fadd(res_xml,"<number class_hint=\"%s\">%d</number>", hint, (int)x);
+                       else
+                               buffer_fadd(res_xml,"<number class_hint=\"%s\">%lf</number>", hint, x);
+               } else {
+                       if (x == (int)x)
+                               buffer_fadd(res_xml,"<number>%d</number>", (int)x);
+                       else
+                               buffer_fadd(res_xml,"<number>%lf</number>", x);
+               }
+
+       } else if (obj->type == JSON_ARRAY) {
+
+               if (hint) 
+                       buffer_fadd(res_xml,"<array class_hint=\"%s\">", hint);
+               else
+                               buffer_add(res_xml,"<array>");
+
+               for ( i = 0; i!= obj->size; i++ )
+                       _recurse_jsonObjectToXML(jsonObjectGetIndex(obj,i), res_xml);
+
+               buffer_add(res_xml,"</array>");
+
+       } else if (obj->type == JSON_HASH) {
+
+               if (hint)
+                       buffer_fadd(res_xml,"<object class_hint=\"%s\">", hint);
+               else
+                       buffer_add(res_xml,"<object>");
+
+                jsonObjectIterator* itr = jsonNewObjectIterator(obj);
+                jsonObjectNode* tmp;
+                while( (tmp = jsonObjectIteratorNext(itr)) ) {
+
+                       buffer_fadd(res_xml,"<element key=\"%s\">",tmp->key);
+
+                       _recurse_jsonObjectToXML(tmp->item, res_xml);
+
+                       buffer_add(res_xml,"</element>");
+                }
+                jsonObjectIteratorFree(itr);
+
+               buffer_add(res_xml,"</object>");
+       }
+
+       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,"&amp;");
+               else if (text[i] == '<')
+                       buffer_add(b,"&lt;");
+               else if (text[i] == '>')
+                       buffer_add(b,"&gt;");
+               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 (file)
index 0000000..47b5a4f
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include <string.h>
+#include <stdio.h>
+
+/* 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*);
+