changes to support the REST gateway
authormiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Tue, 2 Aug 2005 18:38:06 +0000 (18:38 +0000)
committermiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Tue, 2 Aug 2005 18:38:06 +0000 (18:38 +0000)
git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@446 9efc2488-bf62-4759-914b-345cdb29e865

src/Makefile
src/gateway/Makefile
src/gateway/fieldmapper-c-xml-out.pl [new file with mode: 0755]
src/gateway/mod_ils_gateway.c

index 0cbe7bb..7e9bb9b 100644 (file)
@@ -21,7 +21,7 @@ export CC_OPTS                        = -g -Wall -O2 -fPIC -I$(LIBXML2_HEADERS) -I$(APACHE2_HEADERS)
                                                                -I$(LIBXML2_HEADERS)/libxml  -I$(TMP) -I$(TMPDIR)
 
 
-all: test prep router srfsh jserver gateway
+all: test prep router srfsh jserver gateway rest_gateway
 
 test: test
        echo "TEST TEST TEST"
@@ -69,6 +69,10 @@ gateway:     stack
        @echo -e "\n + gateway"
        make -C gateway
 
+rest_gateway:  stack 
+       @echo -e "\n + rest_gateway"
+       make -e -C gateway rest_gateway
+
 jserver: c_utils
        @echo -e "\n + jserver"
        make -C jserver
index 1ae63e4..b587761 100644 (file)
@@ -1,7 +1,8 @@
 CC_OPTS        += -DASSUME_STATELESS
-LD_OPTS        += -lc_utils -lobjson -lxml2 -lopensrf_transport -lopensrf_stack 
+LD_OPTS        += -lc_utils -lobjson -lxml2 -lopensrf_transport -lopensrf_stack
 
 all: libmod_ils_gateway.so
+rest_gateway: libmod_ils_rest_gateway.so
 
 install: 
        cp $(TMPDIR)/libmod_ils_gateway.so $(LIBDIR)/libmod_ils_gateway.so
@@ -12,5 +13,11 @@ libmod_ils_gateway.so: mod_ils_gateway.c
        $(CC) -c $(CC_OPTS)  mod_ils_gateway.c
        $(CC) $(LD_OPTS) -shared -W1 mod_ils_gateway.o -o $(TMPDIR)/libmod_ils_gateway.so
 
+libmod_ils_rest_gateway.so: mod_ils_gateway.c  
+       ./fieldmapper-c-xml-out.pl rest_xml.h rest_xml.c
+       $(CC) -c $(CC_OPTS) -o rest_xml.o rest_xml.c
+       $(CC) -c -DRESTGATEWAY $(CC_OPTS) -o mod_ils_rest_gateway.o mod_ils_gateway.c
+       $(CC) $(LD_OPTS) -shared -W1 mod_ils_rest_gateway.o -o $(TMPDIR)/libmod_ils_rest_gateway.so
+
 clean:
        /bin/rm -f *.o *.so
