fe9894b2433f6332939ce95839bbba11094bdf25
[Evergreen.git] / Open-ILS / src / c-apps / oils_event.c
1 #include "openils/oils_event.h"
2 #include <libxml/parser.h>
3 #include <libxml/tree.h>
4 #include "opensrf/osrf_settings.h"
5
6 static void _oilsEventParseEvents();
7
8 // The following two osrfHashes are created when we
9 // create the first osrfEvent, and are never freed.
10
11 static osrfHash* _oilsEventEvents = NULL;
12 static osrfHash* _oilsEventDescriptions = NULL;
13
14 oilsEvent* oilsNewEvent( const char* file, int line, const char* event ) {
15         if(!event) return NULL;
16         osrfLogInfo(OSRF_LOG_MARK, "Creating new event: %s", event);
17         if(!_oilsEventEvents) _oilsEventParseEvents();
18         oilsEvent* evt = safe_malloc(sizeof(oilsEvent));
19         evt->event = strdup(event);
20         evt->perm = NULL;
21         evt->permloc = -1;
22         evt->payload = NULL;
23         evt->json = NULL;
24         if(file) evt->file = strdup(file);
25         else evt->file = NULL;
26         evt->line = line;
27         return evt;
28 }
29
30 oilsEvent* oilsNewEvent2( const char* file, int line, const char* event,
31                 const jsonObject* payload ) {
32         oilsEvent* evt = oilsNewEvent(file, line, event);
33         if(payload) evt->payload = jsonObjectClone(payload);
34         return evt;
35 }
36
37 oilsEvent* oilsNewEvent3( const char* file, int line, const char* event,
38                 const char* perm, int permloc ) {
39         oilsEvent* evt = oilsNewEvent(file, line, event);
40         if(perm) {
41                 evt->perm = strdup(perm);
42                 evt->permloc = permloc;
43         }
44         return evt;
45 }
46
47 oilsEvent* oilsNewEvent4( const char* file, int line, const char* event,
48                 const char* perm, int permloc, const jsonObject* payload ) {
49         oilsEvent* evt = oilsNewEvent3( file, line, event, perm, permloc );
50         if(payload) evt->payload = jsonObjectClone(payload);
51         return evt;
52 }
53
54 void oilsEventSetPermission( oilsEvent* event, const char* perm, int permloc ) {
55         if(!(event && perm)) return;
56         if(event->perm) free(event->perm);
57         event->perm = strdup(perm);
58         event->permloc = permloc;
59 }
60
61 void oilsEventSetPayload( oilsEvent* event, const jsonObject* payload ) {
62         if(!(event && payload)) return;
63         if(event->payload) jsonObjectFree(event->payload);
64         event->payload = jsonObjectClone(payload);
65 }
66
67
68 void oilsEventFree( oilsEvent* event ) {
69         if(!event) return;
70         free(event->event);
71         free(event->perm);
72         free(event->file);
73         if(event->json) jsonObjectFree(event->json);
74     /* event->json will contain a pointer to event->payload */
75     else jsonObjectFree(event->payload); 
76         free(event);
77 }
78
79
80 jsonObject* oilsEventToJSON( oilsEvent* event ) {
81         if(!event) return NULL;
82         char* code = osrfHashGet( _oilsEventEvents, event->event );
83
84         if(!code) {
85                 osrfLogError(OSRF_LOG_MARK,  "No such event name: %s", event->event );
86                 return NULL;
87         }
88
89
90         char* lang = "en-US"; /* assume this for now */
91         char* desc = NULL;
92         osrfHash* h = osrfHashGet(_oilsEventDescriptions, lang);
93         if(h) {
94                 osrfLogDebug(OSRF_LOG_MARK, "Loaded event lang hash for %s",lang);
95                 desc = osrfHashGet(h, code);
96                 osrfLogDebug(OSRF_LOG_MARK, "Found event description %s", desc);
97         }
98         if(!desc) desc = "";
99
100         jsonObject* json = jsonNewObject(NULL);
101         jsonObjectSetKey( json, "ilsevent", jsonNewNumberObject(atoi(code)) );
102         jsonObjectSetKey( json, "textcode", jsonNewObject(event->event) );
103         jsonObjectSetKey( json, "desc", jsonNewObject(desc) );
104         jsonObjectSetKey( json, "pid", jsonNewNumberObject(getpid()) );
105
106         char buf[256];
107         memset(buf, '\0', sizeof(buf));
108         snprintf(buf, sizeof(buf), "%s:%d", event->file, event->line);
109         jsonObjectSetKey( json, "stacktrace", jsonNewObject(buf) );
110
111         if(event->perm) jsonObjectSetKey( json, "ilsperm", jsonNewObject(event->perm) );
112         if(event->permloc != -1) jsonObjectSetKey( json, "ilspermloc", jsonNewNumberObject(event->permloc) );
113         if(event->payload) jsonObjectSetKey( json, "payload", event->payload );
114         
115         if(event->json) jsonObjectFree(event->json);
116         event->json = json;
117         return json;
118 }
119
120 /* Parses the events file */
121 static void _oilsEventParseEvents() {
122         
123         char* xml = osrf_settings_host_value("/ils_events");
124
125         if(!xml) {
126                 osrfLogError(OSRF_LOG_MARK, "Unable to find ILS Events file: %s", xml);
127                 return;
128         }
129
130         xmlDocPtr doc = xmlParseFile(xml);
131         free(xml);
132         int success = 0;
133         _oilsEventEvents = osrfNewHash();
134         _oilsEventDescriptions = osrfNewHash();
135
136         if( doc ) {
137                 xmlNodePtr root = xmlDocGetRootElement(doc);
138                 if( root ) {
139                         xmlNodePtr child = root->children;
140                         while( child ) {
141                                 if( !strcmp((char*) child->name, "event") ) {
142                                         xmlChar* code = xmlGetProp( child, BAD_CAST "code");
143                                         xmlChar* textcode = xmlGetProp( child, BAD_CAST "textcode");
144                                         if( code && textcode ) {
145                                                 osrfHashSet( _oilsEventEvents, code, (char*) textcode );
146                                                 success = 1;
147                                         }
148
149                                         /* here we collect all of the <desc> nodes on the event
150                                          * element and store them based on the xml:lang attribute
151                                          */
152                                         xmlNodePtr desc = child->children;
153                                         while(desc) {
154                                                 if( !strcmp((char*) desc->name, "desc") ) {
155                                                         xmlChar* lang = xmlGetProp( desc, BAD_CAST "lang");     
156                                                         if(lang) {
157                                                                 osrfLogDebug(OSRF_LOG_MARK, "Loaded event lang: %s", (char*) lang);
158                                                                 osrfHash* langHash = osrfHashGet(
159                                                                         _oilsEventDescriptions, (char*) lang);
160                                                                 if(!langHash) {
161                                                                         langHash = osrfNewHash();
162                                                                         osrfHashSet(_oilsEventDescriptions, langHash, (char*) lang);
163                                                                 }
164                                                                 char* content;
165                                                                 if( desc->children && (content = (char*) desc->children->content) ) {
166                                                                         osrfLogDebug(OSRF_LOG_MARK, "Loaded event desc: %s", content);
167                                                                         osrfHashSet( langHash, content, (char*) code );
168                                                                 }
169                                                         }
170                                                 }
171                                                 desc = desc->next;
172                                         }
173                                 }
174                                 child = child->next;
175                         }
176                 }
177         }
178
179         if(!success) osrfLogError(OSRF_LOG_MARK,  " ! Unable to parse events file: %s", xml );
180 }
181
182