1 #include "opensrf/osrf_message.h"
8 char* x = "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'><oils:domainObject name='oilsMessage'><oils:domainObjectAttr value='STATUS' name='type'/><oils:domainObjectAttr value='12' name='threadTrace'/><oils:domainObject name='oilsMethodException'><oils:domainObjectAttr value=' *** Call to [div] failed for session [1351200643.110915057523738], thread trace [12]: JabberDisconnected Exception This JabberClient instance is no longer connected to the server' name='status'/><oils:domainObjectAttr value='500' name='statusCode'/></oils:domainObject></oils:domainObject></oils:root>";
12 char* x = "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'>"
13 "<oils:domainObject name='oilsMessage'>"
14 "<oils:domainObjectAttr value='STATUS' name='type'/>"
15 "<oils:domainObjectAttr value='1' name='threadTrace'/>"
16 "<oils:domainObject name='oilsConnectStatus'>"
17 "<oils:domainObjectAttr value='Connection Successful' name='status'/>"
18 "<oils:domainObjectAttr value='200' name='statusCode'/>"
19 "</oils:domainObject></oils:domainObject>"
21 "<oils:domainObject name='oilsMessage'>"
22 "<oils:domainObjectAttr value='STATUS' name='type'/>"
23 "<oils:domainObjectAttr value='1' name='threadTrace'/>"
24 "<oils:domainObject name='oilsConnectStatus'>"
25 "<oils:domainObjectAttr value='Request Complete' name='status'/>"
26 "<oils:domainObjectAttr value='205' name='statusCode'/>"
27 "</oils:domainObject></oils:domainObject>"
35 int ret = osrf_message_from_xml( x, arr );
36 fprintf(stderr, "RET: %d\n", ret );
38 fatal_handler( "none parsed" );
40 osrf_message* xml_msg = arr[0];
41 printf("Message name: %s\nstatus %s, \nstatusCode %d\n", xml_msg->status_name, xml_msg->status_text, xml_msg->status_code );
44 // printf("Message 2 status %s, statusCode %d\n", xml_msg->status_text, xml_msg->status_code );
54 osrf_message* msg = osrf_message_init( STATUS, 1, 1 );
55 // osrf_message* msg = osrf_message_init( CONNECT, 1, 1 );
56 //osrf_message* msg = osrf_message_init( REQUEST, 1, 1 );
57 osrf_message_set_status_info( msg, "oilsConnectStatus", "Connection Succsesful", 200 );
59 json* params = json_object_new_array();
60 json_object_array_add(params, json_object_new_int(1));
61 json_object_array_add(params, json_object_new_int(2));
63 osrf_message_set_request_info( msg, "add", params );
64 //osrf_message_set_result_content( msg, params );
65 json_object_put( params );
67 char* xml = osrf_message_to_xml( msg );
68 printf( "\n\nMessage as XML\n%s", xml );
70 osrf_message* xml_msg = osrf_message_from_xml( xml );
72 printf( "Message stuff \n\ntype %d"
73 "\nthread_trace %d \nprotocol %d "
75 "\nstatus_text %s\nstatus_code %d"
76 "\nresult_content %s \nparams %s"
77 "\n", xml_msg->m_type,
78 xml_msg->thread_trace, xml_msg->protocol, xml_msg->status_name,
79 xml_msg->status_text, xml_msg->status_code,
80 json_object_to_json_string( xml_msg->result_content),
81 json_object_to_json_string(xml_msg->params)
86 osrf_message_free( msg );
87 osrf_message_free( xml_msg );
94 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
96 osrf_message* msg = safe_malloc(sizeof(osrf_message));
98 msg->thread_trace = thread_trace;
99 msg->protocol = protocol;
101 msg->is_exception = 0;
107 void osrf_message_set_request_info( osrf_message* msg, char* method_name, json* json_params ) {
108 if( msg == NULL || method_name == NULL )
109 fatal_handler( "Bad params to osrf_message_set_request_params()" );
111 if( json_params != NULL )
112 msg->params = json_tokener_parse(json_object_to_json_string(json_params));
114 msg->params = json_tokener_parse("[]");
116 msg->method_name = strdup( method_name );
121 void osrf_message_set_status_info(
122 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
125 fatal_handler( "Bad params to osrf_message_set_status_info()" );
127 if( status_name != NULL )
128 msg->status_name = strdup( status_name );
130 if( status_text != NULL )
131 msg->status_text = strdup( status_text );
133 msg->status_code = status_code;
137 void osrf_message_set_result_content( osrf_message* msg, json* result_content ) {
139 fatal_handler( "Bad params to osrf_message_set_result_content()" );
140 msg->result_content = json_tokener_parse(json_object_to_json_string(result_content));
145 void osrf_message_free( osrf_message* msg ) {
149 if( msg->status_name != NULL )
150 free(msg->status_name);
152 if( msg->status_text != NULL )
153 free(msg->status_text);
155 if( msg->result_content != NULL )
156 json_object_put( msg->result_content );
158 if( msg->method_name != NULL )
159 free(msg->method_name);
161 if( msg->params != NULL )
162 json_object_put( msg->params );
169 /* here's where things get interesting */
170 char* osrf_message_to_xml( osrf_message* msg ) {
179 xmlKeepBlanksDefault(0);
181 xmlNodePtr message_node;
182 xmlNodePtr type_node;
183 xmlNodePtr thread_trace_node;
184 xmlNodePtr protocol_node;
185 xmlNodePtr status_node;
186 xmlNodePtr status_text_node;
187 xmlNodePtr status_code_node;
188 xmlNodePtr method_node;
189 xmlNodePtr method_name_node;
190 xmlNodePtr params_node;
191 xmlNodePtr result_node;
192 xmlNodePtr content_node;
195 xmlDocPtr doc = xmlReadDoc(
196 BAD_CAST "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'>"
197 "<oils:domainObject name='oilsMessage'/></oils:root>",
198 NULL, NULL, XML_PARSE_NSCLEAN );
200 message_node = xmlDocGetRootElement(doc)->children; /* since it's the only child */
201 type_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
202 thread_trace_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
203 protocol_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
207 sprintf(tt,"%d",msg->thread_trace);
208 xmlSetProp( thread_trace_node, BAD_CAST "name", BAD_CAST "threadTrace" );
209 xmlSetProp( thread_trace_node, BAD_CAST "value", BAD_CAST tt );
213 sprintf(prot,"%d",msg->protocol);
214 xmlSetProp( protocol_node, BAD_CAST "name", BAD_CAST "protocol" );
215 xmlSetProp( protocol_node, BAD_CAST "value", BAD_CAST prot );
217 switch(msg->m_type) {
220 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
221 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "CONNECT" );
225 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
226 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "DISCONNECT" );
231 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
232 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "STATUS" );
233 status_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
234 xmlSetProp( status_node, BAD_CAST "name", BAD_CAST msg->status_name );
236 status_text_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
237 xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
238 xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
240 status_code_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
241 xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
245 sprintf(sc,"%d",msg->status_code);
246 xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST sc);
252 xmlSetProp( type_node, BAD_CAST "name", "type" );
253 xmlSetProp( type_node, BAD_CAST "value", "REQUEST" );
254 method_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
255 xmlSetProp( method_node, BAD_CAST "name", BAD_CAST "oilsMethod" );
257 if( msg->method_name != NULL ) {
259 method_name_node = xmlNewChild( method_node, NULL, BAD_CAST "domainObjectAttr", NULL );
260 xmlSetProp( method_name_node, BAD_CAST "name", BAD_CAST "method" );
261 xmlSetProp( method_name_node, BAD_CAST "value", BAD_CAST msg->method_name );
263 if( msg->params != NULL ) {
264 params_node = xmlNewChild( method_node, NULL,
265 BAD_CAST "params", BAD_CAST json_object_to_json_string( msg->params ) );
273 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
274 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "RESULT" );
275 result_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
276 xmlSetProp( result_node, BAD_CAST "name", BAD_CAST "oilsResult" );
278 status_text_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
279 xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
280 xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
282 status_code_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
283 xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
287 sprintf(stc,"%d",msg->status_code);
288 xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST stc);
290 content_node = xmlNewChild( result_node, NULL,
291 BAD_CAST "domainObject", BAD_CAST json_object_to_json_string( msg->result_content ) );
292 xmlSetProp( content_node, BAD_CAST "name", BAD_CAST "oilsScalar" );
297 warning_handler( "Recieved bogus message type" );
302 // -----------------------------------------------------
303 // Dump the XML doc to a string and remove the
305 // -----------------------------------------------------
307 /* passing in a '1' means we want to retain the formatting */
308 xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
309 encoded_msg = strdup( (char*) xmlbuf );
311 if( encoded_msg == NULL )
312 fatal_handler("message_to_xml(): Out of Memory");
319 /*** remove the XML declaration */
320 int len = strlen(encoded_msg);
322 memset( tmp, 0, len );
326 /* when we reach the first >, take everything after it */
327 for( i = 0; i!= len; i++ ) {
328 if( encoded_msg[i] == 62) { /* ascii > */
330 /* found_at holds the starting index of the rest of the doc*/
337 /* move the shortened doc into the tmp buffer */
338 strncpy( tmp, encoded_msg + found_at, len - found_at );
339 /* move the tmp buffer back into the allocated space */
340 memset( encoded_msg, 0, len );
341 strcpy( encoded_msg, tmp );
349 int osrf_message_from_xml( char* xml, osrf_message* msgs[] ) {
353 xmlKeepBlanksDefault(0);
355 xmlNodePtr message_node;
356 xmlDocPtr doc = xmlReadDoc(
357 BAD_CAST xml, NULL, NULL, XML_PARSE_NSCLEAN );
359 xmlNodePtr root =xmlDocGetRootElement(doc);
361 warning_handler( "Attempt to build message from incomplete xml %s", xml );
366 message_node = root->children; /* since it's the only child */
369 warning_handler( "Attempt to build message from incomplete xml %s", xml );
373 while( message_node != NULL ) {
375 xmlNodePtr cur_node = message_node->children;
376 osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
381 xmlChar* name = NULL;
382 xmlChar* value = NULL;
384 /* we're a domainObjectAttr */
385 if( !strcmp((char*)cur_node->name,"domainObjectAttr" )) {
386 name = xmlGetProp( cur_node, BAD_CAST "name");
390 value = xmlGetProp( cur_node, BAD_CAST "value" );
393 if( (!strcmp((char*)name, "type")) ) { /* what type are we? */
395 if(!strcmp((char*)value, "CONNECT"))
396 new_msg->m_type = CONNECT;
398 if(!strcmp((char*)value, "DISCONNECT"))
399 new_msg->m_type = DISCONNECT;
401 if(!strcmp((char*)value, "STATUS"))
402 new_msg->m_type = STATUS;
404 if(!strcmp((char*)value, "REQUEST"))
405 new_msg->m_type = REQUEST;
407 if(!strcmp((char*)value, "RESULT"))
408 new_msg->m_type = RESULT;
410 } else if((!strcmp((char*)name, "threadTrace"))) {
411 new_msg->thread_trace = atoi( (char*) value );
413 } else if((!strcmp((char*)name, "protocol"))) {
414 new_msg->protocol = atoi( (char*) value );
423 /* we're a domainObject */
424 if( !strcmp((char*)cur_node->name,"domainObject" )) {
426 name = xmlGetProp( cur_node, BAD_CAST "name");
430 if( !strcmp(name,"oilsMethod") ) {
432 xmlNodePtr meth_node = cur_node->children;
434 while( meth_node != NULL ) {
436 if( !strcmp((char*)meth_node->name,"domainObjectAttr" )) {
437 char* meth_name = xmlGetProp( meth_node, BAD_CAST "value" );
439 new_msg->method_name = strdup(meth_name);
444 if( !strcmp((char*)meth_node->name,"params" ) && meth_node->children->content )
445 //new_msg->params = json_object_new_string( meth_node->children->content );
446 new_msg->params = json_tokener_parse(meth_node->children->content);
448 meth_node = meth_node->next;
452 if( !strcmp(name,"oilsResult") || new_msg->m_type == STATUS ) {
454 xmlNodePtr result_nodes = cur_node->children;
456 while( result_nodes ) {
458 if(!strcmp(result_nodes->name,"domainObjectAttr")) {
460 xmlChar* result_attr_name = xmlGetProp( result_nodes, BAD_CAST "name");
461 if(result_attr_name) {
462 xmlChar* result_attr_value = xmlGetProp( result_nodes, BAD_CAST "value" );
464 if( result_attr_value ) {
465 if((!strcmp((char*)result_attr_name, "status")))
466 new_msg->status_text = strdup((char*) result_attr_value );
468 else if((!strcmp((char*)result_attr_name, "statusCode")))
469 new_msg->status_code = atoi((char*) result_attr_value );
470 xmlFree(result_attr_value);
473 xmlFree(result_attr_name);
479 if(!strcmp(result_nodes->name,"domainObject")) {
480 xmlChar* r_name = xmlGetProp( result_nodes, BAD_CAST "name" );
482 if( !strcmp((char*)r_name,"oilsScalar") && result_nodes->children->content )
483 new_msg->result_content = json_tokener_parse(result_nodes->children->content);
487 result_nodes = result_nodes->next;
491 if( new_msg->m_type == STATUS )
492 new_msg->status_name = strdup(name);
498 /* we're a params node */
499 if( !strcmp((char*)cur_node->name,"params" )) {
503 cur_node = cur_node->next;
506 msgs[msg_index] = new_msg;
508 message_node = message_node->next;
510 } // while message_node != null
512 xmlCleanupCharEncodingHandlers();