]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/oils_idl-core.c
Patch from Scott McKellar to apply some const-correctness to the ILS C code
[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;
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                         }
91                         osrfHashSet( usrData, controller, "controller");
92
93
94                         osrfHash* _tmp;
95                         osrfHash* links = osrfNewHash();
96                         osrfHash* fields = osrfNewHash();
97
98                         osrfHashSet( usrData, fields, "fields" );
99                         osrfHashSet( usrData, links, "links" );
100
101                         xmlNodePtr _cur = kid->children;
102
103                         while (_cur) {
104
105                                 if (!strcmp( (char*)_cur->name, "fields" )) {
106
107                                         string_tmp = NULL;
108                                         if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
109                                                 osrfHashSet(
110                                                         usrData,
111                                                         strdup( string_tmp ),
112                                                         "primarykey"
113                                                 );
114                                         }
115
116                                         string_tmp = NULL;
117                                         if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
118                                                 osrfHashSet(
119                                                         usrData,
120                                                         strdup( string_tmp ),
121                                                         "sequence"
122                                                 );
123                                         }
124
125                                         xmlNodePtr _f = _cur->children;
126
127                                         while(_f) {
128                                                 if (strcmp( (char*)_f->name, "field" )) {
129                                                         _f = _f->next;
130                                                         continue;
131                                                 }
132
133                                                 _tmp = osrfNewHash();
134
135                                                 string_tmp = NULL;
136                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
137                                                         osrfHashSet(
138                                                                 _tmp,
139                                                                 strdup( string_tmp ),
140                                                                 "array_position"
141                                                         );
142                                                 }
143
144                                                 string_tmp = NULL;
145                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "i18n", BAD_CAST PERSIST_NS)) ) {
146                                                         osrfHashSet(
147                                                                 _tmp,
148                                                                 strdup( string_tmp ),
149                                                                 "i18n"
150                                                         );
151                                                 }
152
153                                                 string_tmp = NULL;
154                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
155                                                         osrfHashSet(
156                                                                 _tmp,
157                                                                 strdup( string_tmp ),
158                                                                 "virtual"
159                                                         );
160                                                 }
161
162                                                 string_tmp = NULL;
163                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
164                                                         osrfHashSet(
165                                                                 _tmp,
166                                                                 strdup( string_tmp ),
167                                                                 "primitive"
168                                                         );
169                                                 }
170
171                                                 string_tmp = NULL;
172                                                 if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
173                                                         osrfHashSet(
174                                                                 _tmp,
175                                                                 strdup( string_tmp ),
176                                                                 "name"
177                                                         );
178                                                 }
179
180                                                 osrfLogDebug(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
181
182                                                 osrfHashSet(
183                                                         fields,
184                                                         _tmp,
185                                                         strdup( string_tmp )
186                                                 );
187                                                 _f = _f->next;
188                                         }
189                                 }
190
191                                 if (!strcmp( (char*)_cur->name, "links" )) {
192                                         xmlNodePtr _l = _cur->children;
193
194                                         while(_l) {
195                                                 if (strcmp( (char*)_l->name, "link" )) {
196                                                         _l = _l->next;
197                                                         continue;
198                                                 }
199
200                                                 _tmp = osrfNewHash();
201
202                                                 string_tmp = NULL;
203                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
204                                                         osrfHashSet(
205                                                                 _tmp,
206                                                                 strdup( string_tmp ),
207                                                                 "reltype"
208                                                         );
209                                                 }
210                                                 osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
211
212                                                 string_tmp = NULL;
213                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
214                                                         osrfHashSet(
215                                                                 _tmp,
216                                                                 strdup( string_tmp ),
217                                                                 "key"
218                                                         );
219                                                 }
220                                                 osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
221
222                                                 string_tmp = NULL;
223                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
224                                                         osrfHashSet(
225                                                                 _tmp,
226                                                                 strdup( string_tmp ),
227                                                                 "class"
228                                                         );
229                                                 }
230                                                 osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
231
232                                                 osrfStringArray* map = osrfNewStringArray(0);
233
234                                                 string_tmp = NULL;
235                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "map") )) {
236                                                         char* map_list = strdup( string_tmp );
237                                                         osrfLogDebug(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
238
239                                                         if (strlen( map_list ) > 0) {
240                                                                 char* st_tmp;
241                                                                 char* _map_class = strtok_r(map_list, " ", &st_tmp);
242                                                                 osrfStringArrayAdd(map, strdup(_map_class));
243                                                 
244                                                                 while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
245                                                                         osrfStringArrayAdd(map, strdup(_map_class));
246                                                                 }
247                                                         }
248                                                 }
249                                                 osrfHashSet( _tmp, map, "map");
250
251                                                 string_tmp = NULL;
252                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
253                                                         osrfHashSet(
254                                                                 _tmp,
255                                                                 strdup( string_tmp ),
256                                                                 "field"
257                                                         );
258                                                 }
259
260                                                 osrfHashSet(
261                                                         links,
262                                                         _tmp,
263                                                         strdup( string_tmp )
264                                                 );
265
266                                                 osrfLogDebug(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
267
268                                                 _l = _l->next;
269                                         }
270                                 }
271
272                                 if (!strcmp( (char*)_cur->name, "source_definition" )) {
273                                         string_tmp = NULL;
274                                         if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
275                                                 osrfLogDebug(OSRF_LOG_MARK, "Using source definition '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
276                                                 osrfHashSet(
277                                                         usrData,
278                                                         strdup( string_tmp ),
279                                                         "source_definition"
280                                                 );
281                                         }
282
283                                 }
284
285                                 _cur = _cur->next;
286                         }
287                 }
288
289                 kid = kid->next;
290         }
291
292         osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
293
294         return idlHash;
295 }
296
297 osrfHash* oilsIDLFindPath( const char* path, ... ) {
298         if(!path || strlen(path) < 1) return NULL;
299
300         osrfHash* obj = idlHash;
301
302         VA_LIST_TO_STRING(path);
303         char* buf = VA_BUF;
304
305         char* token = NULL;
306         char* t = buf;
307         char* tt;
308
309         token = strtok_r(t, "/", &tt);
310         if(!token) return NULL;
311
312         do {
313                 obj = osrfHashGet(obj, token);
314         } while( (token = strtok_r(NULL, "/", &tt)) && obj);
315
316         return obj;
317 }
318
319 int oilsIDL_classIsFieldmapper ( const char* classname ) {
320         if (!classname) return 0;
321         if(oilsIDLFindPath( "/%s", classname )) return 1;
322         return 0;
323 }
324
325 int oilsIDL_ntop (const char* classname, const char* fieldname) {
326         osrfHash* _pos = NULL;
327
328         if (!oilsIDL_classIsFieldmapper(classname)) return -1;
329         _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
330         if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
331         return -1;
332 }
333
334 char * oilsIDL_pton (const char* classname, int pos) {
335         char* ret = NULL;
336         osrfHash* f = NULL;
337         osrfHash* fields = NULL;
338         osrfHashIterator* itr = NULL;
339
340         if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
341
342         fields = oilsIDLFindPath( "/%s/fields", classname );
343         itr = osrfNewHashIterator( fields );
344
345         while ( (f = osrfHashIteratorNext( itr )) ) {
346                 if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
347                         ret = strdup(itr->current);
348                         break;
349                 }
350         }
351
352         osrfHashIteratorFree( itr );
353
354         return ret;
355 }
356