]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/libstack/osrf_message.c
added some debugging
[Evergreen.git] / OpenSRF / src / libstack / osrf_message.c
1 #include "opensrf/osrf_message.h"
2
3 /* default to true */
4 int parse_json = 1;
5
6 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
7
8         osrf_message* msg = safe_malloc(sizeof(osrf_message));
9         msg->m_type = type;
10         msg->thread_trace = thread_trace;
11         msg->protocol = protocol;
12         msg->next = NULL;
13         msg->is_exception = 0;
14         msg->parse_json = parse_json;
15
16         return msg;
17 }
18
19
20 void osrf_message_set_json_parse( int ibool ) {
21         parse_json = ibool;
22 }
23
24
25 void osrf_message_set_request_info( osrf_message* msg, char* method_name, json* json_params ) {
26         if( msg == NULL || method_name == NULL )
27                 fatal_handler( "Bad params to osrf_message_set_request_params()" );
28
29         if( json_params != NULL )
30                 msg->params = json_tokener_parse(json_object_to_json_string(json_params));
31         else
32                 msg->params = json_tokener_parse("[]");
33
34         msg->method_name = strdup( method_name );
35 }
36
37
38
39 void osrf_message_set_status_info( 
40                 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
41
42         if( msg == NULL )
43                 fatal_handler( "Bad params to osrf_message_set_status_info()" );
44
45         if( status_name != NULL ) 
46                 msg->status_name = strdup( status_name );
47
48         if( status_text != NULL )
49                 msg->status_text = strdup( status_text );
50
51         msg->status_code = status_code;
52 }
53
54
55 void osrf_message_set_result_content( osrf_message* msg, char* json_string ) {
56         if( msg == NULL || json_string == NULL)
57                 warning_handler( "Bad params to osrf_message_set_result_content()" );
58
59         msg->result_string =    strdup(json_string);
60         debug_handler("Setting result_string to %s\n", msg->result_string );
61
62         debug_handler( "Message Parse JSON is set to: %d",  msg->parse_json );
63
64         if(msg->parse_json)
65                 msg->result_content = json_tokener_parse(msg->result_string);
66 }
67
68
69
70 void osrf_message_free( osrf_message* msg ) {
71         if( msg == NULL )
72                 return;
73
74         if( msg->status_name != NULL )
75                 free(msg->status_name);
76
77         if( msg->status_text != NULL )
78                 free(msg->status_text);
79
80         if( msg->result_content != NULL )
81                 json_object_put( msg->result_content );
82
83         if( msg->result_string != NULL )
84                 free( msg->result_string);
85
86         if( msg->method_name != NULL )
87                 free(msg->method_name);
88
89         if( msg->params != NULL )
90                 json_object_put( msg->params );
91
92         free(msg);
93 }
94
95
96                 
97 /* here's where things get interesting */
98 char* osrf_message_to_xml( osrf_message* msg ) {
99
100         if( msg == NULL )
101                 return NULL;
102
103         int                     bufsize;
104         xmlChar*                xmlbuf;
105         char*                   encoded_msg;
106
107         xmlKeepBlanksDefault(0);
108
109         xmlNodePtr      message_node;
110         xmlNodePtr      type_node;
111         xmlNodePtr      thread_trace_node;
112         xmlNodePtr      protocol_node;
113         xmlNodePtr      status_node;
114         xmlNodePtr      status_text_node;
115         xmlNodePtr      status_code_node;
116         xmlNodePtr      method_node;
117         xmlNodePtr      method_name_node;
118         xmlNodePtr      params_node;
119         xmlNodePtr      result_node;
120         xmlNodePtr      content_node;
121
122
123         xmlDocPtr       doc = xmlReadDoc( 
124                         BAD_CAST "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'>"
125                         "<oils:domainObject name='oilsMessage'/></oils:root>", 
126                         NULL, NULL, XML_PARSE_NSCLEAN );
127
128         message_node = xmlDocGetRootElement(doc)->children; /* since it's the only child */
129         type_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
130         thread_trace_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
131         protocol_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
132
133         char tt[64];
134         memset(tt,0,64);
135         sprintf(tt,"%d",msg->thread_trace);
136         xmlSetProp( thread_trace_node, BAD_CAST "name", BAD_CAST "threadTrace" );
137         xmlSetProp( thread_trace_node, BAD_CAST "value", BAD_CAST tt );
138
139         char prot[64];
140         memset(prot,0,64);
141         sprintf(prot,"%d",msg->protocol);
142         xmlSetProp( protocol_node, BAD_CAST "name", BAD_CAST "protocol" );
143         xmlSetProp( protocol_node, BAD_CAST "value", BAD_CAST prot );
144
145         switch(msg->m_type) {
146
147                 case CONNECT: 
148                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
149                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "CONNECT" );
150                         break;
151
152                 case DISCONNECT:
153                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
154                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "DISCONNECT" );
155                         break;
156
157                 case STATUS:
158
159                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
160                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "STATUS" );
161                         status_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
162                         xmlSetProp( status_node, BAD_CAST "name", BAD_CAST msg->status_name );
163
164                         status_text_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
165                         xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
166                         xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
167
168                         status_code_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
169                         xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
170
171                         char sc[64];
172                         memset(sc,0,64);
173                         sprintf(sc,"%d",msg->status_code);
174                         xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST sc);
175                         
176                         break;
177
178                 case REQUEST:
179
180                         xmlSetProp( type_node, BAD_CAST "name", "type" );
181                         xmlSetProp( type_node, BAD_CAST "value", "REQUEST" );
182                         method_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
183                         xmlSetProp( method_node, BAD_CAST "name", BAD_CAST "oilsMethod" );
184
185                         if( msg->method_name != NULL ) {
186
187                                 method_name_node = xmlNewChild( method_node, NULL, BAD_CAST "domainObjectAttr", NULL );
188                                 xmlSetProp( method_name_node, BAD_CAST "name", BAD_CAST "method" );
189                                 xmlSetProp( method_name_node, BAD_CAST "value", BAD_CAST msg->method_name );
190
191                                 if( msg->params != NULL ) {
192                                         params_node = xmlNewChild( method_node, NULL, 
193                                                 BAD_CAST "params", BAD_CAST json_object_to_json_string( msg->params ) );
194                                 }
195                         }
196
197                         break;
198
199                 case RESULT:
200
201                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
202                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "RESULT" );
203                         result_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
204                         xmlSetProp( result_node, BAD_CAST "name", BAD_CAST "oilsResult" );
205
206                         status_text_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
207                         xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
208                         xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
209
210                         status_code_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
211                         xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
212
213                         char stc[64];
214                         memset(stc,0,64);
215                         sprintf(stc,"%d",msg->status_code);
216                         xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST stc);
217
218                         content_node = xmlNewChild( result_node, NULL, 
219                                         BAD_CAST "domainObject", BAD_CAST msg->result_string );
220                         xmlSetProp( content_node, BAD_CAST "name", BAD_CAST "oilsScalar" );
221
222                         break;
223
224                 default:
225                         warning_handler( "Recieved bogus message type" );
226                         return NULL;
227         }
228
229
230         // -----------------------------------------------------
231         // Dump the XML doc to a string and remove the 
232         // xml declaration
233         // -----------------------------------------------------
234
235         /* passing in a '1' means we want to retain the formatting */
236         xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
237         encoded_msg = strdup( (char*) xmlbuf );
238
239         if( encoded_msg == NULL ) 
240                 fatal_handler("message_to_xml(): Out of Memory");
241
242         xmlFree(xmlbuf);
243         xmlFreeDoc( doc );
244         xmlCleanupParser();
245
246
247         /*** remove the XML declaration */
248         int len = strlen(encoded_msg);
249         char tmp[len];
250         memset( tmp, 0, len );
251         int i;
252         int found_at = 0;
253
254         /* when we reach the first >, take everything after it */
255         for( i = 0; i!= len; i++ ) {
256                 if( encoded_msg[i] == 62) { /* ascii > */
257
258                         /* found_at holds the starting index of the rest of the doc*/
259                         found_at = i + 1; 
260                         break;
261                 }
262         }
263
264         if( found_at ) {
265                 /* move the shortened doc into the tmp buffer */
266                 strncpy( tmp, encoded_msg + found_at, len - found_at );
267                 /* move the tmp buffer back into the allocated space */
268                 memset( encoded_msg, 0, len );
269                 strcpy( encoded_msg, tmp );
270         }
271
272         return encoded_msg;
273
274 }
275
276
277 int osrf_message_from_xml( char* xml, osrf_message* msgs[] ) {
278
279         if(!xml) return 0;
280
281         xmlKeepBlanksDefault(0);
282
283         xmlNodePtr      message_node;
284         xmlDocPtr       doc = xmlReadDoc( 
285                         BAD_CAST xml, NULL, NULL, XML_PARSE_NSCLEAN );
286
287         xmlNodePtr root =xmlDocGetRootElement(doc);
288         if(!root) {
289                 warning_handler( "Attempt to build message from incomplete xml %s", xml );
290                 return 0;
291         }
292
293         int msg_index = 0;
294         message_node = root->children; /* since it's the only child */
295
296         if(!message_node) {
297                 warning_handler( "Attempt to build message from incomplete xml %s", xml );
298                 return 0;
299         }
300
301         while( message_node != NULL ) {
302
303                 xmlNodePtr cur_node = message_node->children;
304                 osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
305                 new_msg->parse_json = parse_json;
306         
307
308                 while( cur_node ) {
309
310                         xmlChar* name = NULL; 
311                         xmlChar* value = NULL;
312                         
313                         /* we're a domainObjectAttr */
314                         if( !strcmp((char*)cur_node->name,"domainObjectAttr" )) {
315                                 name = xmlGetProp( cur_node, BAD_CAST "name");
316         
317                                 if(name) {
318         
319                                         value = xmlGetProp( cur_node, BAD_CAST "value" );
320                                         if(value) {
321         
322                                                 if( (!strcmp((char*)name, "type")) ) { /* what type are we? */
323         
324                                                         if(!strcmp((char*)value, "CONNECT"))
325                                                                 new_msg->m_type = CONNECT;
326         
327                                                         if(!strcmp((char*)value, "DISCONNECT"))
328                                                                 new_msg->m_type = DISCONNECT;
329                 
330                                                         if(!strcmp((char*)value, "STATUS"))
331                                                                 new_msg->m_type = STATUS;
332                 
333                                                         if(!strcmp((char*)value, "REQUEST"))
334                                                                 new_msg->m_type = REQUEST;
335                                                         
336                                                         if(!strcmp((char*)value, "RESULT"))
337                                                                 new_msg->m_type = RESULT;
338                         
339                                                 } else if((!strcmp((char*)name, "threadTrace"))) {
340                                                         new_msg->thread_trace = atoi( (char*) value );
341                         
342                                                 } else if((!strcmp((char*)name, "protocol"))) {
343                                                         new_msg->protocol = atoi( (char*) value );
344                                                 }
345         
346                                                 xmlFree(value);
347                                         }
348                                         xmlFree(name);
349                                 }
350                         }
351         
352                         /* we're a domainObject */
353                         if( !strcmp((char*)cur_node->name,"domainObject" )) {
354         
355                                 name = xmlGetProp( cur_node, BAD_CAST "name");
356         
357                                 if(name) {
358
359                                         if( !strcmp(name,"oilsMethod") ) {
360         
361                                                 xmlNodePtr meth_node = cur_node->children;
362         
363                                                 while( meth_node != NULL ) {
364         
365                                                         if( !strcmp((char*)meth_node->name,"domainObjectAttr" )) {
366                                                                 char* meth_name = xmlGetProp( meth_node, BAD_CAST "value" );
367                                                                 if(meth_name) {
368                                                                         new_msg->method_name = strdup(meth_name);
369                                                                         xmlFree(meth_name);
370                                                                 }
371                                                         }
372         
373                                                         if( !strcmp((char*)meth_node->name,"params" ) && meth_node->children->content ) 
374                                                                 //new_msg->params = json_object_new_string( meth_node->children->content );
375                                                                 new_msg->params = json_tokener_parse(meth_node->children->content);
376         
377                                                         meth_node = meth_node->next;
378                                                 }
379                                         } //oilsMethod
380         
381                                         if( !strcmp(name,"oilsResult") || new_msg->m_type == STATUS ) {
382         
383                                                 xmlNodePtr result_nodes = cur_node->children;
384         
385                                                 while( result_nodes ) {
386         
387                                                         if(!strcmp(result_nodes->name,"domainObjectAttr")) {
388         
389                                                                 xmlChar* result_attr_name = xmlGetProp( result_nodes, BAD_CAST "name");
390                                                                 if(result_attr_name) {
391                                                                         xmlChar* result_attr_value = xmlGetProp( result_nodes, BAD_CAST "value" );
392         
393                                                                         if( result_attr_value ) {
394                                                                                 if((!strcmp((char*)result_attr_name, "status"))) 
395                                                                                         new_msg->status_text = strdup((char*) result_attr_value );
396         
397                                                                                 else if((!strcmp((char*)result_attr_name, "statusCode"))) 
398                                                                                         new_msg->status_code = atoi((char*) result_attr_value );
399                                                                                 xmlFree(result_attr_value);
400                                                                         }
401         
402                                                                         xmlFree(result_attr_name);
403                                                                 }
404         
405                                                         }
406                                                 
407         
408                                                         if(!strcmp(result_nodes->name,"domainObject")) {
409                                                                 xmlChar* r_name = xmlGetProp( result_nodes, BAD_CAST "name" );
410                                                                 if(r_name) {
411                                                                         if( !strcmp((char*)r_name,"oilsScalar") && result_nodes->children->content ) {
412                                                                                 osrf_message_set_result_content( new_msg, result_nodes->children->content);
413                                                                         }
414                                                                         xmlFree(r_name);
415                                                                 }
416                                                         }
417                                                         result_nodes = result_nodes->next;
418                                                 }
419                                         }
420                                         
421                                         if( new_msg->m_type == STATUS ) 
422                                                 new_msg->status_name = strdup(name); 
423
424                                         xmlFree(name);
425                                 }
426                         }
427         
428                         /* we're a params node */
429                         if( !strcmp((char*)cur_node->name,"params" )) {
430         
431                         }
432         
433                         cur_node = cur_node->next;
434                 }
435         
436                 msgs[msg_index] = new_msg;
437                 msg_index++;
438                 message_node = message_node->next;
439
440         } // while message_node != null
441
442         xmlCleanupCharEncodingHandlers();
443         xmlFreeDoc( doc );
444         xmlCleanupParser();
445
446         return msg_index;
447
448 }
449
450