source: trunk/zoo-kernel/service_internal_js.c @ 34

Last change on this file since 34 was 34, checked in by djay, 9 years ago

Make ZOO Kernel able to speak the natural language you teach him by using gettext tools for creating translation files. Add basic french translation .po files as current messages.po. Gettext Domains used are zoo-kernel and zoo-services.

File size: 11.9 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2010 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal.h"
26
27static char dbg[1024];
28
29int zoo_js_support(maps** main_conf,map* request,service* s,
30                   maps **inputs,maps **outputs)
31{
32  maps* main=*main_conf;
33  maps* _inputs=*inputs;
34  maps* _outputs=*outputs;
35
36  /* The class of the global object. */
37  JSClass global_class = {
38    "global", JSCLASS_GLOBAL_FLAGS,
39    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
40    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
41    JSCLASS_NO_OPTIONAL_MEMBERS
42  };
43
44  /* JS variables. */
45  JSRuntime *rt;
46  JSContext *cx;
47  JSObject  *global;
48
49  /* Create a JS runtime. */
50  rt = JS_NewRuntime(8L * 1024L * 1024L);
51  if (rt == NULL)
52    return 1;
53 
54  /* Create a context. */
55  cx = JS_NewContext(rt,8192);
56  if (cx == NULL){
57    return 1;
58  }
59  JS_SetOptions(cx, JSOPTION_VAROBJFIX);
60  JS_SetVersion(cx, JSVERSION_LATEST);
61  JS_SetErrorReporter(cx, reportError);
62
63  /* Create the global object. */
64  global = JS_NewObject(cx, &global_class, NULL, NULL);
65  if (global == NULL){
66    return 1;
67  }
68
69  /* Populate the global object with the standard globals,
70     like Object and Array. */
71  if (!JS_InitStandardClasses(cx, global)){
72    return 1;
73  }
74  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
75    return 1;
76  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
77    return 1;
78
79  /* Your application code here. This may include JSAPI calls
80     to create your own custom JS objects and run scripts. */
81  maps* out=*outputs;
82  int res=SERVICE_FAILED;
83  maps* mc=*main_conf;
84  map* tmpm1=getMap(request,"metapath");
85  map* tmpm2=getMap(s->content,"serviceProvider");
86  char ntmp[1024];
87  getcwd(ntmp,1024);
88  char filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2];
89  sprintf(filename,"%s/%s%s",ntmp,tmpm1->value,tmpm2->value);
90  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+1]=0;
91  fprintf(stderr,"FILENAME %s\n",filename);
92  struct stat file_status;
93  stat(filename, &file_status);
94  char source[file_status.st_size];
95  uint16 lineno;
96  jsval rval;
97  FILE *jsfile=fopen(filename,"r");
98  JSBool ok ;
99  JSScript *script = JS_CompileFileHandle(cx, global, filename,jsfile);
100  if(script!=NULL){
101    (void)JS_ExecuteScript(cx, global, script, &rval);
102  }
103  else{
104    char tmp1[1024];
105    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
106    map* err=createMap("text",tmp1);
107    addMapToMap(&err,createMap("code","NoApplicableCode"));
108    printExceptionReportResponse(mc,err);
109    JS_DestroyContext(cx);
110    JS_DestroyRuntime(rt);
111    JS_ShutDown();
112    fclose(jsfile);
113    exit(-1);
114  }
115  /* Call a function in obj's scope. */
116  jsval argv[3];
117  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
118  argv[0] = OBJECT_TO_JSVAL(jsargv1);
119  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
120  argv[1] = OBJECT_TO_JSVAL(jsargv2);
121  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
122  argv[2] = OBJECT_TO_JSVAL(jsargv3);
123  jsval rval1=JSVAL_NULL;
124#ifdef JS_DEBUG
125  fprintf(stderr, "object %p\n", (void *) argv[2]);
126#endif
127
128  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
129
130#ifdef JS_DEBUG
131  fprintf(stderr, "object %p\n", (void *) argv[2]);
132#endif
133
134  JSObject *d;
135  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
136#ifdef JS_DEBUG
137    fprintf(stderr,"Function run sucessfully !\n");
138#endif
139    /* Should get a number back from the service function call. */
140    ok = JS_ValueToObject(cx, rval1, &d);
141  }else{
142    /* Unable to run JS function */
143    char tmp1[1024];
144    if(strlen(dbg)==0)
145      sprintf(dbg,"No result was found after the function call");
146    sprintf(tmp1,"Unable to run %s from the JavScript file %s : \n %s",s->name,filename,dbg);
147    fprintf(stderr,"%s",tmp1);
148    map* err=createMap("text",tmp1);
149    addToMap(err,"code","NoApplicableCode");
150    printExceptionReportResponse(*main_conf,err);
151    freeMap(&err);
152    free(err);
153    JS_DestroyContext(cx);
154    JS_DestroyRuntime(rt);
155    JS_ShutDown();
156    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
157    exit(-1);
158  }
159
160  jsval t=OBJECT_TO_JSVAL(d);
161  if(JS_IsArrayObject(cx,d)){
162#ifdef JS_DEBUG
163    fprintf(stderr,"An array was returned !\n");
164#endif
165    jsint len;
166    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
167#ifdef JS_DEBUG
168      fprintf(stderr,"outputs array is empty\n");
169#endif
170    }
171    jsval tmp1;
172    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
173    res=JSVAL_TO_INT(tmp1);
174#ifdef JS_DEBUG
175    fprintf(stderr," * %d * \n",res);
176#endif
177    jsval tmp2;
178    JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
179    if(hasElement==JS_TRUE){
180      *outputs=mapsFromJSObject(cx,tmp2);
181    }
182  }
183  else{
184#ifdef JS_DEBUG
185    fprintf(stderr,"The serice didn't return an array !\n");
186#endif
187    jsval tmp1;
188    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
189    res=JSVAL_TO_INT(tmp1);
190
191#ifdef JS_DEBUG
192    fprintf(stderr," * %d * \n",res);
193#endif
194    jsval tmp2;
195    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
196    if(!hasElement)
197      fprintf(stderr,"No outputs property returned\n");
198    if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
199      fprintf(stderr,"outputs is array an as expected\n");
200    else
201      fprintf(stderr,"outputs is not an array as expected\n");
202    *outputs=mapsFromJSObject(cx,tmp2);
203#ifdef JS_DEBUG
204    dumpMaps(out);
205#endif
206  }
207
208  /* Cleanup. */
209  JS_DestroyScript(cx, script);
210  //JS_MaybeGC(cx);
211  // If we use the DestroyContext as requested to release memory then we get
212  // issue getting back the main configuration maps after coming back to the
213  // runRequest function ...
214  //JS_DestroyContext(cx);
215  JS_DestroyRuntime(rt);
216  JS_ShutDown();
217#ifdef JS_DEBUG
218  fprintf(stderr,"Returned value %d\n",res);
219#endif
220  return res;
221}
222
223JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
224  JSObject *res = JS_NewArrayObject(cx, 0, NULL);
225  if(res==NULL)
226    fprintf(stderr,"Array Object is NULL!\n");
227  maps* tmp=t;
228  while(tmp!=NULL){
229    jsuint len;
230    JSObject* res1=JS_NewObject(cx, NULL, NULL, NULL);
231    JSObject *pval=JSObject_FromMap(cx,tmp->content);
232    jsval pvalj=OBJECT_TO_JSVAL(pval);
233    JS_SetProperty(cx, res1, tmp->name, &pvalj);
234    JS_GetArrayLength(cx, res, &len);
235    jsval res1j = OBJECT_TO_JSVAL(res1);
236    JS_SetElement(cx,res,len,&res1j);
237#ifdef JS_DEBUG
238    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
239#endif
240    tmp=tmp->next;
241  } 
242  return res;
243}
244
245JSObject* JSObject_FromMap(JSContext *cx,map* t){
246  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
247  jsval resf =  OBJECT_TO_JSVAL(res);
248  map* tmpm=t;
249  while(tmpm!=NULL){
250    jsval jsstr = STRING_TO_JSVAL(JS_NewString(cx,tmpm->value,strlen(tmpm->value)));
251    JS_SetProperty(cx, res, tmpm->name,&jsstr);
252#ifdef JS_DEBUG
253    fprintf(stderr,"%s => %s\n",tmpm->name,tmpm->value);
254#endif
255    tmpm=tmpm->next;
256  }
257  return res;
258}
259
260maps* mapsFromJSObject(JSContext *cx,jsval t){
261  maps *res=NULL;
262  maps *tres=NULL;
263  jsint oi=0;
264  JSObject* tt=JSVAL_TO_OBJECT(t);
265#ifdef JS_DEBUG
266  fprintf(stderr,"Is finally an array ?\n");
267  if(JS_IsArrayObject(cx,tt)){
268    fprintf(stderr,"Is finally an array !\n");
269  }
270  else
271    fprintf(stderr,"Is not an array !\n");
272#endif
273  jsint len;
274  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
275  if(hasLen==JS_FALSE){
276#ifdef JS_DEBUG
277    fprintf(stderr,"outputs array is empty\n");
278#endif
279  }
280#ifdef JS_DEBUG
281  fprintf(stderr,"outputs array length : %d\n",len);
282#endif
283  for(oi=0;oi < len;oi++){
284#ifdef JS_DEBUG
285    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
286#endif
287    jsval tmp1;
288    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
289    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
290    JSIdArray *idp=JS_Enumerate(cx,otmp1);
291    if(idp!=NULL) {
292      int index;
293      jsdouble argNum;
294#ifdef JS_DEBUG
295      fprintf(stderr,"Properties length :  %d \n",idp->length);
296#endif
297      for (index=0,argNum=idp->length;index<argNum;index++) { 
298        jsval id = idp->vector[index];
299        jsval vp;
300        JSString* str; 
301        JS_IdToValue(cx,id,&vp);
302        char *c, *tmp;
303        JSString *jsmsg;
304        size_t len1;
305        jsmsg = JS_ValueToString(cx,vp);
306        len1 = JS_GetStringLength(jsmsg);
307#ifdef JS_DEBUG
308        fprintf(stderr,"Enumerate id : %d => %s\n",oi,JS_GetStringBytes(jsmsg));
309#endif
310        jsval nvp=JSVAL_NULL;
311        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), JS_GetStringBytes(jsmsg), &nvp)==JS_FALSE))
312#ifdef JS_DEBUG
313        fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,JS_GetStringBytes(jsmsg));
314#endif
315        if(JSVAL_IS_OBJECT(nvp)){
316#ifdef JS_DEBUG
317          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
318#endif
319        }
320#ifdef JS_DEBUG
321        else
322          fprintf(stderr,"JSVAL NVP IS NOT OBJECT !!\n");
323#endif
324        JSObject *nvp1;
325        JS_ValueToObject(cx,nvp,&nvp1);
326        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
327        if(JSVAL_IS_OBJECT(nvp1j)){
328#ifdef JS_DEBUG
329          fprintf(stderr,"JSVAL NVP1J IS OBJECT\n");
330#endif
331          tres=(maps*)malloc(MAPS_SIZE);
332          tres->name=strdup(JS_GetStringBytes(jsmsg));
333          tres->content=mapFromJSObject(cx,nvp1j);
334          tres->next=NULL;
335#ifdef JS_DEBUG
336          dumpMaps(res);
337#endif
338          if(res==NULL)
339            res=dupMaps(&tres);
340          else
341            addMapsToMaps(&res,tres);
342          freeMaps(&tres);
343          free(tres);
344          tres=NULL;
345#ifdef JS_DEBUG
346          dumpMaps(res);
347#endif
348        }
349#ifdef JS_DEBUG
350        else
351          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
352#endif
353      }
354    }
355  }
356#ifdef JS_DEBUG
357  dumpMaps(res);
358#endif
359  return res;
360}
361
362map* mapFromJSObject(JSContext *cx,jsval t){
363  map *res=NULL;
364  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
365#ifdef JS_DEBUG
366  fprintf(stderr,"Properties %p\n",(void*)t);
367#endif
368  if(idp!=NULL) {
369    int index;
370    jsdouble argNum;
371#ifdef JS_DEBUG
372    fprintf(stderr,"Properties length :  %d \n",idp->length);
373#endif
374    for (index=0,argNum=idp->length;index<argNum;index++) { 
375      jsval id = idp->vector[index];
376      jsval vp;
377      JSString* str; 
378      JS_IdToValue(cx,id,&vp);
379      char *c, *tmp;
380      JSString *jsmsg,*jsmsg1;
381      size_t len,len1;
382      jsmsg = JS_ValueToString(cx,vp);
383      len = JS_GetStringLength(jsmsg);
384      jsval nvp;
385      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), JS_GetStringBytes(jsmsg), &nvp);
386      jsmsg1 = JS_ValueToString(cx,nvp);
387      len1 = JS_GetStringLength(jsmsg1);
388#ifdef JS_DEBUG
389      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
390#endif
391      if(res!=NULL){
392#ifdef JS_DEBUG
393        fprintf(stderr,"%s - %s\n",JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
394#endif
395        addToMap(res,JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
396      }
397      else{
398        res=createMap(JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
399        res->next=NULL;
400      }
401#ifdef JS_DEBUG
402      dumpMap(res);
403#endif
404    }
405  }
406#ifdef JS_DEBUG
407  dumpMap(res);
408#endif
409  return res;
410}
411
412/* The error reporter callback. */
413void reportError(JSContext *cx, const char *message, JSErrorReport *report)
414{
415  sprintf(dbg,"%s:%u:%s\n",
416          report->filename ? report->filename : "<no filename>",
417          (unsigned int) report->lineno,
418          message);
419#ifdef JS_DEBUG
420  fprintf(stderr,"%s",dbg);
421#endif
422  fflush(stderr);
423}
424
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png