Fix unit tests for Python in a twistd instance
[OpenSRF.git] / examples / fieldmapper2javascript.xsl
1 <xsl:stylesheet
2         version='1.0'
3         xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
4         xmlns:opensrf="http://opensrf.org/xmlns/opensrf"
5         xmlns:cdbi="http://opensrf.org/xmlns/opensrf/cdbi"
6         xmlns:database="http://opensrf.org/xmlns/opensrf/database"
7         xmlns:perl="http://opensrf.org/xmlns/opensrf/perl"
8         xmlns:javascript="http://opensrf.org/xmlns/opensrf/javascript"
9         xmlns:c="http://opensrf.org/xmlns/opensrf/c">
10         <xsl:output method="text" />
11         <xsl:strip-space elements="xsl:*"/>
12         <xsl:variable name="last_field_pos"/>
13
14         <xsl:template match="/">
15 // support functions
16  
17 var IE = false;
18 var unit_test = false;
19  
20 function instanceOf(object, constructorFunction) {
21         if(!IE) {
22                 while (object != null) {
23                         if (object == constructorFunction.prototype)
24                                 return true;
25                         object = object.__proto__;
26                 }
27         } else {
28                 while(object != null) {
29                         if( object instanceof constructorFunction )
30                                 return true;
31                         object = object.__proto__;
32                 }
33         }
34         return false;
35 }
36  
37 // Top level superclass
38 function Fieldmapper(array) {
39         this.array = [];
40         if(array) {
41                 if (array.constructor == Array) {
42                         this.array = array;
43                 } else if ( instanceOf( array, String ) || instanceOf( array, Number ) ) {
44
45                         var obj = null;
46                         if (this.cacheable) {
47                                 try {
48                                         obj = this.baseClass.obj_cache[this.classname][array];
49                                 } catch (E) {};
50                         }
51
52                         if (!obj) {
53                                 obj = user_request(
54                                         'open-ils.proxy',
55                                         'open-ils.proxy.proxy',
56                                         [
57                                                 mw.G.auth_ses[0],
58                                                 'open-ils.storage',
59                                                 'open-ils.storage.direct.' + this.db_type + '.retrieve',
60                                                 array
61                                         ]
62                                 )[0];
63
64                                 if (this.cacheable) {
65                                         if (this.baseClass.obj_cache[this.classname] == null)
66                                                 this.baseClass.obj_cache[this.classname] = {};
67
68                                         this.baseClass.obj_cache[this.classname][obj.id()] = obj;
69                                 }
70                         }
71                         this.array = obj.array;
72
73                 } else {
74                         throw new FieldmapperException( "Attempt to build fieldmapper object with something wierd");
75                 }
76         }
77 }
78 Fieldmapper.prototype.baseClass = Fieldmapper;
79 Fieldmapper.prototype.obj_cache = {};
80
81 Fieldmapper.prototype.search function (type,field,value) {
82
83         var list = user_request(
84                 'open-ils.proxy',
85                 'open-ils.proxy.proxy',
86                 [
87                         mw.G.auth_ses[0],
88                         'open-ils.storage',
89                         'open-ils.storage.direct.' + type.db_type + '.search.' + field,
90                         array
91                 ]
92         )[0];
93         if (type.cacheable) {
94                 if (type.baseClass.obj_cache[type.classname] == null)
95                         type.baseClass.obj_cache[type.classname] = {};
96                 for (var i in list) {
97                         type.baseClass.obj_cache[type.classname][list[i].id()] = list[i];
98                 }
99         }
100         return list;
101 }
102  
103 Fieldmapper.prototype.clone = function() {
104         var obj = new this.constructor();
105
106         for( var i in this.array ) {
107                 var thing = this.array[i];
108                 if(thing == null) continue;
109
110                 if( thing._isfieldmapper ) {
111                         obj.array[i] = thing.clone();
112                 } else {
113
114                         if(instanceOf(thing, Array)) {
115                                 obj.array[i] = new Array();
116
117                                 for( var j in thing ) {
118
119                                         if( thing[j]._isfieldmapper )
120                                                 obj.array[i][j] = thing[j].clone();
121                                         else
122                                                 obj.array[i][j] = thing[j];
123                                 }
124                         } else {
125                                 obj.array[i] = thing;
126                         }
127                 }
128         }
129         return obj;
130 }
131   
132 function FieldmapperException(message) {
133         this.message = message;
134 }
135
136 FieldmapperException.toString = function() {
137         return "FieldmapperException: " + this.message + "\n";
138
139 }
140
141         
142                 <xsl:apply-templates select="opensrf:fieldmapper/opensrf:classes"/>
143         </xsl:template>
144
145
146
147
148
149 <!-- sub-templates -->
150         <xsl:template match="opensrf:fieldmapper/opensrf:classes">
151                 <xsl:for-each select="opensrf:class">
152                         <xsl:sort select="@id"/>
153                         <xsl:apply-templates select="."/>
154                 </xsl:for-each>
155         </xsl:template>
156
157
158
159
160         <xsl:template match="opensrf:class">
161                 <xsl:apply-templates select="@javascript:class"/>
162                 <xsl:apply-templates select="opensrf:fields"/>
163                 <xsl:apply-templates select="opensrf:links/opensrf:link[@type='has_many']"/>
164         </xsl:template>
165
166
167
168
169         <xsl:template match="opensrf:fields">
170                 <xsl:apply-templates select="opensrf:field"/>
171         </xsl:template>
172
173
174
175
176
177         <xsl:template match="@javascript:class">
178
179 // Class definition for "<xsl:value-of select="."/>"
180
181 function <xsl:value-of select="."/> (array) {
182
183         if (!instanceOf(this, <xsl:value-of select="."/>))
184                 return new <xsl:value-of select="."/>(array);
185
186         this.baseClass.call(this,array);
187         this.classname = "<xsl:value-of select="."/>";
188         this._isfieldmapper = true;
189         this.uber = <xsl:value-of select="."/>.baseClass.prototype;
190 }
191
192 <xsl:value-of select="."/>.prototype                    = new <xsl:value-of select="../javascript:superclass"/>();
193 <xsl:value-of select="."/>.prototype.constructor        = <xsl:value-of select="."/>;
194 <xsl:value-of select="."/>.baseClass                    = <xsl:value-of select="../javascript:superclass"/>;
195 <xsl:value-of select="."/>.prototype.cachable           = true;
196 <xsl:value-of select="."/>.prototype.fields             = [];
197 <xsl:value-of select="."/>.last_real_field              = 2;
198  
199 <!-- XXX This needs to come from somewhere else!!!! -->
200 <xsl:value-of select="."/>.prototype.db_type            = "<xsl:value-of select="../database:table[@rdbms='Pg']/database:name"/>";
201  
202 <xsl:value-of select="."/>.prototype.isnew = function(new_value) {
203         if(arguments.length == 1) { this.array[0] = new_value; }
204         return this.array[0];
205 }
206  
207 <xsl:value-of select="."/>.prototype.ischanged = function(new_value) {
208         if(arguments.length == 1) { this.array[1] = new_value; }
209         return this.array[1];
210 }
211  
212 <xsl:value-of select="."/>.prototype.isdeleted = function(new_value) {
213         if(arguments.length == 1) { this.array[2] = new_value; }
214         return this.array[2];
215 }
216  
217         </xsl:template>
218
219
220
221
222
223         <!-- scalar valued fields and "has_a" relationships -->
224         <xsl:template match="opensrf:field">
225
226                 <xsl:variable name="num"><xsl:number/></xsl:variable>
227                 <xsl:variable name="field_pos" select="$num + 2"/>
228                 <xsl:variable name="last_field_pos" select="$field_pos + 1"/>
229                 <xsl:variable name="field_name" select="@name"/>
230
231 // Accessor/mutator for <xsl:value-of select="../../@javascript:class"/>.<xsl:value-of select="$field_name"/>:
232 <xsl:value-of select="../../@javascript:class"/>.last_real_field++;
233 <xsl:value-of select="../../@javascript:class"/>.prototype.fields.push("<xsl:value-of select="$field_name"/>");
234 <xsl:value-of select="../../@javascript:class"/>.prototype.<xsl:value-of select="$field_name"/> = function (new_value) {
235         if(arguments.length == 1) { this.array[<xsl:value-of select="$field_pos"/>] = new_value; }
236
237                 <xsl:if test="../../opensrf:links/opensrf:link[@field=$field_name and @type='has_a']">
238                         <!-- We have a fkey on this field.  Go fetch the referenced object. -->
239                         <xsl:variable
240                                 name="source"
241                                 select="../../opensrf:links/opensrf:link[@field=$field_name and @type='has_a']/@source"/>
242
243         var val = this.array[<xsl:value-of select="$field_pos"/>];
244
245         if (!instanceOf(this.array[<xsl:value-of select="$field_pos"/>], <xsl:value-of select="$source"/>)) {
246                 if (this.array[<xsl:value-of select="$field_pos"/>] != null) {
247                         this.array[<xsl:value-of select="$field_pos"/>] = new <xsl:value-of select="$source"/>(val);
248                 }
249         }
250                 </xsl:if>
251         return this.array[<xsl:value-of select="$field_pos"/>];
252 }
253         </xsl:template>
254
255
256
257
258
259         <!-- "has_many" relationships -->
260         <xsl:template match="opensrf:links/opensrf:link[@type='has_many']">
261                 <xsl:variable name="num"><xsl:number/></xsl:variable>
262                 <xsl:variable name="source"><xsl:value-of select="@source"/></xsl:variable>
263                 <xsl:variable name="classname"><xsl:value-of select="../../@javascript:class"/></xsl:variable>
264                 <xsl:variable name="id"><xsl:value-of select="../../@id"/></xsl:variable>
265                 <xsl:variable name="fkey" select="//*[@id=$source]/opensrf:links/opensrf:link[@type='has_a' and @source=$id]/@field"/>
266                 <xsl:variable name="pkey" select="../../opensrf:fields/opensrf:field[@database:primary='true']/@name"/>
267
268 // accessor for <xsl:value-of select="$classname"/>:
269 <xsl:value-of select="$classname"/>.prototype.<xsl:value-of select="@field"/> = function () {
270  
271         var _pos = <xsl:value-of select="$classname"/>.last_real_field + <xsl:value-of select="$num"/>;
272  
273         if (!instanceOf(this.array[_pos], Array)) {
274                 this.array[_pos] = [];
275  
276         if (this.array[_pos].length == 0) {
277                 /* get the real thing.
278                  * search where <xsl:value-of select="$source"/>.<xsl:value-of select="$fkey"/>()
279                  * equals this.<xsl:value-of select="../../opensrf:fields/opensrf:field[@database:primary='true']/@name"/>();
280                  */
281                 this.array[_pos] = this.uber.search(
282                         <xsl:value-of select="$source"/>,
283                         "<xsl:value-of select="$fkey"/>",
284                         this.<xsl:value-of select="$pkey"/>()
285                 );
286         }
287  
288         return this.array[_pos];
289 }
290
291         </xsl:template>
292
293
294
295
296 </xsl:stylesheet>
297