1 #include "opensrf/osrf_message.h"
6 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
8 osrf_message* msg = safe_malloc(sizeof(osrf_message));
10 msg->thread_trace = thread_trace;
11 msg->protocol = protocol;
13 msg->is_exception = 0;
14 msg->parse_json = parse_json;
20 void osrf_message_set_json_parse( int ibool ) {
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()" );
29 if( json_params != NULL )
30 msg->params = json_tokener_parse(json_object_to_json_string(json_params));
32 msg->params = json_tokener_parse("[]");
34 msg->method_name = strdup( method_name );
39 void osrf_message_set_status_info(
40 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
43 fatal_handler( "Bad params to osrf_message_set_status_info()" );
45 if( status_name != NULL )
46 msg->status_name = strdup( status_name );
48 if( status_text != NULL )
49 msg->status_text = strdup( status_text );
51 msg->status_code = status_code;
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()" );
59 msg->result_string = strdup(json_string);
60 debug_handler("Setting result_string to %s\n", msg->result_string );
62 debug_handler( "Message Parse JSON is set to: %d", msg->parse_json );
65 msg->result_content = json_tokener_parse(msg->result_string);
70 void osrf_message_free( osrf_message* msg ) {
74 if( msg->status_name != NULL )
75 free(msg->status_name);
77 if( msg->status_text != NULL )
78 free(msg->status_text);
80 if( msg->result_content != NULL )
81 json_object_put( msg->result_content );
83 if( msg->result_string != NULL )
84 free( msg->result_string);
86 if( msg->method_name != NULL )
87 free(msg->method_name);
89 if( msg->params != NULL )
90 json_object_put( msg->params );
97 /* here's where things get interesting */
98 char* osrf_message_to_xml( osrf_message* msg ) {
107 xmlKeepBlanksDefault(0);
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;
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 );
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 );
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 );
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 );
145 switch(msg->m_type) {
148 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
149 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "CONNECT" );
153 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
154 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "DISCONNECT" );
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 );
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);
168 status_code_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
169 xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
173 sprintf(sc,"%d",msg->status_code);
174 xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST sc);
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" );
185 if( msg->method_name != NULL ) {
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 );
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 ) );
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" );
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);
210 status_code_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
211 xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
215 sprintf(stc,"%d",msg->status_code);
216 xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST stc);
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" );
225 warning_handler( "Recieved bogus message type" );
230 // -----------------------------------------------------
231 // Dump the XML doc to a string and remove the
233 // -----------------------------------------------------
235 /* passing in a '1' means we want to retain the formatting */
236 xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
237 encoded_msg = strdup( (char*) xmlbuf );
239 if( encoded_msg == NULL )
240 fatal_handler("message_to_xml(): Out of Memory");
247 /*** remove the XML declaration */
248 int len = strlen(encoded_msg);
250 memset( tmp, 0, len );
254 /* when we reach the first >, take everything after it */
255 for( i = 0; i!= len; i++ ) {
256 if( encoded_msg[i] == 62) { /* ascii > */
258 /* found_at holds the starting index of the rest of the doc*/
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 );
277 int osrf_message_from_xml( char* xml, osrf_message* msgs[] ) {
281 xmlKeepBlanksDefault(0);
283 xmlNodePtr message_node;
284 xmlDocPtr doc = xmlReadDoc(
285 BAD_CAST xml, NULL, NULL, XML_PARSE_NSCLEAN );
287 xmlNodePtr root =xmlDocGetRootElement(doc);
289 warning_handler( "Attempt to build message from incomplete xml %s", xml );
294 message_node = root->children; /* since it's the only child */
297 warning_handler( "Attempt to build message from incomplete xml %s", xml );
301 while( message_node != NULL ) {
303 xmlNodePtr cur_node = message_node->children;
304 osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
305 new_msg->parse_json = parse_json;
310 xmlChar* name = NULL;
311 xmlChar* value = NULL;
313 /* we're a domainObjectAttr */
314 if( !strcmp((char*)cur_node->name,"domainObjectAttr" )) {
315 name = xmlGetProp( cur_node, BAD_CAST "name");
319 value = xmlGetProp( cur_node, BAD_CAST "value" );
322 if( (!strcmp((char*)name, "type")) ) { /* what type are we? */
324 if(!strcmp((char*)value, "CONNECT"))
325 new_msg->m_type = CONNECT;
327 if(!strcmp((char*)value, "DISCONNECT"))
328 new_msg->m_type = DISCONNECT;
330 if(!strcmp((char*)value, "STATUS"))
331 new_msg->m_type = STATUS;
333 if(!strcmp((char*)value, "REQUEST"))
334 new_msg->m_type = REQUEST;
336 if(!strcmp((char*)value, "RESULT"))
337 new_msg->m_type = RESULT;
339 } else if((!strcmp((char*)name, "threadTrace"))) {
340 new_msg->thread_trace = atoi( (char*) value );
342 } else if((!strcmp((char*)name, "protocol"))) {
343 new_msg->protocol = atoi( (char*) value );
352 /* we're a domainObject */
353 if( !strcmp((char*)cur_node->name,"domainObject" )) {
355 name = xmlGetProp( cur_node, BAD_CAST "name");
359 if( !strcmp(name,"oilsMethod") ) {
361 xmlNodePtr meth_node = cur_node->children;
363 while( meth_node != NULL ) {
365 if( !strcmp((char*)meth_node->name,"domainObjectAttr" )) {
366 char* meth_name = xmlGetProp( meth_node, BAD_CAST "value" );
368 new_msg->method_name = strdup(meth_name);
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);
377 meth_node = meth_node->next;
381 if( !strcmp(name,"oilsResult") || new_msg->m_type == STATUS ) {
383 xmlNodePtr result_nodes = cur_node->children;
385 while( result_nodes ) {
387 if(!strcmp(result_nodes->name,"domainObjectAttr")) {
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" );
393 if( result_attr_value ) {
394 if((!strcmp((char*)result_attr_name, "status")))
395 new_msg->status_text = strdup((char*) result_attr_value );
397 else if((!strcmp((char*)result_attr_name, "statusCode")))
398 new_msg->status_code = atoi((char*) result_attr_value );
399 xmlFree(result_attr_value);
402 xmlFree(result_attr_name);
408 if(!strcmp(result_nodes->name,"domainObject")) {
409 xmlChar* r_name = xmlGetProp( result_nodes, BAD_CAST "name" );
411 if( !strcmp((char*)r_name,"oilsScalar") && result_nodes->children->content ) {
412 osrf_message_set_result_content( new_msg, result_nodes->children->content);
417 result_nodes = result_nodes->next;
421 if( new_msg->m_type == STATUS )
422 new_msg->status_name = strdup(name);
428 /* we're a params node */
429 if( !strcmp((char*)cur_node->name,"params" )) {
433 cur_node = cur_node->next;
436 msgs[msg_index] = new_msg;
438 message_node = message_node->next;
440 } // while message_node != null
442 xmlCleanupCharEncodingHandlers();