1 #include "openils/oils_idl.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>
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"
19 static xmlDocPtr idlDoc = NULL; // parse and store the IDL here
21 /* parse and store the IDL here */
22 static osrfHash* idlHash;
24 osrfHash* oilsIDL(void) { return idlHash; }
25 osrfHash* oilsIDLInit( const char* idl_filename ) {
27 if (idlHash) return idlHash;
29 char* string_tmp = NULL;
31 idlHash = osrfNewHash();
32 osrfHash* usrData = NULL;
34 osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
35 idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
38 osrfLogError(OSRF_LOG_MARK, "Could not load or parse the IDL XML file!");
42 osrfLogDebug(OSRF_LOG_MARK, "Initializing the Fieldmapper IDL...");
44 xmlNodePtr docRoot = xmlDocGetRootElement(idlDoc);
45 xmlNodePtr kid = docRoot->children;
47 if (!strcmp( (char*)kid->name, "class" )) {
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");
54 osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
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") );
67 if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "virtual", BAD_CAST PERSIST_NS))) {
75 osrfStringArray* controller = osrfNewStringArray(0);
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 );
81 if (strlen( controller_list ) > 0) {
83 char* _controller_class = strtok_r(controller_list, " ", &st_tmp);
84 osrfStringArrayAdd(controller, strdup(_controller_class));
86 while ((_controller_class = strtok_r(NULL, " ", &st_tmp))) {
87 osrfStringArrayAdd(controller, strdup(_controller_class));
90 free(controller_list);
92 osrfHashSet( usrData, controller, "controller");
96 osrfHash* links = osrfNewHash();
97 osrfHash* fields = osrfNewHash();
99 osrfHashSet( usrData, fields, "fields" );
100 osrfHashSet( usrData, links, "links" );
102 xmlNodePtr _cur = kid->children;
106 if (!strcmp( (char*)_cur->name, "fields" )) {
109 if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
112 strdup( string_tmp ),
118 if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
121 strdup( string_tmp ),
126 xmlNodePtr _f = _cur->children;
129 if (strcmp( (char*)_f->name, "field" )) {
134 _tmp = osrfNewHash();
137 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
140 strdup( string_tmp ),
146 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "i18n", BAD_CAST PERSIST_NS)) ) {
149 strdup( string_tmp ),
155 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
158 strdup( string_tmp ),
164 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
167 strdup( string_tmp ),
173 if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
176 strdup( string_tmp ),
181 osrfLogDebug(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
192 if (!strcmp( (char*)_cur->name, "links" )) {
193 xmlNodePtr _l = _cur->children;
196 if (strcmp( (char*)_l->name, "link" )) {
201 _tmp = osrfNewHash();
204 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
207 strdup( string_tmp ),
211 osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
214 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
217 strdup( string_tmp ),
221 osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
224 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
227 strdup( string_tmp ),
231 osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
233 osrfStringArray* map = osrfNewStringArray(0);
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 );
240 if (strlen( map_list ) > 0) {
242 char* _map_class = strtok_r(map_list, " ", &st_tmp);
243 osrfStringArrayAdd(map, strdup(_map_class));
245 while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
246 osrfStringArrayAdd(map, strdup(_map_class));
251 osrfHashSet( _tmp, map, "map");
254 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
257 strdup( string_tmp ),
268 osrfLogDebug(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
274 if (!strcmp( (char*)_cur->name, "source_definition" )) {
276 if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
277 osrfLogDebug(OSRF_LOG_MARK, "Using source definition '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
280 strdup( string_tmp ),
294 osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
299 osrfHash* oilsIDLFindPath( const char* path, ... ) {
300 if(!path || strlen(path) < 1) return NULL;
302 osrfHash* obj = idlHash;
304 VA_LIST_TO_STRING(path);
311 token = strtok_r(t, "/", &tt);
312 if(!token) return NULL;
315 obj = osrfHashGet(obj, token);
316 } while( (token = strtok_r(NULL, "/", &tt)) && obj);
321 int oilsIDL_classIsFieldmapper ( const char* classname ) {
322 if (!classname) return 0;
323 if(oilsIDLFindPath( "/%s", classname )) return 1;
327 int oilsIDL_ntop (const char* classname, const char* fieldname) {
328 osrfHash* _pos = NULL;
330 if (!oilsIDL_classIsFieldmapper(classname)) return -1;
331 _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
332 if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
336 char * oilsIDL_pton (const char* classname, int pos) {
339 osrfHash* fields = NULL;
340 osrfHashIterator* itr = NULL;
342 if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
344 fields = oilsIDLFindPath( "/%s/fields", classname );
345 itr = osrfNewHashIterator( fields );
347 while ( (f = osrfHashIteratorNext( itr )) ) {
348 if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
349 ret = strdup(osrfHashIteratorKey(itr));
354 osrfHashIteratorFree( itr );