1decf921c610ad499bf2579b6af08664cfa14680
[OpenSRF.git] / src / gateway / fieldmapper-c-xml-out.pl
1 #!/usr/bin/perl
2 use strict;
3 use lib '../perlmods/';
4
5 my $map = {};
6 eval "
7         use lib '../../../Open-ILS/src/perlmods/';
8         use OpenILS::Utils::Fieldmapper;  
9 ";
10 $map = $Fieldmapper::fieldmap unless ($@);
11
12
13 if(!$ARGV[1]) {
14         print "usage: $0 <header_file> <source_file>\n";
15         exit;
16 }
17
18 warn "Generating fieldmapper-c code...\n";
19
20
21 print $ARGV[0] . "\n";
22 print $ARGV[1] . "\n";
23
24 open(HEADER, ">$ARGV[0]");
25 open(SOURCE, ">$ARGV[1]");
26
27 warn "Generating fieldmapper-c code...\n";
28
29 print HEADER <<C;
30 #ifndef _TOXML_H_
31 #define _TOXML_H_
32
33 char* json_string_to_xml(char*);
34
35 #endif
36 C
37
38 print SOURCE <<C;
39
40 #include <string.h>
41
42 /* and the JSON parser, so we can read the response we're XMLizing */
43 #include <string.h>
44 #include <stdio.h>
45 #include "objson/object.h"
46 #include "objson/json_parser.h"
47 #include "opensrf/utils.h"
48
49 char* json_string_to_xml(char*);
50 void _rest_xml_output(growing_buffer*, object*, char*, int, int);
51 char * _lookup_fm_field(char*,int);
52 char* _escape_xml (char*);
53
54 char* json_string_to_xml(char* content) {
55         object * obj;
56         growing_buffer * res_xml;
57         char * output;
58         int i;
59
60         obj = json_parse_string( content );
61         res_xml = buffer_init(1024);
62
63         if (!obj)
64                 return NULL;
65         
66         buffer_add(res_xml, "<response>");
67
68         for( i = 0; i!= obj->size; i++ ) {
69                 _rest_xml_output(res_xml, obj->get_index(obj,i), NULL, 0,0);
70         }
71
72         buffer_add(res_xml, "</response>");
73
74         output = buffer_data(res_xml);
75         buffer_free(res_xml);
76
77         return output;
78 }
79
80 char* _escape_xml (char* text) {
81         char* out;
82         growing_buffer* b = buffer_init(256);
83         int len = strlen(text);
84         int i;
85         for (i = 0; i < len; i++) {
86                 if (text[i] == '&')
87                         buffer_add(b,"&amp;");
88                 else if (text[i] == '<')
89                         buffer_add(b,"&lt;");
90                 else if (text[i] == '>')
91                         buffer_add(b,"&gt;");
92                 else
93                         buffer_add_char(b,text[i]);
94         }
95         out = buffer_data(b);
96         buffer_free(b);
97         return out;
98 }
99
100 void _rest_xml_output(growing_buffer* buf, object* obj, char * fm_class, int fm_index, int notag) {
101         char * tag;
102         int i;
103         
104         if (obj->classname)
105                 notag = 1;
106
107         if(fm_class) {
108                 tag = _lookup_fm_field(fm_class,fm_index);
109         } else {
110                 tag = strdup("datum");
111         }
112         
113         /* add class hints if we have a class name */
114         if(obj->classname) {
115                 if(obj->is_null) {
116                         buffer_fadd(buf,"<%s><Object class_hint=\\\"%s\\\"/></%s>", tag, obj->classname, tag);
117                         return;
118                 } else {
119                         buffer_fadd(buf,"<%s><Object class_hint=\\\"%s\\\">", tag, obj->classname);
120                 }
121         }
122
123         /* now add the data */
124         if(obj->is_null) {
125                 if (!notag)
126                         buffer_fadd(buf, "<%s/>",tag);
127         } else if(obj->is_bool && obj->bool_value) {
128                 if (notag)
129                         buffer_add(buf, "true");
130                 else
131                         buffer_fadd(buf, "<%s>true</%s>",tag,tag);
132                 
133         } else if(obj->is_bool && ! obj->bool_value) {
134                 if (notag)
135                         buffer_add(buf, "false");
136                 else
137                         buffer_fadd(buf, "<%s>false</%s>",tag,tag);
138
139         } else if (obj->is_string) {
140                 if (notag) {
141                         char * t = _escape_xml(obj->string_data);
142                         buffer_add(buf,t);
143                         free(t);
144                 } else {
145                         char * t = _escape_xml(obj->string_data);
146                         buffer_fadd(buf,"<%s>%s</%s>",tag,t,tag);
147                         free(t);
148                 }
149
150         } else if(obj->is_number) {
151                 if (notag)
152                         buffer_fadd(buf,"%ld",obj->num_value);
153                 else
154                         buffer_fadd(buf,"<%s>%ld</%s>",tag,obj->num_value,tag);
155
156         } else if(obj->is_double) {
157                 if (notag)
158                         buffer_fadd(buf,"%lf",tag,obj->double_value,tag);
159                 else
160                         buffer_fadd(buf,"<%s>%lf</%s>",tag,obj->double_value,tag);
161
162
163         } else if (obj->is_array) {
164                 if (!notag) {
165                         if(!fm_class)
166                                 buffer_add(buf,"<array>");
167                         else
168                                 buffer_fadd(buf,"<%s>",tag);
169                 }
170
171                 for( i = 0; i!= obj->size; i++ ) {
172                         _rest_xml_output(buf, obj->get_index(obj,i), obj->classname, i,0);
173                 }
174
175                 if (!notag) {
176                         if(!fm_class)
177                                 buffer_add(buf,"</array>");
178                         else
179                                 buffer_fadd(buf,"</%s>",tag);
180                 }
181
182         } else if (obj->is_hash) {
183
184                 if (!notag) {
185                         if(!fm_class)
186                                 buffer_add(buf,"<hash>");
187                         else
188                                 buffer_fadd(buf,"<%s>",tag);
189                 }
190
191                 object_iterator* itr = new_iterator(obj);
192                 object_node* tmp;
193                 while( (tmp = itr->next(itr)) ) {
194                         if (notag) {
195                                 buffer_fadd(buf,"<%s>",tmp->key);
196                         } else {
197                                 buffer_add(buf,"<pair>");
198                                 buffer_fadd(buf,"<key>%s</key><value>",tmp->key);
199                         }
200
201                         _rest_xml_output(buf, tmp->item, NULL,0,notag);
202
203                         if (notag) {
204                                 buffer_fadd(buf,"</%s>",tmp->key);
205                         } else {
206                                 buffer_add(buf,"</value></pair>");
207                         }
208                 }
209                 free_iterator(itr);
210
211                 if (!notag) {
212                         if(!fm_class)
213                                 buffer_add(buf,"</hash>");
214                         else
215                                 buffer_fadd(buf,"</%s>",tag);
216                 }
217
218         }
219
220         if (obj->classname)
221                 buffer_fadd(buf,"</Object></%s>",tag);
222
223         free(tag);
224 }
225
226 char * _lookup_fm_field(char * class, int pos) {
227
228 C
229
230 print SOURCE "  if (class == NULL) return NULL;";
231
232 for my $object (keys %$map) {
233
234         my $short_name                          = $map->{$object}->{hint};
235
236         print SOURCE <<"        C";
237
238         else if (!strcmp(class, "$short_name")) {
239                 switch (pos) {
240         C
241
242         for my $field (keys %{$map->{$object}->{fields}}) {
243                 my $position = $map->{$object}->{fields}->{$field}->{position};
244
245                 print SOURCE <<"                C";
246                         case $position:
247                                 return strdup("$field");
248                                 break;
249                 C
250         }
251         print SOURCE "          }\n";
252         print SOURCE "  }\n";
253 }
254 print SOURCE '  return strdup("datum");'."\n";
255 print SOURCE "}\n";
256
257 close HEADER;
258 close SOURCE;
259
260 warn  "done\n";
261