]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/services/idl.js
LP#1350042 Browser client templates/scripts (phase 1)
[Evergreen.git] / Open-ILS / web / js / ui / default / staff / services / idl.js
1 /**
2  * Core Service - egIDL
3  *
4  * IDL parser
5  * usage:
6  *  var aou = new egIDL.aou();
7  *  var fullIDL = egIDL.classes;
8  *
9  *  IDL TODO:
10  *
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 
13  *    class level.
14  * 2. we don't need to store array_position in /IDL2js since it
15  *    can be derived at parse time.  Ditto saving space.
16  */
17 angular.module('egCoreMod')
18
19 .factory('egIDL', ['$window', function($window) {
20
21     var service = {};
22
23     service.parseIDL = function() {
24         //console.debug('egIDL.parseIDL()');
25
26         // retain a copy of the full IDL within the service
27         service.classes = $window._preload_fieldmapper_IDL;
28
29         // keep this reference around (note: not a clone, just a ref)
30         // so that unit tests, which repeatedly instantiate the
31         // service will work.
32         //$window._preload_fieldmapper_IDL = null;
33
34         /**
35          * Creates the class constructor and getter/setter
36          * methods for each IDL class.
37          */
38         function mkclass(cls, fields) {
39
40             service[cls] = function(seed) {
41                 this.a = seed || [];
42                 this.classname = cls;
43                 this._isfieldmapper = true;
44             }
45
46             /** creates the getter/setter methods for each field */
47             angular.forEach(fields, function(field, idx) {
48                 service[cls].prototype[fields[idx].name] = function(n) {
49                     if (arguments.length==1) this.a[idx] = n;
50                     return this.a[idx];
51                 }
52             });
53
54             // global class constructors required for JSON_v1.js
55             $window[cls] = service[cls]; 
56         }
57
58         for (var cls in service.classes) 
59             mkclass(cls, service.classes[cls].fields);
60     };
61
62     /**
63      * Generate a hash version of an IDL object.
64      *
65      * Flatten determines if nested objects should be squashed into
66      * the top-level hash.
67      *
68      * If 'flatten' is false, e.g.:
69      *
70      * {"call_number" : {"label" :  "foo"}}
71      *
72      * If 'flatten' is true, e.g.:
73      *
74      * e.g.  {"call_number.label" : "foo"}
75      */
76     service.toHash = function(obj, flatten) {
77         if (!angular.isObject(obj)) return obj; // arrays are objects
78
79         if (angular.isArray(obj)) { // NOTE: flatten arrays not supported
80             return obj.map(function(item) {return service.toHash(item)});
81         }
82
83         var field_names = obj.classname ? 
84             Object.keys(service.classes[obj.classname].field_map) :
85             Object.keys(obj);
86
87         var hash = {};
88         angular.forEach(
89             field_names,
90             function(field) { 
91
92                 var val = service.toHash(
93                     angular.isFunction(obj[field]) ? 
94                         obj[field]() : obj[field], 
95                     flatten
96                 );
97
98                 if (flatten && angular.isObject(val)) {
99                     angular.forEach(val, function(sub_val, key) {
100                         var fname = field + '.' + key;
101                         hash[fname] = sub_val;
102                     });
103
104                 } else if (val !== undefined) {
105                     hash[field] = val;
106                 }
107             }
108         );
109
110         return hash;
111     }
112
113     // Transforms a flattened hash (see toHash() or egGridFlatDataProvider)
114     // to a nested hash.
115     //
116     // e.g. {"call_number.label" : "foo"} => {"call_number":{"label":"foo"}}
117     service.flatToNestedHash = function(obj) {
118         var hash = {};
119         angular.forEach(obj, function(val, key) {
120             var parts = key.split('.');
121             var sub_hash = hash;
122             var last_key;
123             for (var i = 0; i < parts.length; i++) {
124                 var part = parts[i];
125                 if (i == parts.length - 1) {
126                     sub_hash[part] = val;
127                     break;
128                 } else {
129                     if (!sub_hash[part])
130                         sub_hash[part] = {};
131                     sub_hash = sub_hash[part];
132                 }
133             }
134         });
135
136         return hash;
137     }
138
139     return service;
140 }]);
141