5 #include <libxml/globals.h>
6 #include <libxml/xmlerror.h>
7 #include <libxml/parser.h>
8 #include <libxml/tree.h>
9 #include <libxml/debugXML.h>
10 #include <libxml/xmlmemory.h>
12 #define PERSIST_NS "http://open-ils.org/spec/opensrf/IDL/persistence/v1"
13 #define OBJECT_NS "http://open-ils.org/spec/opensrf/IDL/objects/v1"
14 #define BASE_NS "http://opensrf.org/spec/IDL/base/v1"
16 xmlDocPtr idlDoc = NULL; // parse and store the IDL here
18 /* parse and store the IDL here */
21 osrfHash* oilsIDL() { return idlHash; }
22 osrfHash* oilsIDLInit( char* idl_filename ) {
24 if (idlHash) return idlHash;
26 char* string_tmp = NULL;
28 idlHash = osrfNewHash();
29 osrfHash* usrData = NULL;
31 osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
32 idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
35 osrfLogError(OSRF_LOG_MARK, "Could not load or parse the IDL XML file!");
39 osrfLogDebug(OSRF_LOG_MARK, "Initializing the Fieldmapper IDL...");
41 xmlNodePtr docRoot = xmlDocGetRootElement(idlDoc);
42 xmlNodePtr kid = docRoot->children;
44 if (!strcmp( (char*)kid->name, "class" )) {
46 usrData = osrfNewHash();
47 osrfHashSet( usrData, xmlGetProp(kid, BAD_CAST "id"), "classname");
48 osrfHashSet( usrData, xmlGetNsProp(kid, BAD_CAST "fieldmapper", BAD_CAST OBJECT_NS), "fieldmapper");
49 osrfHashSet( usrData, xmlGetNsProp(kid, BAD_CAST "readonly", BAD_CAST PERSIST_NS), "readonly");
51 osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
54 if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "tablename", BAD_CAST PERSIST_NS))) {
55 osrfLogDebug(OSRF_LOG_MARK, "Using table '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
64 if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "virtual", BAD_CAST PERSIST_NS))) {
72 osrfStringArray* controller = osrfNewStringArray(0);
74 if( (string_tmp = (char*)xmlGetProp(kid, BAD_CAST "controller") )) {
75 char* controller_list = strdup( string_tmp );
76 osrfLogDebug(OSRF_LOG_MARK, "Controller list is %s", string_tmp );
78 if (strlen( controller_list ) > 0) {
80 char* _controller_class = strtok_r(controller_list, " ", &st_tmp);
81 osrfStringArrayAdd(controller, strdup(_controller_class));
83 while ((_controller_class = strtok_r(NULL, " ", &st_tmp))) {
84 osrfStringArrayAdd(controller, strdup(_controller_class));
88 osrfHashSet( usrData, controller, "controller");
92 osrfHash* links = osrfNewHash();
93 osrfHash* fields = osrfNewHash();
95 osrfHashSet( usrData, fields, "fields" );
96 osrfHashSet( usrData, links, "links" );
98 xmlNodePtr _cur = kid->children;
102 if (!strcmp( (char*)_cur->name, "fields" )) {
105 if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
108 strdup( string_tmp ),
114 if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
117 strdup( string_tmp ),
122 xmlNodePtr _f = _cur->children;
125 if (strcmp( (char*)_f->name, "field" )) {
130 _tmp = osrfNewHash();
133 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
136 strdup( string_tmp ),
142 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
145 strdup( string_tmp ),
151 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
154 strdup( string_tmp ),
160 if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
163 strdup( string_tmp ),
168 osrfLogDebug(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
179 if (!strcmp( (char*)_cur->name, "links" )) {
180 xmlNodePtr _l = _cur->children;
183 if (strcmp( (char*)_l->name, "link" )) {
188 _tmp = osrfNewHash();
191 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
194 strdup( string_tmp ),
198 osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
201 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
204 strdup( string_tmp ),
208 osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
211 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
214 strdup( string_tmp ),
218 osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
220 osrfStringArray* map = osrfNewStringArray(0);
223 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "map") )) {
224 char* map_list = strdup( string_tmp );
225 osrfLogDebug(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
227 if (strlen( map_list ) > 0) {
229 char* _map_class = strtok_r(map_list, " ", &st_tmp);
230 osrfStringArrayAdd(map, strdup(_map_class));
232 while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
233 osrfStringArrayAdd(map, strdup(_map_class));
237 osrfHashSet( _tmp, map, "map");
240 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
243 strdup( string_tmp ),
254 osrfLogDebug(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
260 if (!strcmp( (char*)_cur->name, "source_definition" )) {
262 if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
263 osrfLogDebug(OSRF_LOG_MARK, "Using source definion '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
266 strdup( string_tmp ),
280 osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
285 osrfHash* oilsIDLFindPath( char* path, ... ) {
286 if(!path || strlen(path) < 1) return NULL;
288 osrfHash* obj = idlHash;
290 VA_LIST_TO_STRING(path);
297 token = strtok_r(t, "/", &tt);
298 if(!token) return NULL;
301 obj = osrfHashGet(obj, token);
302 } while( (token = strtok_r(NULL, "/", &tt)) && obj);
307 int oilsIDL_classIsFieldmapper ( char* classname ) {
308 if (!classname) return 0;
309 if(oilsIDLFindPath( "/%s", classname )) return 1;
313 int oilsIDL_ntop (char* classname, char* fieldname) {
314 osrfHash* _pos = NULL;
316 if (!oilsIDL_classIsFieldmapper(classname)) return -1;
317 _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
318 if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
322 char * oilsIDL_pton (char* classname, int pos) {
325 osrfHash* fields = NULL;
326 osrfHashIterator* itr = NULL;
328 if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
330 fields = oilsIDLFindPath( "/%s/fields", classname );
331 itr = osrfNewHashIterator( fields );
333 while ( (f = osrfHashIteratorNext( itr )) ) {
334 if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
335 ret = strdup(itr->current);
340 osrfHashIteratorFree( itr );