6 * var aou = new egIDL.aou();
7 * var fullIDL = egIDL.classes;
11 * 1. selector field only appears once per class. We could save
12 * a lot of IDL (network) space storing it only once at the
14 * 2. we don't need to store array_position in /IDL2js since it
15 * can be derived at parse time. Ditto saving space.
17 angular.module('egCoreMod')
19 .factory('egIDL', ['$window', function($window) {
23 // Clones data structures containing fieldmapper objects
24 service.Clone = function(old) {
26 if (old._isfieldmapper) {
27 obj = new service[old.classname]()
29 for( var i in old.a ) {
31 if(thing === null) continue;
33 if( thing._isfieldmapper ) {
34 obj.a[i] = service.Clone(thing);
37 if(angular.isArray(thing)) {
40 for( var j in thing ) {
42 if( thing[j]._isfieldmapper )
43 obj.a[i][j] = service.Clone(thing[j]);
45 obj.a[i][j] = angular.copy(thing[j]);
48 obj.a[i] = angular.copy(thing);
53 if(angular.isArray(old)) {
56 if( old[j]._isfieldmapper )
57 obj[j] = service.Clone(old[j]);
59 obj[j] = angular.copy(old[j]);
61 } else if(angular.isObject(old)) {
64 if( old[j]._isfieldmapper )
65 obj[j] = service.Clone(old[j]);
67 obj[j] = angular.copy(old[j]);
70 obj = angular.copy(old);
76 service.parseIDL = function() {
77 //console.debug('egIDL.parseIDL()');
79 // retain a copy of the full IDL within the service
80 service.classes = $window._preload_fieldmapper_IDL;
82 // keep this reference around (note: not a clone, just a ref)
83 // so that unit tests, which repeatedly instantiate the
85 //$window._preload_fieldmapper_IDL = null;
88 * Creates the class constructor and getter/setter
89 * methods for each IDL class.
91 function mkclass(cls, fields) {
93 service[cls] = function(seed) {
96 this._isfieldmapper = true;
99 /** creates the getter/setter methods for each field */
100 angular.forEach(fields, function(field, idx) {
101 service[cls].prototype[fields[idx].name] = function(n) {
102 if (arguments.length==1) this.a[idx] = n;
107 // global class constructors required for JSON_v1.js
108 $window[cls] = service[cls];
111 for (var cls in service.classes)
112 mkclass(cls, service.classes[cls].fields);
116 * Generate a hash version of an IDL object.
118 * Flatten determines if nested objects should be squashed into
119 * the top-level hash.
121 * If 'flatten' is false, e.g.:
123 * {"call_number" : {"label" : "foo"}}
125 * If 'flatten' is true, e.g.:
127 * e.g. {"call_number.label" : "foo"}
129 service.toHash = function(obj, flatten) {
130 if (!angular.isObject(obj)) return obj; // arrays are objects
132 if (angular.isArray(obj)) { // NOTE: flatten arrays not supported
133 return obj.map(function(item) {return service.toHash(item)});
136 var field_names = obj.classname ?
137 Object.keys(service.classes[obj.classname].field_map) :
145 var val = service.toHash(
146 angular.isFunction(obj[field]) ?
147 obj[field]() : obj[field],
151 if (flatten && angular.isObject(val)) {
152 angular.forEach(val, function(sub_val, key) {
153 var fname = field + '.' + key;
154 hash[fname] = sub_val;
157 } else if (val !== undefined) {
166 // Transforms a flattened hash (see toHash() or egGridFlatDataProvider)
169 // e.g. {"call_number.label" : "foo"} => {"call_number":{"label":"foo"}}
170 service.flatToNestedHash = function(obj) {
172 angular.forEach(obj, function(val, key) {
173 var parts = key.split('.');
176 for (var i = 0; i < parts.length; i++) {
178 if (i == parts.length - 1) {
179 sub_hash[part] = val;
184 sub_hash = sub_hash[part];