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 osrfLogInfo(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))) {
63 if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "virtual", BAD_CAST PERSIST_NS))) {
71 osrfStringArray* controller = osrfNewStringArray(0);
73 if( (string_tmp = (char*)xmlGetProp(kid, BAD_CAST "controller") )) {
74 char* controller_list = strdup( string_tmp );
75 osrfLogInfo(OSRF_LOG_MARK, "Controller list is %s", string_tmp );
77 if (strlen( controller_list ) > 0) {
79 char* _controller_class = strtok_r(controller_list, " ", &st_tmp);
80 osrfStringArrayAdd(controller, strdup(_controller_class));
82 while ((_controller_class = strtok_r(NULL, " ", &st_tmp))) {
83 osrfStringArrayAdd(controller, strdup(_controller_class));
87 osrfHashSet( usrData, controller, "controller");
91 osrfHash* links = osrfNewHash();
92 osrfHash* fields = osrfNewHash();
94 osrfHashSet( usrData, fields, "fields" );
95 osrfHashSet( usrData, links, "links" );
97 xmlNodePtr _cur = kid->children;
101 if (!strcmp( (char*)_cur->name, "fields" )) {
104 if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
107 strdup( string_tmp ),
113 if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
116 strdup( string_tmp ),
121 xmlNodePtr _f = _cur->children;
124 if (strcmp( (char*)_f->name, "field" )) {
129 _tmp = osrfNewHash();
132 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
135 strdup( string_tmp ),
141 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
144 strdup( string_tmp ),
150 if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
153 strdup( string_tmp ),
159 if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
162 strdup( string_tmp ),
167 osrfLogInfo(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
178 if (!strcmp( (char*)_cur->name, "links" )) {
179 xmlNodePtr _l = _cur->children;
182 if (strcmp( (char*)_l->name, "link" )) {
187 _tmp = osrfNewHash();
190 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
193 strdup( string_tmp ),
197 osrfLogInfo(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
200 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
203 strdup( string_tmp ),
207 osrfLogInfo(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
210 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
213 strdup( string_tmp ),
217 osrfLogInfo(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
219 osrfStringArray* map = osrfNewStringArray(0);
222 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "map") )) {
223 char* map_list = strdup( string_tmp );
224 osrfLogInfo(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
226 if (strlen( map_list ) > 0) {
228 char* _map_class = strtok_r(map_list, " ", &st_tmp);
229 osrfStringArrayAdd(map, strdup(_map_class));
231 while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
232 osrfStringArrayAdd(map, strdup(_map_class));
236 osrfHashSet( _tmp, map, "map");
239 if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
242 strdup( string_tmp ),
253 osrfLogInfo(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
259 if (!strcmp( (char*)_cur->name, "source_definition" )) {
261 if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
264 strdup( string_tmp ),
278 osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
283 osrfHash* oilsIDLFindPath( char* path, ... ) {
284 if(!path || strlen(path) < 1) return NULL;
286 osrfHash* obj = idlHash;
288 VA_LIST_TO_STRING(path);
295 token = strtok_r(t, "/", &tt);
296 if(!token) return NULL;
299 obj = osrfHashGet(obj, token);
300 } while( (token = strtok_r(NULL, "/", &tt)) && obj);
305 int oilsIDL_classIsFieldmapper ( char* classname ) {
306 if (!classname) return 0;
307 if(oilsIDLFindPath( "/%s", classname )) return 1;
311 int oilsIDL_ntop (char* classname, char* fieldname) {
312 osrfHash* _pos = NULL;
314 if (!oilsIDL_classIsFieldmapper(classname)) return -1;
315 _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
316 if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
320 char * oilsIDL_pton (char* classname, int pos) {
323 osrfHash* fields = NULL;
324 osrfHashIterator* itr = NULL;
326 if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
328 fields = oilsIDLFindPath( "/%s/fields", classname );
329 itr = osrfNewHashIterator( fields );
331 while ( (f = osrfHashIteratorNext( itr )) ) {
332 if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
333 ret = strdup(itr->current);
338 osrfHashIteratorFree( itr );