1 #include "opensrf/osrf_message.h"
4 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
6 osrf_message* msg = safe_malloc(sizeof(osrf_message));
8 msg->thread_trace = thread_trace;
9 msg->protocol = protocol;
11 msg->is_exception = 0;
17 void osrf_message_set_request_info( osrf_message* msg, char* method_name, json* json_params ) {
18 if( msg == NULL || method_name == NULL )
19 fatal_handler( "Bad params to osrf_message_set_request_params()" );
21 if( json_params != NULL )
22 msg->params = json_tokener_parse(json_object_to_json_string(json_params));
24 msg->params = json_tokener_parse("[]");
26 msg->method_name = strdup( method_name );
31 void osrf_message_set_status_info(
32 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
35 fatal_handler( "Bad params to osrf_message_set_status_info()" );
37 if( status_name != NULL )
38 msg->status_name = strdup( status_name );
40 if( status_text != NULL )
41 msg->status_text = strdup( status_text );
43 msg->status_code = status_code;
47 void osrf_message_set_result_content( osrf_message* msg, json* result_content ) {
49 fatal_handler( "Bad params to osrf_message_set_result_content()" );
50 msg->result_string = strdup(json_object_to_json_string(result_content));
51 debug_handler("Setting result_string to %s\n", msg->result_string );
52 msg->result_content = json_tokener_parse(msg->result_string);
57 void osrf_message_free( osrf_message* msg ) {
61 if( msg->status_name != NULL )
62 free(msg->status_name);
64 if( msg->status_text != NULL )
65 free(msg->status_text);
67 if( msg->result_content != NULL )
68 json_object_put( msg->result_content );
70 if( msg->result_string != NULL )
71 free( msg->result_string);
73 if( msg->method_name != NULL )
74 free(msg->method_name);
76 if( msg->params != NULL )
77 json_object_put( msg->params );
84 /* here's where things get interesting */
85 char* osrf_message_to_xml( osrf_message* msg ) {
94 xmlKeepBlanksDefault(0);
96 xmlNodePtr message_node;
98 xmlNodePtr thread_trace_node;
99 xmlNodePtr protocol_node;
100 xmlNodePtr status_node;
101 xmlNodePtr status_text_node;
102 xmlNodePtr status_code_node;
103 xmlNodePtr method_node;
104 xmlNodePtr method_name_node;
105 xmlNodePtr params_node;
106 xmlNodePtr result_node;
107 xmlNodePtr content_node;
110 xmlDocPtr doc = xmlReadDoc(
111 BAD_CAST "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'>"
112 "<oils:domainObject name='oilsMessage'/></oils:root>",
113 NULL, NULL, XML_PARSE_NSCLEAN );
115 message_node = xmlDocGetRootElement(doc)->children; /* since it's the only child */
116 type_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
117 thread_trace_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
118 protocol_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
122 sprintf(tt,"%d",msg->thread_trace);
123 xmlSetProp( thread_trace_node, BAD_CAST "name", BAD_CAST "threadTrace" );
124 xmlSetProp( thread_trace_node, BAD_CAST "value", BAD_CAST tt );
128 sprintf(prot,"%d",msg->protocol);
129 xmlSetProp( protocol_node, BAD_CAST "name", BAD_CAST "protocol" );
130 xmlSetProp( protocol_node, BAD_CAST "value", BAD_CAST prot );
132 switch(msg->m_type) {
135 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
136 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "CONNECT" );
140 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
141 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "DISCONNECT" );
146 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
147 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "STATUS" );
148 status_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
149 xmlSetProp( status_node, BAD_CAST "name", BAD_CAST msg->status_name );
151 status_text_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
152 xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
153 xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
155 status_code_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
156 xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
160 sprintf(sc,"%d",msg->status_code);
161 xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST sc);
167 xmlSetProp( type_node, BAD_CAST "name", "type" );
168 xmlSetProp( type_node, BAD_CAST "value", "REQUEST" );
169 method_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
170 xmlSetProp( method_node, BAD_CAST "name", BAD_CAST "oilsMethod" );
172 if( msg->method_name != NULL ) {
174 method_name_node = xmlNewChild( method_node, NULL, BAD_CAST "domainObjectAttr", NULL );
175 xmlSetProp( method_name_node, BAD_CAST "name", BAD_CAST "method" );
176 xmlSetProp( method_name_node, BAD_CAST "value", BAD_CAST msg->method_name );
178 if( msg->params != NULL ) {
179 params_node = xmlNewChild( method_node, NULL,
180 BAD_CAST "params", BAD_CAST json_object_to_json_string( msg->params ) );
188 xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
189 xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "RESULT" );
190 result_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
191 xmlSetProp( result_node, BAD_CAST "name", BAD_CAST "oilsResult" );
193 status_text_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
194 xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
195 xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
197 status_code_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
198 xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
202 sprintf(stc,"%d",msg->status_code);
203 xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST stc);
205 content_node = xmlNewChild( result_node, NULL,
206 BAD_CAST "domainObject", BAD_CAST msg->result_string );
207 xmlSetProp( content_node, BAD_CAST "name", BAD_CAST "oilsScalar" );
212 warning_handler( "Recieved bogus message type" );
217 // -----------------------------------------------------
218 // Dump the XML doc to a string and remove the
220 // -----------------------------------------------------
222 /* passing in a '1' means we want to retain the formatting */
223 xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
224 encoded_msg = strdup( (char*) xmlbuf );
226 if( encoded_msg == NULL )
227 fatal_handler("message_to_xml(): Out of Memory");
234 /*** remove the XML declaration */
235 int len = strlen(encoded_msg);
237 memset( tmp, 0, len );
241 /* when we reach the first >, take everything after it */
242 for( i = 0; i!= len; i++ ) {
243 if( encoded_msg[i] == 62) { /* ascii > */
245 /* found_at holds the starting index of the rest of the doc*/
252 /* move the shortened doc into the tmp buffer */
253 strncpy( tmp, encoded_msg + found_at, len - found_at );
254 /* move the tmp buffer back into the allocated space */
255 memset( encoded_msg, 0, len );
256 strcpy( encoded_msg, tmp );
264 int osrf_message_from_xml( char* xml, osrf_message* msgs[] ) {
268 xmlKeepBlanksDefault(0);
270 xmlNodePtr message_node;
271 xmlDocPtr doc = xmlReadDoc(
272 BAD_CAST xml, NULL, NULL, XML_PARSE_NSCLEAN );
274 xmlNodePtr root =xmlDocGetRootElement(doc);
276 warning_handler( "Attempt to build message from incomplete xml %s", xml );
281 message_node = root->children; /* since it's the only child */
284 warning_handler( "Attempt to build message from incomplete xml %s", xml );
288 while( message_node != NULL ) {
290 xmlNodePtr cur_node = message_node->children;
291 osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
296 xmlChar* name = NULL;
297 xmlChar* value = NULL;
299 /* we're a domainObjectAttr */
300 if( !strcmp((char*)cur_node->name,"domainObjectAttr" )) {
301 name = xmlGetProp( cur_node, BAD_CAST "name");
305 value = xmlGetProp( cur_node, BAD_CAST "value" );
308 if( (!strcmp((char*)name, "type")) ) { /* what type are we? */
310 if(!strcmp((char*)value, "CONNECT"))
311 new_msg->m_type = CONNECT;
313 if(!strcmp((char*)value, "DISCONNECT"))
314 new_msg->m_type = DISCONNECT;
316 if(!strcmp((char*)value, "STATUS"))
317 new_msg->m_type = STATUS;
319 if(!strcmp((char*)value, "REQUEST"))
320 new_msg->m_type = REQUEST;
322 if(!strcmp((char*)value, "RESULT"))
323 new_msg->m_type = RESULT;
325 } else if((!strcmp((char*)name, "threadTrace"))) {
326 new_msg->thread_trace = atoi( (char*) value );
328 } else if((!strcmp((char*)name, "protocol"))) {
329 new_msg->protocol = atoi( (char*) value );
338 /* we're a domainObject */
339 if( !strcmp((char*)cur_node->name,"domainObject" )) {
341 name = xmlGetProp( cur_node, BAD_CAST "name");
345 if( !strcmp(name,"oilsMethod") ) {
347 xmlNodePtr meth_node = cur_node->children;
349 while( meth_node != NULL ) {
351 if( !strcmp((char*)meth_node->name,"domainObjectAttr" )) {
352 char* meth_name = xmlGetProp( meth_node, BAD_CAST "value" );
354 new_msg->method_name = strdup(meth_name);
359 if( !strcmp((char*)meth_node->name,"params" ) && meth_node->children->content )
360 //new_msg->params = json_object_new_string( meth_node->children->content );
361 new_msg->params = json_tokener_parse(meth_node->children->content);
363 meth_node = meth_node->next;
367 if( !strcmp(name,"oilsResult") || new_msg->m_type == STATUS ) {
369 xmlNodePtr result_nodes = cur_node->children;
371 while( result_nodes ) {
373 if(!strcmp(result_nodes->name,"domainObjectAttr")) {
375 xmlChar* result_attr_name = xmlGetProp( result_nodes, BAD_CAST "name");
376 if(result_attr_name) {
377 xmlChar* result_attr_value = xmlGetProp( result_nodes, BAD_CAST "value" );
379 if( result_attr_value ) {
380 if((!strcmp((char*)result_attr_name, "status")))
381 new_msg->status_text = strdup((char*) result_attr_value );
383 else if((!strcmp((char*)result_attr_name, "statusCode")))
384 new_msg->status_code = atoi((char*) result_attr_value );
385 xmlFree(result_attr_value);
388 xmlFree(result_attr_name);
394 if(!strcmp(result_nodes->name,"domainObject")) {
395 xmlChar* r_name = xmlGetProp( result_nodes, BAD_CAST "name" );
397 if( !strcmp((char*)r_name,"oilsScalar") && result_nodes->children->content ) {
398 new_msg->result_string = strdup(result_nodes->children->content);
399 new_msg->result_content = json_tokener_parse(result_nodes->children->content);
404 result_nodes = result_nodes->next;
408 if( new_msg->m_type == STATUS )
409 new_msg->status_name = strdup(name);
415 /* we're a params node */
416 if( !strcmp((char*)cur_node->name,"params" )) {
420 cur_node = cur_node->next;
423 msgs[msg_index] = new_msg;
425 message_node = message_node->next;
427 } // while message_node != null
429 xmlCleanupCharEncodingHandlers();