initializing some vars so gcc will stop warning
[Evergreen.git] / Open-ILS / src / c-apps / oils_idl-core.c
1 #include "openils/oils_idl.h"
2 /*
3  * vim:noet:ts=4:
4  */
5
6 #include <stdlib.h>
7 #include <string.h>
8 #include <libxml/globals.h>
9 #include <libxml/xmlerror.h>
10 #include <libxml/parser.h>
11 #include <libxml/tree.h>
12 #include <libxml/debugXML.h>
13 #include <libxml/xmlmemory.h>
14
15 #define PERSIST_NS "http://open-ils.org/spec/opensrf/IDL/persistence/v1"
16 #define OBJECT_NS "http://open-ils.org/spec/opensrf/IDL/objects/v1"
17 #define BASE_NS "http://opensrf.org/spec/IDL/base/v1"
18
19 static xmlDocPtr idlDoc = NULL; // parse and store the IDL here
20
21 /* parse and store the IDL here */
22 static osrfHash* idlHash;
23
24 osrfHash* oilsIDL(void) { return idlHash; }
25 osrfHash* oilsIDLInit( const char* idl_filename ) {
26
27         if (idlHash) return idlHash;
28
29         char* string_tmp = NULL;
30
31         idlHash = osrfNewHash();
32         osrfHash* usrData = NULL;
33
34         osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
35         idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
36         
37         if (!idlDoc) {
38                 osrfLogError(OSRF_LOG_MARK, "Could not load or parse the IDL XML file!");
39                 return NULL;
40         }
41
42         osrfLogDebug(OSRF_LOG_MARK, "Initializing the Fieldmapper IDL...");
43
44         xmlNodePtr docRoot = xmlDocGetRootElement(idlDoc);
45         xmlNodePtr kid = docRoot->children;
46         while (kid) {
47                 if (!strcmp( (char*)kid->name, "class" )) {
48
49                         usrData = osrfNewHash();
50                         osrfHashSet( usrData, xmlGetProp(kid, BAD_CAST "id"), "classname");
51                         osrfHashSet( usrData, xmlGetNsProp(kid, BAD_CAST "fieldmapper", BAD_CAST OBJECT_NS), "fieldmapper");
52                         osrfHashSet( usrData, xmlGetNsProp(kid, BAD_CAST "readonly", BAD_CAST PERSIST_NS), "readonly");
53
54                         osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
55
56                         string_tmp = NULL;
57                         if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "tablename", BAD_CAST PERSIST_NS))) {
58                                 osrfLogDebug(OSRF_LOG_MARK, "Using table '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
59                                 osrfHashSet(
60                                         usrData,
61                                         strdup( string_tmp ),
62                                         "tablename"
63                                 );
64                         }
65
66                         string_tmp = NULL;
67                         if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "virtual", BAD_CAST PERSIST_NS))) {
68                                 osrfHashSet(
69                                         usrData,
70                                         strdup( string_tmp ),
71                                         "virtual"
72                                 );
73                         }
74
75                         osrfStringArray* controller = osrfNewStringArray(0);
76                         string_tmp = NULL;
77                         if( (string_tmp = (char*)xmlGetProp(kid, BAD_CAST "controller") )) {
78                                 char* controller_list = strdup( string_tmp );
79                                 osrfLogDebug(OSRF_LOG_MARK, "Controller list is %s", string_tmp );
80
81                                 if (strlen( controller_list ) > 0) {
82                                         char* st_tmp = NULL;
83                                         char* _controller_class = strtok_r(controller_list, " ", &st_tmp);
84                                         osrfStringArrayAdd(controller, strdup(_controller_class));
85
86                                         while ((_controller_class = strtok_r(NULL, " ", &st_tmp))) {
87                                                 osrfStringArrayAdd(controller, strdup(_controller_class));
88                                         }
89                                 }
90                                 free(controller_list);
91                         }
92                         osrfHashSet( usrData, controller, "controller");
93
94
95                         osrfHash* _tmp;
96                         osrfHash* links = osrfNewHash();
97                         osrfHash* fields = osrfNewHash();
98
99                         osrfHashSet( usrData, fields, "fields" );
100                         osrfHashSet( usrData, links, "links" );
101
102                         xmlNodePtr _cur = kid->children;
103
104                         while (_cur) {
105
106                                 if (!strcmp( (char*)_cur->name, "fields" )) {
107
108                                         string_tmp = NULL;
109                                         if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
110                                                 osrfHashSet(
111                                                         usrData,
112                                                         strdup( string_tmp ),
113                                                         "primarykey"
114                                                 );
115                                         }
116
117                                         string_tmp = NULL;
118                                         if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
119                                                 osrfHashSet(
120                                                         usrData,
121                                                         strdup( string_tmp ),
122                                                         "sequence"
123                                                 );
124                                         }
125
126                                         xmlNodePtr _f = _cur->children;
127
128                                         while(_f) {
129                                                 if (strcmp( (char*)_f->name, "field" )) {
130                                                         _f = _f->next;
131                                                         continue;
132                                                 }
133
134                                                 _tmp = osrfNewHash();
135
136                                                 string_tmp = NULL;
137                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
138                                                         osrfHashSet(
139                                                                 _tmp,
140                                                                 strdup( string_tmp ),
141                                                                 "array_position"
142                                                         );
143                                                 }
144
145                                                 string_tmp = NULL;
146                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "i18n", BAD_CAST PERSIST_NS)) ) {
147                                                         osrfHashSet(
148                                                                 _tmp,
149                                                                 strdup( string_tmp ),
150                                                                 "i18n"
151                                                         );
152                                                 }
153
154                                                 string_tmp = NULL;
155                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
156                                                         osrfHashSet(
157                                                                 _tmp,
158                                                                 strdup( string_tmp ),
159                                                                 "virtual"
160                                                         );
161                                                 }
162
163                                                 string_tmp = NULL;
164                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
165                                                         osrfHashSet(
166                                                                 _tmp,
167                                                                 strdup( string_tmp ),
168                                                                 "primitive"
169                                                         );
170                                                 }
171
172                                                 string_tmp = NULL;
173                                                 if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
174                                                         osrfHashSet(
175                                                                 _tmp,
176                                                                 strdup( string_tmp ),
177                                                                 "name"
178                                                         );
179                                                 }
180
181                                                 osrfLogDebug(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
182
183                                                 osrfHashSet(
184                                                         fields,
185                                                         _tmp,
186                                                         strdup( string_tmp )
187                                                 );
188                                                 _f = _f->next;
189                                         }
190                                 }
191
192                                 if (!strcmp( (char*)_cur->name, "links" )) {
193                                         xmlNodePtr _l = _cur->children;
194
195                                         while(_l) {
196                                                 if (strcmp( (char*)_l->name, "link" )) {
197                                                         _l = _l->next;
198                                                         continue;
199                                                 }
200
201                                                 _tmp = osrfNewHash();
202
203                                                 string_tmp = NULL;
204                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
205                                                         osrfHashSet(
206                                                                 _tmp,
207                                                                 strdup( string_tmp ),
208                                                                 "reltype"
209                                                         );
210                                                 }
211                                                 osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
212
213                                                 string_tmp = NULL;
214                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
215                                                         osrfHashSet(
216                                                                 _tmp,
217                                                                 strdup( string_tmp ),
218                                                                 "key"
219                                                         );
220                                                 }
221                                                 osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
222
223                                                 string_tmp = NULL;
224                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
225                                                         osrfHashSet(
226                                                                 _tmp,
227                                                                 strdup( string_tmp ),
228                                                                 "class"
229                                                         );
230                                                 }
231                                                 osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
232
233                                                 osrfStringArray* map = osrfNewStringArray(0);
234
235                                                 string_tmp = NULL;
236                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "map") )) {
237                                                         char* map_list = strdup( string_tmp );
238                                                         osrfLogDebug(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
239
240                                                         if (strlen( map_list ) > 0) {
241                                                                 char* st_tmp = NULL;
242                                                                 char* _map_class = strtok_r(map_list, " ", &st_tmp);
243                                                                 osrfStringArrayAdd(map, strdup(_map_class));
244                                                 
245                                                                 while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
246                                                                         osrfStringArrayAdd(map, strdup(_map_class));
247                                                                 }
248                                                         }
249                                                         free(map_list);
250                                                 }
251                                                 osrfHashSet( _tmp, map, "map");
252
253                                                 string_tmp = NULL;
254                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
255                                                         osrfHashSet(
256                                                                 _tmp,
257                                                                 strdup( string_tmp ),
258                                                                 "field"
259                                                         );
260                                                 }
261
262                                                 osrfHashSet(
263                                                         links,
264                                                         _tmp,
265                                                         strdup( string_tmp )
266                                                 );
267
268                                                 osrfLogDebug(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
269
270                                                 _l = _l->next;
271                                         }
272                                 }
273
274                                 if (!strcmp( (char*)_cur->name, "source_definition" )) {
275                                         string_tmp = NULL;
276                                         if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
277                                                 osrfLogDebug(OSRF_LOG_MARK, "Using source definition '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
278                                                 osrfHashSet(
279                                                         usrData,
280                                                         strdup( string_tmp ),
281                                                         "source_definition"
282                                                 );
283                                         }
284
285                                 }
286
287                                 _cur = _cur->next;
288                         } // end while
289                 }
290
291                 kid = kid->next;
292         } // end while
293
294         osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
295
296         return idlHash;
297 }
298
299 osrfHash* oilsIDLFindPath( const char* path, ... ) {
300         if(!path || strlen(path) < 1) return NULL;
301
302         osrfHash* obj = idlHash;
303
304         VA_LIST_TO_STRING(path);
305         char* buf = VA_BUF;
306
307         char* token = NULL;
308         char* t = buf;
309         char* tt;
310
311         token = strtok_r(t, "/", &tt);
312         if(!token) return NULL;
313
314         do {
315                 obj = osrfHashGet(obj, token);
316         } while( (token = strtok_r(NULL, "/", &tt)) && obj);
317
318         return obj;
319 }
320
321 int oilsIDL_classIsFieldmapper ( const char* classname ) {
322         if (!classname) return 0;
323         if(oilsIDLFindPath( "/%s", classname )) return 1;
324         return 0;
325 }
326
327 int oilsIDL_ntop (const char* classname, const char* fieldname) {
328         osrfHash* _pos = NULL;
329
330         if (!oilsIDL_classIsFieldmapper(classname)) return -1;
331         _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
332         if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
333         return -1;
334 }
335
336 char * oilsIDL_pton (const char* classname, int pos) {
337         char* ret = NULL;
338         osrfHash* f = NULL;
339         osrfHash* fields = NULL;
340         osrfHashIterator* itr = NULL;
341
342         if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
343
344         fields = oilsIDLFindPath( "/%s/fields", classname );
345         itr = osrfNewHashIterator( fields );
346
347         while ( (f = osrfHashIteratorNext( itr )) ) {
348                 if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
349                         ret = strdup(osrfHashIteratorKey(itr));
350                         break;
351                 }
352         }
353
354         osrfHashIteratorFree( itr );
355
356         return ret;
357 }
358