IDL parsing lib
authormiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 9 Jul 2006 20:13:47 +0000 (20:13 +0000)
committermiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 9 Jul 2006 20:13:47 +0000 (20:13 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@4946 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/c-apps/Makefile
Open-ILS/src/c-apps/oils_cstore.c
Open-ILS/src/c-apps/oils_idl-core.c [new file with mode: 0644]
Open-ILS/src/c-apps/oils_idl.h [new file with mode: 0644]

index 1c1fcf0..fb1b75b 100644 (file)
@@ -9,18 +9,27 @@ oils_event.o: oils_event.c oils_event.h
 oils_utils.o:  oils_utils.c oils_utils.h
 oils_auth.o:   oils_auth.c
 oils_fetch.o:  oils_fetch.c oils_utils.h 
-oils_cstore.o: oils_cstore.c oils_utils.h 
+oils_cstore.o: oils_cstore.c oils_utils.h
 
-oils_cstore.so:        oils_cstore.o liboils_utils.so
+oils_cstore.so:        oils_cstore.o liboils_utils.so liboils_idl.so
        @echo $@
        $(CC) -shared -W1 -L/usr/local/lib/dbd \
-               $(LDLIBS) $(LDFLAGS) -loils_utils -ldbi -ldbdpgsql oils_cstore.o -o $(TMPDIR)/$@
+               $(LDLIBS) $(LDFLAGS) -loils_idl -loils_utils -ldbi -ldbdpgsql oils_cstore.o -o $(TMPDIR)/$@
 
 oils_fetch.so: oils_fetch.o liboils_utils.so
        @echo $@
        $(CC) -shared -W1 -L/usr/local/lib/dbd \
                $(LDLIBS) $(LDFLAGS) -ldbi -ldbdpgsql -loils_utils oils_fetch.o -o $(TMPDIR)/$@
 
+oils_idl-core.o:       oils_idl-core.c oils_idl.h
+
+liboils_idl.so:        oils_idl-core.o
+       @echo $@
+       $(CC) -shared -W1 $(LDLIBS) $(LDFLAGS) oils_idl-core.o -o $@
+       cp $@ $(TMPDIR)/
+       mkdir -p $(TMPDIR)/openils/
+       cp oils_idl.h $(TMPDIR)/openils/
+
 oils_auth.so:  oils_auth.o liboils_utils.so
        @echo $@
        $(CC) -shared -W1 $(LDLIBS) $(LDFLAGS) -loils_utils oils_auth.o -o $(TMPDIR)/$@
@@ -42,8 +51,10 @@ install:
        #cp $(TMPDIR)/oils_fetch.so $(LIBDIR)/
        cp $(TMPDIR)/oils_cstore.so $(LIBDIR)/
        cp $(TMPDIR)/liboils_utils.so $(LIBDIR)/
+       cp $(TMPDIR)/liboils_idl.so $(LIBDIR)/
        mkdir -p $(INCDIR)/
        cp oils_utils.h $(INCDIR)
+       cp oils_idl.h $(INCDIR)
        cp oils_event.h $(INCDIR)
        cp oils_constants.h $(INCDIR)
 
index 605057b..7efae15 100644 (file)
@@ -6,17 +6,12 @@
 #include "oils_utils.h"
 #include "oils_constants.h"
 #include "oils_event.h"
+#include "oils_idl.h"
 #include <dbi/dbi.h>
 
 #include <time.h>
 #include <stdlib.h>
 #include <string.h>
-#include <libxml/globals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/debugXML.h>
-#include <libxml/xmlmemory.h>
 
 #define OILS_AUTH_CACHE_PRFX "oils_cstore_"
 #define MODULENAME "open-ils.cstore"
@@ -59,12 +54,11 @@ void sessionDataFree( char*, void* );
 dbi_conn writehandle; /* our MASTER db connection */
 dbi_conn dbhandle; /* our CURRENT db connection */
 osrfHash readHandles;
-xmlDocPtr idlDoc = NULL; // parse and store the IDL here
 jsonObject* jsonNULL = NULL; // 
 
 
 /* parse and store the IDL here */
-osrfHash* idlHash;
+osrfHash* idl;
 
 int osrfAppInitialize() {
 
@@ -78,9 +72,6 @@ int osrfAppInitialize() {
        osrfAppRegisterMethod( MODULENAME, "open-ils.cstore.savepoint.rollback", "rollbackSavepoint", "", 1, 0 );
 
 
-       idlHash = osrfNewHash();
-       osrfHash* usrData = NULL;
-
        osrfLogInfo(OSRF_LOG_MARK, "Initializing the CStore Server...");
        osrfLogInfo(OSRF_LOG_MARK, "Finding XML file...");
 
@@ -88,17 +79,14 @@ int osrfAppInitialize() {
        osrfLogInfo(OSRF_LOG_MARK, "Found file:");
        osrfLogInfo(OSRF_LOG_MARK, idl_filename);
 
-       osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
-       idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
-       
-       if (!idlDoc) {
-               osrfLogError(OSRF_LOG_MARK, "Could not load or parse the IDL XML file!");
+       idl = oilsIDLInit( idl_filename );
+
+       if (!idl) {
+               osrfLogError(OSRF_LOG_MARK, "Problem loading the IDL.  Seacrest out!");
                exit(1);
        }
 
-       osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
-
-       osrfStringArray* global_methods = osrfNewStringArray(1);
+       osrfStringArray* global_methods = osrfNewStringArray(6);
 
        osrfStringArrayAdd( global_methods, "create" );
        osrfStringArrayAdd( global_methods, "retrieve" );
@@ -107,247 +95,73 @@ int osrfAppInitialize() {
        osrfStringArrayAdd( global_methods, "search" );
        osrfStringArrayAdd( global_methods, "id_list" );
 
-       xmlNodePtr docRoot = xmlDocGetRootElement(idlDoc);
-       xmlNodePtr kid = docRoot->children;
-       while (kid) {
-               if (!strcmp( (char*)kid->name, "class" )) {
-
-                       char* virt_class = xmlGetNsProp(kid, "virtual", PERSIST_NS);
-                       if (virt_class && !strcmp(virt_class, "true")) {
-                               free(virt_class);
-                               kid = kid->next;
-                               continue;
-                       }
-                       free(virt_class);
-                       
-                       usrData = osrfNewHash();
-                       osrfHashSet( usrData, xmlGetProp(kid, "id"), "classname");
-                       osrfHashSet( usrData, xmlGetNsProp(kid, "tablename", PERSIST_NS), "tablename");
-                       osrfHashSet( usrData, xmlGetNsProp(kid, "fieldmapper", OBJECT_NS), "fieldmapper");
-
-                       osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
-
-                       osrfLogInfo(OSRF_LOG_MARK, "Generating class methods for %s", osrfHashGet(usrData, "fieldmapper") );
-
-                       osrfHash* _tmp;
-                       osrfHash* links = osrfNewHash();
-                       osrfHash* fields = osrfNewHash();
-
-                       osrfHashSet( usrData, fields, "fields" );
-                       osrfHashSet( usrData, links, "links" );
-
-                       xmlNodePtr _cur = kid->children;
-
-                       while (_cur) {
-                               char* string_tmp = NULL;
-
-                               if (!strcmp( (char*)_cur->name, "fields" )) {
-
-                                       if( (string_tmp = (char*)xmlGetNsProp(_cur, "primary", PERSIST_NS)) ) {
-                                               osrfHashSet(
-                                                       usrData,
-                                                       strdup( string_tmp ),
-                                                       "primarykey"
-                                               );
-                                       }
-                                       string_tmp = NULL;
-
-                                       if( (string_tmp = (char*)xmlGetNsProp(_cur, "sequence", PERSIST_NS)) ) {
-                                               osrfHashSet(
-                                                       usrData,
-                                                       strdup( string_tmp ),
-                                                       "sequence"
-                                               );
-                                       }
-                                       string_tmp = NULL;
-
-                                       xmlNodePtr _f = _cur->children;
-
-                                       while(_f) {
-                                               if (strcmp( (char*)_f->name, "field" )) {
-                                                       _f = _f->next;
-                                                       continue;
-                                               }
-
-                                               _tmp = osrfNewHash();
-
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, "array_position", OBJECT_NS)) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "array_position"
-                                                       );
-                                               }
-                                               string_tmp = NULL;
-
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, "virtual", PERSIST_NS)) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "virtual"
-                                                       );
-                                               }
-                                               string_tmp = NULL;
-
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, "primitive", PERSIST_NS)) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "primitive"
-                                                       );
-                                               }
-                                               string_tmp = NULL;
-
-                                               if( (string_tmp = (char*)xmlGetProp(_f, "name")) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "name"
-                                                       );
-                                               }
-
-                                               osrfLogInfo(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
-
-                                               osrfHashSet(
-                                                       fields,
-                                                       _tmp,
-                                                       strdup( string_tmp )
-                                               );
-                                               _f = _f->next;
-                                       }
-                               }
-
-                               if (!strcmp( (char*)_cur->name, "links" )) {
-                                       xmlNodePtr _l = _cur->children;
-
-                                       while(_l) {
-                                               if (strcmp( (char*)_l->name, "link" )) {
-                                                       _l = _l->next;
-                                                       continue;
-                                               }
+       int c_index = 0; 
+       char* classname;
+       osrfStringArray* classes = osrfHashKeys( idl );
+       osrfLogDebug(OSRF_LOG_MARK, "%d classes loaded", classes->size );
+       osrfLogDebug(OSRF_LOG_MARK, "At least %d methods will be generated", classes->size * global_methods->size);
+       
+       while ( (classname = osrfStringArrayGetString(classes, c_index++)) ) {
+               osrfLogInfo(OSRF_LOG_MARK, "Generating class methods for %s", classname);
+               
+               osrfHash* idlClass = osrfHashGet(idl, classname);
 
-                                               _tmp = osrfNewHash();
+               char* virt = osrfHashGet(idlClass, "virtual");
+               if (virt && !strcmp( virt, "true")) {
+                       osrfLogDebug(OSRF_LOG_MARK, "Class %s is virtual, skipping", classname );
+                       continue;
+               }
 
-                                               if( (string_tmp = (char*)xmlGetProp(_l, "reltype")) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "reltype"
-                                                       );
-                                               }
-                                               osrfLogInfo(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
-                                               string_tmp = NULL;
-
-                                               if( (string_tmp = (char*)xmlGetProp(_l, "key")) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "key"
-                                                       );
-                                               }
-                                               osrfLogInfo(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
-                                               string_tmp = NULL;
-
-                                               if( (string_tmp = (char*)xmlGetProp(_l, "class")) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "class"
-                                                       );
-                                               }
-                                               osrfLogInfo(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
-                                               string_tmp = NULL;
-
-                                               osrfStringArray* map = osrfNewStringArray(0);
-
-                                               if( (string_tmp = (char*)xmlGetProp(_l, "map") )) {
-                                                       char* map_list = strdup( string_tmp );
-                                                       osrfLogInfo(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
-
-                                                       if (strlen( map_list ) > 0) {
-                                                               char* st_tmp;
-                                                               char* _map_class = strtok_r(map_list, " ", &st_tmp);
-                                                               osrfStringArrayAdd(map, strdup(_map_class));
-                                               
-                                                               while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
-                                                                       osrfStringArrayAdd(map, strdup(_map_class));
-                                                               }
-                                                       }
-                                               }
-                                               osrfHashSet( _tmp, map, "map");
+               osrfLogDebug(OSRF_LOG_MARK, "HERE");
+               
+               int i = 0; 
+               char* method_type;
+               char* st_tmp;
+               char* _fm;
+               char* part;
+               osrfHash* method_meta;
+               while ( (method_type = osrfStringArrayGetString(global_methods, i++)) ) {
+                       osrfLogDebug(OSRF_LOG_MARK, "Using files to build %s class methods for %s", method_type, classname);
 
-                                               if( (string_tmp = (char*)xmlGetProp(_l, "field")) ) {
-                                                       osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
-                                                               "field"
-                                                       );
-                                               }
+                       if (!osrfHashGet(idlClass, "fieldmapper")) continue;
 
-                                               osrfHashSet(
-                                                       links,
-                                                       _tmp,
-                                                       strdup( string_tmp )
-                                               );
+                       method_meta = osrfNewHash();
+                       osrfHashSet(method_meta, idlClass, "class");
 
-                                               osrfLogInfo(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+                       _fm = strdup( (char*)osrfHashGet(idlClass, "fieldmapper") );
+                       part = strtok_r(_fm, ":", &st_tmp);
 
-                                               _l = _l->next;
-                                       }
-                               }
+                       growing_buffer* method_name =  buffer_init(64);
+                       buffer_fadd(method_name, "%s.direct.%s", MODULENAME, part);
 
-                               _cur = _cur->next;
+                       while ((part = strtok_r(NULL, ":", &st_tmp))) {
+                               buffer_fadd(method_name, ".%s", part);
                        }
+                       buffer_fadd(method_name, ".%s", method_type);
 
-                       int i = 0; 
-                       char* method_type;
-                       char* st_tmp;
-                       char* _fm;
-                       char* part;
-                       osrfHash* method_meta;
-                       while ( (method_type = osrfStringArrayGetString(global_methods, i++)) ) {
 
-                               if (!osrfHashGet(usrData, "fieldmapper")) continue;
+                       char* method = buffer_data(method_name);
+                       buffer_free(method_name);
+                       free(_fm);
 
-                               method_meta = osrfNewHash();
-                               osrfHashSet(method_meta, usrData, "class");
+                       osrfHashSet( method_meta, method, "methodname" );
+                       osrfHashSet( method_meta, method_type, "methodtype" );
 
-                               _fm = strdup( (char*)osrfHashGet(usrData, "fieldmapper") );
-                               part = strtok_r(_fm, ":", &st_tmp);
-
-                               growing_buffer* method_name =  buffer_init(64);
-                               buffer_fadd(method_name, "%s.direct.%s", MODULENAME, part);
-
-                               while ((part = strtok_r(NULL, ":", &st_tmp))) {
-                                       buffer_fadd(method_name, ".%s", part);
-                               }
-                               buffer_fadd(method_name, ".%s", method_type);
-
-
-                               char* method = buffer_data(method_name);
-                               buffer_free(method_name);
-                               free(_fm);
-
-                               osrfHashSet( method_meta, method, "methodname" );
-                               osrfHashSet( method_meta, method_type, "methodtype" );
-
-                               int flags = 0;
-                               if (!(strcmp( method_type, "search" )) || !(strcmp( method_type, "id_list" ))) {
-                                       flags = flags | OSRF_METHOD_STREAMING;
-                               }
-
-                               osrfAppRegisterExtendedMethod(
-                                       MODULENAME,
-                                       method,
-                                       "dispatchCRUDMethod",
-                                       "",
-                                       1,
-                                       flags,
-                                       (void*)method_meta
-                               );
+                       int flags = 0;
+                       if (!(strcmp( method_type, "search" )) || !(strcmp( method_type, "id_list" ))) {
+                               flags = flags | OSRF_METHOD_STREAMING;
                        }
+
+                       osrfAppRegisterExtendedMethod(
+                               MODULENAME,
+                               method,
+                               "dispatchCRUDMethod",
+                               "",
+                               1,
+                               flags,
+                               (void*)method_meta
+                       );
                }
-               kid = kid->next;
        }
 
        return 0;
@@ -406,12 +220,19 @@ int osrfAppChildInit() {
        unsigned short type;
        int i = 0; 
        char* classname;
-       osrfStringArray* classes = osrfHashKeys( idlHash );
+       osrfStringArray* classes = osrfHashKeys( idl );
        
        while ( (classname = osrfStringArrayGetString(classes, i++)) ) {
-               osrfHash* class = osrfHashGet( idlHash, classname );
+               osrfHash* class = osrfHashGet( idl, classname );
                osrfHash* fields = osrfHashGet( class, "fields" );
-               
+
+               char* virt = osrfHashGet(class, "virtual");
+               if (virt && !strcmp( virt, "true")) {
+                       osrfLogDebug(OSRF_LOG_MARK, "Class %s is virtual, skipping", classname );
+                       continue;
+               }
+
+       
                growing_buffer* sql_buf = buffer_init(32);
                buffer_fadd( sql_buf, "SELECT * FROM %s WHERE 1=0;", osrfHashGet(class, "tablename") );
 
@@ -1347,7 +1168,7 @@ jsonObject* doSearch(osrfMethodContext* ctx, osrfHash* meta, jsonObject* params,
                jsonObjectIterator* class_itr = jsonNewObjectIterator( _tmp );
                while ( (snode = jsonObjectIteratorNext( class_itr )) ) {
 
-                       osrfHash* idlClass = osrfHashGet( idlHash, snode->key );
+                       osrfHash* idlClass = osrfHashGet( idl, snode->key );
                        if (!idlClass) continue;
                        char* cname = osrfHashGet(idlClass, "classname");
 
@@ -1522,7 +1343,7 @@ jsonObject* doSearch(osrfMethodContext* ctx, osrfHash* meta, jsonObject* params,
 
                                                osrfHash* value_field = field;
 
-                                               osrfHash* kid_idl = osrfHashGet(idlHash, osrfHashGet(kid_link, "class"));
+                                               osrfHash* kid_idl = osrfHashGet(idl, osrfHashGet(kid_link, "class"));
                                                if (!kid_idl) continue;
 
                                                if (!(strcmp( osrfHashGet(kid_link, "reltype"), "has_many" ))) { // has_many
@@ -1633,7 +1454,7 @@ jsonObject* doSearch(osrfMethodContext* ctx, osrfHash* meta, jsonObject* params,
                                                                                                        osrfHashGet(
                                                                                                                osrfHashGet(
                                                                                                                        osrfHashGet(
-                                                                                                                               idlHash,
+                                                                                                                               idl,
                                                                                                                                osrfHashGet(kid_link, "class")
                                                                                                                        ),
                                                                                                                        "fields"
diff --git a/Open-ILS/src/c-apps/oils_idl-core.c b/Open-ILS/src/c-apps/oils_idl-core.c
new file mode 100644 (file)
index 0000000..6799696
--- /dev/null
@@ -0,0 +1,272 @@
+#include "oils_idl.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmemory.h>
+
+#define PERSIST_NS "http://open-ils.org/spec/opensrf/IDL/persistance/v1"
+#define OBJECT_NS "http://open-ils.org/spec/opensrf/IDL/objects/v1"
+#define BASE_NS "http://opensrf.org/spec/IDL/base/v1"
+
+xmlDocPtr idlDoc = NULL; // parse and store the IDL here
+
+/* parse and store the IDL here */
+osrfHash* idlHash;
+
+osrfHash* oilsIDL() { return idlHash; }
+osrfHash* oilsIDLInit( char* idl_filename ) {
+
+       if (idlHash) return idlHash;
+
+       char* string_tmp = NULL;
+
+       idlHash = osrfNewHash();
+       osrfHash* usrData = NULL;
+
+       osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
+       idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
+       
+       if (!idlDoc) {
+               osrfLogError(OSRF_LOG_MARK, "Could not load or parse the IDL XML file!");
+               return NULL;
+       }
+
+       osrfLogInfo(OSRF_LOG_MARK, "Initializing the Fieldmapper IDL...");
+
+       xmlNodePtr docRoot = xmlDocGetRootElement(idlDoc);
+       xmlNodePtr kid = docRoot->children;
+       while (kid) {
+               if (!strcmp( (char*)kid->name, "class" )) {
+
+                       usrData = osrfNewHash();
+                       osrfHashSet( usrData, xmlGetProp(kid, "id"), "classname");
+                       osrfHashSet( usrData, xmlGetNsProp(kid, "fieldmapper", OBJECT_NS), "fieldmapper");
+
+                       osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
+
+                       string_tmp = NULL;
+                       if ((string_tmp = (char*)xmlGetNsProp(kid, "tablename", PERSIST_NS))) {
+                               osrfHashSet(
+                                       usrData,
+                                       strdup( string_tmp ),
+                                       "tablename"
+                               );
+                       }
+
+                       string_tmp = NULL;
+                       if ((string_tmp = (char*)xmlGetNsProp(kid, "virtual", PERSIST_NS))) {
+                               osrfHashSet(
+                                       usrData,
+                                       strdup( string_tmp ),
+                                       "virtual"
+                               );
+                       }
+
+                       osrfHash* _tmp;
+                       osrfHash* links = osrfNewHash();
+                       osrfHash* fields = osrfNewHash();
+
+                       osrfHashSet( usrData, fields, "fields" );
+                       osrfHashSet( usrData, links, "links" );
+
+                       xmlNodePtr _cur = kid->children;
+
+                       while (_cur) {
+
+                               if (!strcmp( (char*)_cur->name, "fields" )) {
+
+                                       string_tmp = NULL;
+                                       if( (string_tmp = (char*)xmlGetNsProp(_cur, "primary", PERSIST_NS)) ) {
+                                               osrfHashSet(
+                                                       usrData,
+                                                       strdup( string_tmp ),
+                                                       "primarykey"
+                                               );
+                                       }
+
+                                       string_tmp = NULL;
+                                       if( (string_tmp = (char*)xmlGetNsProp(_cur, "sequence", PERSIST_NS)) ) {
+                                               osrfHashSet(
+                                                       usrData,
+                                                       strdup( string_tmp ),
+                                                       "sequence"
+                                               );
+                                       }
+
+                                       xmlNodePtr _f = _cur->children;
+
+                                       while(_f) {
+                                               if (strcmp( (char*)_f->name, "field" )) {
+                                                       _f = _f->next;
+                                                       continue;
+                                               }
+
+                                               _tmp = osrfNewHash();
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetNsProp(_f, "array_position", OBJECT_NS)) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "array_position"
+                                                       );
+                                               }
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetNsProp(_f, "virtual", PERSIST_NS)) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "virtual"
+                                                       );
+                                               }
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetNsProp(_f, "primitive", PERSIST_NS)) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "primitive"
+                                                       );
+                                               }
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetProp(_f, "name")) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "name"
+                                                       );
+                                               }
+
+                                               osrfLogInfo(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+
+                                               osrfHashSet(
+                                                       fields,
+                                                       _tmp,
+                                                       strdup( string_tmp )
+                                               );
+                                               _f = _f->next;
+                                       }
+                               }
+
+                               if (!strcmp( (char*)_cur->name, "links" )) {
+                                       xmlNodePtr _l = _cur->children;
+
+                                       while(_l) {
+                                               if (strcmp( (char*)_l->name, "link" )) {
+                                                       _l = _l->next;
+                                                       continue;
+                                               }
+
+                                               _tmp = osrfNewHash();
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetProp(_l, "reltype")) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "reltype"
+                                                       );
+                                               }
+                                               osrfLogInfo(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetProp(_l, "key")) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "key"
+                                                       );
+                                               }
+                                               osrfLogInfo(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetProp(_l, "class")) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "class"
+                                                       );
+                                               }
+                                               osrfLogInfo(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
+
+                                               osrfStringArray* map = osrfNewStringArray(0);
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetProp(_l, "map") )) {
+                                                       char* map_list = strdup( string_tmp );
+                                                       osrfLogInfo(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
+
+                                                       if (strlen( map_list ) > 0) {
+                                                               char* st_tmp;
+                                                               char* _map_class = strtok_r(map_list, " ", &st_tmp);
+                                                               osrfStringArrayAdd(map, strdup(_map_class));
+                                               
+                                                               while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
+                                                                       osrfStringArrayAdd(map, strdup(_map_class));
+                                                               }
+                                                       }
+                                               }
+                                               osrfHashSet( _tmp, map, "map");
+
+                                               string_tmp = NULL;
+                                               if( (string_tmp = (char*)xmlGetProp(_l, "field")) ) {
+                                                       osrfHashSet(
+                                                               _tmp,
+                                                               strdup( string_tmp ),
+                                                               "field"
+                                                       );
+                                               }
+
+                                               osrfHashSet(
+                                                       links,
+                                                       _tmp,
+                                                       strdup( string_tmp )
+                                               );
+
+                                               osrfLogInfo(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+
+                                               _l = _l->next;
+                                       }
+                               }
+
+                               _cur = _cur->next;
+                       }
+               }
+
+               kid = kid->next;
+       }
+
+       osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
+
+       return idlHash;
+}
+
+osrfHash* oilsIDLFindPath( char* path, ... ) {
+       if(!path || strlen(path) < 1) return NULL;
+
+       osrfHash* obj = idlHash;
+
+       VA_LIST_TO_STRING(path);
+       char* buf = VA_BUF;
+
+       char* token = NULL;
+       char* t = buf;
+       char* tt;
+
+       token = strtok_r(t, "/", &tt);
+       if(!token) return NULL;
+
+       do {
+               obj = osrfHashGet(obj, token);
+       } while( (token = strtok_r(NULL, "/", &tt)) && obj);
+
+       return obj;
+}
+
diff --git a/Open-ILS/src/c-apps/oils_idl.h b/Open-ILS/src/c-apps/oils_idl.h
new file mode 100644 (file)
index 0000000..a0ddff1
--- /dev/null
@@ -0,0 +1,43 @@
+#include "opensrf/log.h"
+#include "opensrf/utils.h"
+#include "opensrf/osrf_hash.h"
+
+osrfHash* oilsIDLInit( char* );
+osrfHash* oilsIDL();
+osrfHash* oilsIDLFindPath( char*, ... );
+
+/* The oilsIDL hash looks like this:
+
+{ aws : {
+        classname       : "aws",
+        fieldmapper     : "actor::workstation",
+        tablename       : "actor.workstation",          optional
+        sequence        : "actor.workstation_id_seq",   optional
+        primarykey      : "id",
+        virtual         : "true",                       optional, "true" | "false"
+        fields          : {
+                isnew : {
+                        name            : "isnew",
+                        array_position  : "0",
+                        virtual         : "true",       "true" | "false"
+                        primitive       : "number"      optional, JSON primitive (number, string, array,
+                                                        object, bool)
+                },
+                ...
+        },
+        links           : {
+                record : {
+                        field           : "owning_lib", field above that links to another class
+                        rel_type        : "has_a",      link type, "has_a" | "has_many" | "might_have"
+                        class           : "aou",        the foreign class that is linked
+                        key             : "id",         the foreign class's key that creates the link to "field"
+                        map             : []            osrfStringArray used by cstore in "has_many" rel_types to
+                                                        point through a linking class
+                },
+                ...
+        },
+        ...
+}
+
+*/
+