field array position is determined by position in the IDL. dynamically generate...
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 30 Apr 2009 14:42:40 +0000 (14:42 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 30 Apr 2009 14:42:40 +0000 (14:42 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@13022 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/c-apps/oils_idl-core.c
Open-ILS/src/extras/org_tree_js.pl
Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm
Open-ILS/src/python/oils/utils/idl.py
Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js
Open-ILS/web/js/dojo/fieldmapper/IDL.js
Open-ILS/web/opac/common/js/fmgen.js

index b0cce8d..471435c 100644 (file)
@@ -23,6 +23,7 @@ static xmlDocPtr idlDoc = NULL; // parse and store the IDL here
 /* parse and store the IDL here */
 static osrfHash* idlHash;
 
+static void add_std_fld( osrfHash* fields_hash, const char* field_name, unsigned pos );
 osrfHash* oilsIDL(void) { return idlHash; }
 osrfHash* oilsIDLInit( const char* idl_filename ) {
 
@@ -121,14 +122,34 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
 
                                        unsigned int array_pos = 0;
                                        char array_pos_buf[ 7 ];  // For up to 1,000,000 fields per class
-                                       xmlNodePtr _f = _cur->children;
 
+                                       xmlNodePtr _f = _cur->children;
                                        while(_f) {
                                                if (strcmp( (char*)_f->name, "field" )) {
                                                        _f = _f->next;
                                                        continue;
                                                }
 
+                                               // Get the field name.  If it's one of the three standard
+                                               // fields that we always generate, ignore it.
+                                               char* field_name = (char*)xmlGetProp(_f, BAD_CAST "name");
+                                               if( field_name ) {
+                                                       osrfLogDebug(OSRF_LOG_MARK, 
+                                                                       "Found field %s for class %s", field_name, current_class_name );
+                                                       if(    !strcmp( field_name, "isnew" )
+                                                               || !strcmp( field_name, "ischanged" )
+                                                               || !strcmp( field_name, "isdeleted" ) ) {
+                                                               free( field_name );
+                                                               _f = _f->next;
+                                                               continue;
+                                                       }
+                                               } else {
+                                                       osrfLogDebug(OSRF_LOG_MARK,
+                                                                       "Found field with no name for class %s", current_class_name );
+                                                       _f = _f->next;
+                                                       continue;
+                                               }
                                                osrfHash* field_def_hash = osrfNewHash();
 
                                                // Insert array_position
@@ -165,25 +186,20 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
                                                        );
                                                }
 
-                                               if( (prop_str = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
-                                                       osrfHashSet(
-                                                               field_def_hash,
-                                                               prop_str,
-                                                               "name"
-                                                       );
-                                                       osrfLogDebug(OSRF_LOG_MARK, 
-                                                               "Found field %s for class %s", prop_str, current_class_name );
-                                               } else
-                                                       osrfLogDebug(OSRF_LOG_MARK, 
-                                                               "Found field with no name for class %s", current_class_name );
-
+                                               osrfHashSet( field_def_hash, field_name, "name" );
                                                osrfHashSet(
                                                        current_fields_hash,
                                                        field_def_hash,
-                                                       prop_str
+                                                       field_name
                                                );
                                                _f = _f->next;
                                        }
+
+                                       // Create three standard, stereotyped virtual fields for every class
+                                       add_std_fld( current_fields_hash, "isnew",     array_pos++ );
+                                       add_std_fld( current_fields_hash, "ischanged", array_pos++ );
+                                       add_std_fld( current_fields_hash, "isdeleted", array_pos   );
+
                                }
 
                                if (!strcmp( (char*)_cur->name, "links" )) {
@@ -419,6 +435,19 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
        return idlHash;
 }
 
+// Adds a standard virtual field to a fields hash
+static void add_std_fld( osrfHash* fields_hash, const char* field_name, unsigned pos ) {
+       char array_pos_buf[ 7 ];
+       osrfHash* std_fld_hash = osrfNewHash();
+
+       snprintf( array_pos_buf, sizeof( array_pos_buf ), "%u", pos );
+       osrfHashSet( std_fld_hash, strdup( array_pos_buf ), "array_position" );
+       osrfHashSet( std_fld_hash, "true", "virtual" );
+       osrfHashSet( std_fld_hash, strdup( field_name ), "name" );
+       osrfHashSet( fields_hash, std_fld_hash, field_name );
+}
+
+
 osrfHash* oilsIDLFindPath( const char* path, ... ) {
        if(!path || strlen(path) < 1) return NULL;
 
index cac77fc..50f34cb 100644 (file)
@@ -86,7 +86,7 @@ sub build_tree_js {
        for my $t (@$types) {
                my ($u,$v,$d,$i,$n,$o,$p) = (val($t->can_have_users),val($t->can_have_vols),$t->depth,$t->id,val($t->name),val($t->opac_label),$t->parent);
                $p ||= 'null';
-               $pile .= "new aout([null,null,null,null,$u,$v,$d,$i,$n,$o,$p]), ";
+               $pile .= "new aout([null,$u,$v,$d,$i,$n,$o,$p]), ";
        }
        $pile =~ s/, $//; # remove trailing comma
                $pile .= ']; /* OU Types */';
index 308976b..ea782f7 100644 (file)
@@ -78,6 +78,7 @@ sub load_fields {
                        my $attribute_list = $field->attributes();
                        
                        my $name     = get_attribute( $attribute_list, 'name' );
+                       next if( $name eq 'isnew' || $name eq 'ischanged' || $name eq 'isdeleted' );
                        my $virtual  = get_attribute( $attribute_list, 'oils_persist:virtual' );
                        if( ! defined( $virtual ) ) {
                                $virtual = "false";
@@ -100,6 +101,16 @@ sub load_fields {
                        ++$array_position;
                }
        }
+
+       # Load the standard 3 virtual fields ------------------------
+
+       for my $vfield ( qw/isnew ischanged isdeleted/ ) {
+               $$fieldmap{$fm}{fields}{ $vfield } =
+                       { position => $array_position,
+                         virtual => 1
+                       };
+               ++$array_position;
+       }
 }
 
 sub load_links {
@@ -199,12 +210,6 @@ sub import {
                        use base 'Fieldmapper';
                PERL
 
-               my $pos = 0;
-               for my $vfield ( qw/isnew ischanged isdeleted/ ) {
-                       $$fieldmap{$pkg}{fields}{$vfield} = { position => $pos, virtual => 1 };
-                       $pos++;
-               }
-
                if (exists $$fieldmap{$pkg}{proto_fields}) {
                        for my $pfield ( sort keys %{ $$fieldmap{$pkg}{proto_fields} } ) {
                                $$fieldmap{$pkg}{fields}{$pfield} = { position => $pos, virtual => $$fieldmap{$pkg}{proto_fields}{$pfield} };
index 32da172..e834558 100644 (file)
@@ -78,6 +78,10 @@ class IDLParser(object):
     def parse_IDL(self):
         """Parses the IDL file and builds class, field, and link objects"""
 
+        # in case we're calling parse_IDL directly
+        if not IDLParser._global_parser:
+            IDLParser._global_parser = self
+
         doc = xml.dom.minidom.parse(self.idlFile)
         root = doc.documentElement
 
@@ -105,11 +109,11 @@ class IDLParser(object):
                 fields = [f for f in child.childNodes if f.nodeName == 'fields']
                 links = [f for f in child.childNodes if f.nodeName == 'links']
 
-                keys = self.parse_fields(obj, fields[0])
+                fields = self.parse_fields(obj, fields[0])
                 if len(links) > 0:
                     self.parse_links(obj, links[0])
 
-                osrf.net_obj.register_hint(obj.name, keys, 'array')
+                osrf.net_obj.register_hint(obj.name, [f.name for f in fields], 'array')
 
         doc.unlink()
 
@@ -129,22 +133,21 @@ class IDLParser(object):
     def parse_fields(self, idlobj, fields):
         """Takes the fields node and parses the included field elements"""
 
-        keys = []
-
         idlobj.primary = self._get_attr(fields, 'oils_persist:primary', OILS_NS_PERSIST)
         idlobj.sequence =  self._get_attr(fields, 'oils_persist:sequence', OILS_NS_PERSIST)
 
-        # pre-flesh the array of keys to accomodate random index insertions
-        for field in fields.childNodes:
-            if field.nodeType == field.ELEMENT_NODE:
-                keys.append(None)
-        
+        position = 0
         for field in [l for l in fields.childNodes if l.nodeName == 'field']:
 
+            name = self._get_attr(field, 'name')
+
+            if name in ['isnew', 'ischanged', 'isdeleted']: 
+                continue
+
             obj = IDLField(
                 idlobj,
-                name = self._get_attr(field, 'name'),
-                position = int(self._get_attr(field, 'oils_obj:array_position', OILS_NS_OBJ)),
+                name = name,
+                position = position,
                 virtual = self._get_attr(field, 'oils_persist:virtual', OILS_NS_PERSIST),
                 label = self._get_attr(field, 'reporter:label', OILS_NS_REPORTER),
                 rpt_datatype = self._get_attr(field, 'reporter:datatype', OILS_NS_REPORTER),
@@ -152,15 +155,19 @@ class IDLParser(object):
                 primitive = self._get_attr(field, 'oils_persist:primitive', OILS_NS_PERSIST)
             )
 
-            try:
-                keys[obj.position] = obj.name
-            except Exception, e:
-                osrf.log.log_error("parse_fields(): position out of range.  pos=%d : key-size=%d" % (obj.position, len(keys)))
-                raise e
+            idlobj.fields.append(obj)
+            position += 1
 
+        for name in ['isnew', 'ischanged', 'isdeleted']: 
+            obj = IDLField(idlobj, 
+                name = name, 
+                position = position, 
+                virtual = 'true'
+            )
             idlobj.fields.append(obj)
+            position += 1
 
-        return keys
+        return idlobj.fields
 
 
 
index ec9066e..901d87d 100644 (file)
@@ -150,8 +150,6 @@ if(!dojo._hasResource["fieldmapper.Fieldmapper"]){
                     for (var f in fieldmapper.IDL.fmclasses[this.classname].fields) {
                         var field = fieldmapper.IDL.fmclasses[this.classname].fields[f];
                         var p = field.array_position;
-                        if (p <= 2) continue;
-
                                        this._fields.push( field.name );
                                        this[field.name]=new Function('n', 'if(arguments.length==1)this.a['+p+']=n;return this.a['+p+'];');
                     }
@@ -174,7 +172,7 @@ if(!dojo._hasResource["fieldmapper.Fieldmapper"]){
                                this.classname = this.declaredClass;
                                this._fields = fmclasses[this.classname];
                                for( var pos = 0; pos <  this._fields.length; pos++ ) {
-                                       var p = parseInt(pos) + 3;
+                                       var p = parseInt(pos);
                                        var f = this._fields[pos];
                                        this[f]=new Function('n', 'if(arguments.length==1)this.a['+p+']=n;return this.a['+p+'];');
                                }
index 105e246..87af3e3 100644 (file)
@@ -105,10 +105,14 @@ if(!dojo._hasResource["fieldmapper.IDL"]) {
             else links = [];
     
     
+            var position = 0;
             for(var i = 0; i < fields.length; i++) {
                 var field = fields[i];
                 var name = field.getAttribute('name');
 
+                if(name == 'isnew' || name == 'ischanged' || name == 'isdeleted') 
+                    continue;
+
                 var obj = {
                     field : field,
                     name       : name,
@@ -116,7 +120,7 @@ if(!dojo._hasResource["fieldmapper.IDL"]) {
                     datatype : field.getAttributeNS(this.NS_REPORTS,'datatype'),
                     primitive : field.getAttributeNS(this.NS_PERSIST,'primitive'),
                     selector : field.getAttributeNS(this.NS_REPORTS,'selector'),
-                    array_position : parseInt(field.getAttributeNS(this.NS_OBJ,'array_position')),
+                    array_position : position++,
                     type       : 'field',
                     virtual : (fields[i].getAttributeNS(this.NS_PERSIST, 'virtual') == 'true') 
                 };
@@ -124,8 +128,7 @@ if(!dojo._hasResource["fieldmapper.IDL"]) {
                 obj.label = obj.label || obj.name;
                 obj.datatype = obj.datatype || 'text';
 
-                if (obj.array_position > 2)
-                    window.fmclasses[classname].push(obj.name);
+                window.fmclasses[classname].push(obj.name);
     
                 var link = null;
                 for(var l = 0; l < links.length; l++) {
@@ -146,16 +149,19 @@ if(!dojo._hasResource["fieldmapper.IDL"]) {
                 map[obj.name] = obj;
             }
     
-            /*
-            data = data.sort(
-                function(a,b) {
-                    if( a.label > b.label ) return 1;
-                    if( a.label < b.name ) return -1;
-                    return 0;
+            dojo.forEach(['isnew', 'ischanged', 'isdeleted'],
+                function(name) {
+                    var obj = {
+                        name : name,
+                        array_position : position++,
+                        type : 'field',
+                        virtual : true
+                    };
+                    data.push(obj);
+                    map[obj.name] = obj;
                 }
             );
-            */
-    
+
             return { list : data, map : map };
         }
 
index e26d262..bf67355 100644 (file)
@@ -33,9 +33,7 @@ Fieldmapper.prototype.clone = function() {
        }
        return obj;
 }
-Fieldmapper.prototype.isnew = function(n) { if(arguments.length == 1) this.a[0] =n; return this.a[0]; }
-Fieldmapper.prototype.ischanged = function(n) { if(arguments.length == 1) this.a[1] =n; return this.a[1]; }
-Fieldmapper.prototype.isdeleted = function(n) { if(arguments.length == 1) this.a[2] =n; return this.a[2]; }
+
 function FMEX(message) { this.message = message; }
 FMEX.toString = function() { return "FieldmapperException: " + this.message + "\n"; }
 
@@ -51,8 +49,12 @@ for( var cl in fmclasses ) {
 
        string += cl + "._isfieldmapper=true;";
 
+       fmclasses[cl].push('isnew');
+       fmclasses[cl].push('ischanged');
+       fmclasses[cl].push('isdeleted');
+
        for( var pos in fmclasses[cl] ) {
-               var p = parseInt(pos) + 3;
+               var p = parseInt(pos);
                var field = fmclasses[cl][pos];
                string += cl + ".prototype." + field + 
                        "=function(n){if(arguments.length == 1)this.a[" +