diff --git a/src/gateway/fieldmapper-c-xml-out.pl b/src/gateway/fieldmapper-c-xml-out.pl
new file mode 100755 (executable)
index 0000000..ce9f5de
--- /dev/null
@@ -0,0 +1,172 @@
+#!/usr/bin/perl
+use strict; use warnings;
+use lib '../../../Open-ILS/src/perlmods/';
+use OpenILS::Utils::Fieldmapper;  
+
+
+if(!$ARGV[1]) {
+       print "usage: $0 <header_file> <source_file>\n";
+       exit;
+}
+
+warn "Generating fieldmapper-c code...\n";
+
+
+print $ARGV[0] . "\n";
+print $ARGV[1] . "\n";
+
+open(HEADER, ">$ARGV[0]");
+open(SOURCE, ">$ARGV[1]");
+
+
+warn "Generating fieldmapper-c code...\n";
+
+my $map = $Fieldmapper::fieldmap;
+
+print HEADER <<C;
+#ifndef _TOXML_H_
+#define _TOXML_H_
+
+char* json_string_to_xml(char*);
+
+#endif
+C
+
+print SOURCE <<C;
+
+#include <string.h>
+
+/* and the JSON parser, so we can read the response we're XMLizing */
+#include <string.h>
+#include "objson/object.h"
+#include "objson/json_parser.h"
+#include "opensrf/utils.h"
+
+char* json_string_to_xml(char*);
+void _rest_xml_output(growing_buffer*, object*, char*, int);
+char * _lookup_fm_field(char*,int);
+
+char* json_string_to_xml(char* content) {
+       object * obj;
+       growing_buffer * res_xml;
+       char * output;
+       int i;
+
+       obj = json_parse_string( content );
+       res_xml = buffer_init(1024);
+
+       if (!obj)
+               return NULL;
+       
+       buffer_add(res_xml, "<response>");
+
+       for( i = 0; i!= obj->size; i++ ) {
+               _rest_xml_output(res_xml, obj->get_index(obj,i), NULL, 0);
+       }
+
+       buffer_add(res_xml, "</response>");
+
+       output = buffer_data(res_xml);
+       buffer_free(res_xml);
+
+       return output;
+}
+
+void _rest_xml_output(growing_buffer* buf, object* obj, char * fm_class, int fm_index) {
+       char * tag;
+       int i;
+       
+
+       if(fm_class ) {
+               tag = _lookup_fm_field(fm_class,fm_index);
+       } else {
+               tag = strdup("datum");
+       }
+        
+        /* add class hints if we have a class name */
+        if(obj->classname)
+                buffer_fadd(buf,"<Fieldmapper hint=\\\"%s\\\">", obj->classname);
+
+       /* now add the data */
+        if(obj->is_null)
+               buffer_fadd(buf, "<%s/>",tag);
+                
+        else if(obj->is_bool && obj->bool_value)
+               buffer_fadd(buf, "<%s>true</%s>",tag,tag);
+                
+        else if(obj->is_bool && ! obj->bool_value)
+               buffer_fadd(buf, "<%s>false</%s>",tag,tag);
+
+       else if (obj->is_string)
+                buffer_fadd(buf,"<%s>%s</%s>",tag,obj->string_data,tag);
+
+        else if(obj->is_number)
+                buffer_fadd(buf,"<%s>%ld</%s>",tag,obj->num_value,tag);
+
+        else if(obj->is_double)
+                buffer_fadd(buf,"<%s>%lf</%s>",tag,obj->double_value,tag);
+
+
+       else if (obj->is_array) {
+               if (!obj->classname)
+                               buffer_add(buf,"<array>");
+               for( i = 0; i!= obj->size; i++ ) {
+                       _rest_xml_output(buf, obj->get_index(obj,i), obj->classname, i);
+               }
+               if (!obj->classname)
+                       buffer_add(buf,"</array>");
+        } else if (obj->is_hash) {
+                       buffer_add(buf,"<hash>");
+                object_iterator* itr = new_iterator(obj);
+                object_node* tmp;
+                while( (tmp = itr->next(itr)) ) {
+                               buffer_add(buf,"<pair>");
+                        buffer_fadd(buf,"<key>%s</key>",tmp->key);
+                        _rest_xml_output(buf, tmp->item, NULL,0);
+                               buffer_add(buf,"</pair>");
+                }
+                free_iterator(itr);
+                       buffer_add(buf,"</hash>");
+        }
+
+
+        if(obj->classname)
+                buffer_add(buf,"</Fieldmapper>");
+}
+
+char * _lookup_fm_field(char * class, int pos) {
+
+C
+
+print SOURCE " if (class == NULL) return NULL;";
+
+for my $object (keys %$map) {
+
+       my $short_name                          = $map->{$object}->{hint};
+
+       print SOURCE <<"        C";
+
+       else if (!strcmp(class, "$short_name")) {
+               switch (pos) {
+       C
+
+       for my $field (keys %{$map->{$object}->{fields}}) {
+               my $position = $map->{$object}->{fields}->{$field}->{position};
+
+               print SOURCE <<"                C";
+                       case $position:
+                               return strdup("$field");
+                               break;
+               C
+       }
+       print SOURCE "          }\n";
+       print SOURCE "  }\n";
+}
+print SOURCE ' return strdup("datum");'."\n";
+print SOURCE "}\n";
+
+close HEADER;
+close SOURCE;
+
+warn  "done\n";
+
index a4ba81b..c1e69fc 100644 (file)
@@ -37,6 +37,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #include "objson/object.h"
 #include "objson/json_parser.h"
 
+#ifdef RESTGATEWAY
+#include "rest_xml.h"
+#endif
+
 /*
  * This function is registered as a handler for HTTP methods and will
   * therefore be invoked for all GET requests (and others).  Regardless
@@ -364,8 +368,13 @@ static int mod_ils_gateway_method_handler (request_rec *r) {
                //json_object_put(exception);
                content = strdup(exception->to_json(exception));
                free_object(exception);
-       } else 
+       } else {
+#ifdef RESTGATEWAY
+               content = json_string_to_xml( buffer_data(result_data) );
+#else
                content = buffer_data(result_data); 
+#endif
+       }
        
 
        buffer_free(result_data);