]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/oils_idl-core.c
Typo fix (and add ye olde vim modeline while we're here).
[Evergreen.git] / Open-ILS / src / c-apps / oils_idl-core.c
1 #include "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 xmlDocPtr idlDoc = NULL; // parse and store the IDL here
20
21 /* parse and store the IDL here */
22 osrfHash* idlHash;
23
24 osrfHash* oilsIDL() { return idlHash; }
25 osrfHash* oilsIDLInit( 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 "virtual", BAD_CAST PERSIST_NS)) ) {
146                                                         osrfHashSet(
147                                                                 _tmp,
148                                                                 strdup( string_tmp ),
149                                                                 "virtual"
150                                                         );
151                                                 }
152
153                                                 string_tmp = NULL;
154                                                 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
155                                                         osrfHashSet(
156                                                                 _tmp,
157                                                                 strdup( string_tmp ),
158                                                                 "primitive"
159                                                         );
160                                                 }
161
162                                                 string_tmp = NULL;
163                                                 if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
164                                                         osrfHashSet(
165                                                                 _tmp,
166                                                                 strdup( string_tmp ),
167                                                                 "name"
168                                                         );
169                                                 }
170
171                                                 osrfLogDebug(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
172
173                                                 osrfHashSet(
174                                                         fields,
175                                                         _tmp,
176                                                         strdup( string_tmp )
177                                                 );
178                                                 _f = _f->next;
179                                         }
180                                 }
181
182                                 if (!strcmp( (char*)_cur->name, "links" )) {
183                                         xmlNodePtr _l = _cur->children;
184
185                                         while(_l) {
186                                                 if (strcmp( (char*)_l->name, "link" )) {
187                                                         _l = _l->next;
188                                                         continue;
189                                                 }
190
191                                                 _tmp = osrfNewHash();
192
193                                                 string_tmp = NULL;
194                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
195                                                         osrfHashSet(
196                                                                 _tmp,
197                                                                 strdup( string_tmp ),
198                                                                 "reltype"
199                                                         );
200                                                 }
201                                                 osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
202
203                                                 string_tmp = NULL;
204                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
205                                                         osrfHashSet(
206                                                                 _tmp,
207                                                                 strdup( string_tmp ),
208                                                                 "key"
209                                                         );
210                                                 }
211                                                 osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
212
213                                                 string_tmp = NULL;
214                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
215                                                         osrfHashSet(
216                                                                 _tmp,
217                                                                 strdup( string_tmp ),
218                                                                 "class"
219                                                         );
220                                                 }
221                                                 osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
222
223                                                 osrfStringArray* map = osrfNewStringArray(0);
224
225                                                 string_tmp = NULL;
226                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "map") )) {
227                                                         char* map_list = strdup( string_tmp );
228                                                         osrfLogDebug(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
229
230                                                         if (strlen( map_list ) > 0) {
231                                                                 char* st_tmp;
232                                                                 char* _map_class = strtok_r(map_list, " ", &st_tmp);
233                                                                 osrfStringArrayAdd(map, strdup(_map_class));
234                                                 
235                                                                 while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
236                                                                         osrfStringArrayAdd(map, strdup(_map_class));
237                                                                 }
238                                                         }
239                                                 }
240                                                 osrfHashSet( _tmp, map, "map");
241
242                                                 string_tmp = NULL;
243                                                 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
244                                                         osrfHashSet(
245                                                                 _tmp,
246                                                                 strdup( string_tmp ),
247                                                                 "field"
248                                                         );
249                                                 }
250
251                                                 osrfHashSet(
252                                                         links,
253                                                         _tmp,
254                                                         strdup( string_tmp )
255                                                 );
256
257                                                 osrfLogDebug(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
258
259                                                 _l = _l->next;
260                                         }
261                                 }
262
263                                 if (!strcmp( (char*)_cur->name, "source_definition" )) {
264                                         string_tmp = NULL;
265                                         if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
266                                                 osrfLogDebug(OSRF_LOG_MARK, "Using source definition '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
267                                                 osrfHashSet(
268                                                         usrData,
269                                                         strdup( string_tmp ),
270                                                         "source_definition"
271                                                 );
272                                         }
273
274                                 }
275
276                                 _cur = _cur->next;
277                         }
278                 }
279
280                 kid = kid->next;
281         }
282
283         osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
284
285         return idlHash;
286 }
287
288 osrfHash* oilsIDLFindPath( char* path, ... ) {
289         if(!path || strlen(path) < 1) return NULL;
290
291         osrfHash* obj = idlHash;
292
293         VA_LIST_TO_STRING(path);
294         char* buf = VA_BUF;
295
296         char* token = NULL;
297         char* t = buf;
298         char* tt;
299
300         token = strtok_r(t, "/", &tt);
301         if(!token) return NULL;
302
303         do {
304                 obj = osrfHashGet(obj, token);
305         } while( (token = strtok_r(NULL, "/", &tt)) && obj);
306
307         return obj;
308 }
309
310 int oilsIDL_classIsFieldmapper ( char* classname ) {
311         if (!classname) return 0;
312         if(oilsIDLFindPath( "/%s", classname )) return 1;
313         return 0;
314 }
315
316 int oilsIDL_ntop (char* classname, char* fieldname) {
317         osrfHash* _pos = NULL;
318
319         if (!oilsIDL_classIsFieldmapper(classname)) return -1;
320         _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
321         if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
322         return -1;
323 }
324
325 char * oilsIDL_pton (char* classname, int pos) {
326         char* ret = NULL;
327         osrfHash* f = NULL;
328         osrfHash* fields = NULL;
329         osrfHashIterator* itr = NULL;
330
331         if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
332
333         fields = oilsIDLFindPath( "/%s/fields", classname );
334         itr = osrfNewHashIterator( fields );
335
336         while ( (f = osrfHashIteratorNext( itr )) ) {
337                 if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
338                         ret = strdup(itr->current);
339                         break;
340                 }
341         }
342
343         osrfHashIteratorFree( itr );
344
345         return ret;
346 }
347