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

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

Update of both ZOO Kernel and ZOO Services (ogr base-vect-ops ServicesProvider?).
All the ZCFG files have been corrected to remove all references to wrong metadata (Test = Demo) to avoid validation issues.
Main Memory leaks has been removed from this version.
Addition of the Simplify Service in the C ogr base-vect-ops ServicesProvider? and addition of the Python version (without Simplify).
Update of the configure.ac and Makefile.in to follow dicussions on the mailing list and ensure to use our cgic206 and not another one, path to our cgic library is now directly in the Makefile.in file.
Accept the "-" character to name inputs, to solve issue on GRASS 7 integration.
Addition of the extension keyword for ZCFG file to be able to store resulting outputs in a file name using the extension suffix.
This version after a testing period shall be considerate as 1.0.1 version of the ZOO Project.

File size: 11.7 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_js.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
77  /* Your application code here. This may include JSAPI calls
78     to create your own custom JS objects and run scripts. */
79  maps* out=*outputs;
80  int res=SERVICE_FAILED;
81  maps* mc=*main_conf;
82  map* tmpm1=getMap(request,"metapath");
83  map* tmpm2=getMap(s->content,"serviceProvider");
84  char filename[strlen(tmpm1->value)+strlen(tmpm2->value)+6];
85  char ntmp[1024];
86  getcwd(ntmp,1024);
87  sprintf(filename,"%s/%s%s",ntmp,tmpm1->value,tmpm2->value);
88  struct stat file_status;
89  stat(filename, &file_status);
90  char source[file_status.st_size];
91  uint16 lineno;
92  jsval rval;
93  FILE *jsfile=fopen(filename,"r");
94  JSBool ok ;
95  JSScript *script = JS_CompileFileHandle(cx, global, filename,jsfile);
96  if(script!=NULL){
97    (void)JS_ExecuteScript(cx, global, script, &rval);
98  }
99  else{
100    char tmp1[1024];
101    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
102    map* err=createMap("text",tmp1);
103    addMapToMap(&err,createMap("code","NoApplicableCode"));
104    printExceptionReportResponse(mc,err);
105    JS_DestroyContext(cx);
106    JS_DestroyRuntime(rt);
107    JS_ShutDown();
108    fclose(jsfile);
109    exit(-1);
110  }
111  /* Call a function in obj's scope. */
112  jsval argv[3];
113  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
114  argv[0] = OBJECT_TO_JSVAL(jsargv1);
115  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
116  argv[1] = OBJECT_TO_JSVAL(jsargv2);
117  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
118  argv[2] = OBJECT_TO_JSVAL(jsargv3);
119  jsval rval1=JSVAL_NULL;
120#ifdef JS_DEBUG
121  fprintf(stderr, "object %p\n", (void *) argv[2]);
122#endif
123
124  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
125
126#ifdef JS_DEBUG
127  fprintf(stderr, "object %p\n", (void *) argv[2]);
128#endif
129
130  JSObject *d;
131  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
132#ifdef JS_DEBUG
133    fprintf(stderr,"Function run sucessfully !\n");
134#endif
135    /* Should get a number back from the service function call. */
136    ok = JS_ValueToObject(cx, rval1, &d);
137  }else{
138    /* Unable to run JS function */
139    char tmp1[1024];
140    if(strlen(dbg)==0)
141      sprintf(dbg,"No result was found after the function call");
142    sprintf(tmp1,"Unable to run %s from the JavScript file %s : \n %s",s->name,filename,dbg);
143    fprintf(stderr,"%s",tmp1);
144    map* err=createMap("text",tmp1);
145    addToMap(err,"code","NoApplicableCode");
146    printExceptionReportResponse(*main_conf,err);
147    freeMap(&err);
148    free(err);
149    JS_DestroyContext(cx);
150    JS_DestroyRuntime(rt);
151    JS_ShutDown();
152    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
153    exit(-1);
154  }
155
156  jsval t=OBJECT_TO_JSVAL(d);
157  if(JS_IsArrayObject(cx,d)){
158#ifdef JS_DEBUG
159    fprintf(stderr,"An array was returned !\n");
160#endif
161    jsint len;
162    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
163#ifdef JS_DEBUG
164      fprintf(stderr,"outputs array is empty\n");
165#endif
166    }
167    jsval tmp1;
168    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
169    res=JSVAL_TO_INT(tmp1);
170#ifdef JS_DEBUG
171    fprintf(stderr," * %d * \n",res);
172#endif
173    jsval tmp2;
174    JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
175    if(hasElement==JS_TRUE){
176      *outputs=mapsFromJSObject(cx,tmp2);
177    }
178  }
179  else{
180#ifdef JS_DEBUG
181    fprintf(stderr,"The serice didn't return an array !\n");
182#endif
183    jsval tmp1;
184    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
185    res=JSVAL_TO_INT(tmp1);
186
187#ifdef JS_DEBUG
188    fprintf(stderr," * %d * \n",res);
189#endif
190    jsval tmp2;
191    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
192    if(!hasElement)
193      fprintf(stderr,"No outputs property returned\n");
194    if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
195      fprintf(stderr,"outputs is array an as expected\n");
196    else
197      fprintf(stderr,"outputs is not an array as expected\n");
198    *outputs=mapsFromJSObject(cx,tmp2);
199#ifdef JS_DEBUG
200    dumpMaps(out);
201#endif
202  }
203
204  /* Cleanup. */
205  // The JS_MaybeGC call imply segmentation fault
206  //JS_MaybeGC(cx);
207  JS_DestroyScript(cx, script);
208  // If we use the DestroyContext as requested to release memory then we get
209  // issue getting back the main configuration maps after coming back to the
210  // runRequest function ...
211  //JS_DestroyContext(cx);
212  JS_DestroyRuntime(rt);
213  JS_ShutDown();
214#ifdef JS_DEBUG
215  fprintf(stderr,"Returned value %d\n",res);
216#endif
217  return res;
218}
219
220JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
221  JSObject *res = JS_NewArrayObject(cx, 0, NULL);
222  if(res==NULL)
223    fprintf(stderr,"Array Object is NULL!\n");
224  maps* tmp=t;
225  while(tmp!=NULL){
226    jsuint len;
227    JSObject* res1=JS_NewObject(cx, NULL, NULL, NULL);
228    JSObject *pval=JSObject_FromMap(cx,tmp->content);
229    jsval pvalj=OBJECT_TO_JSVAL(pval);
230    JS_SetProperty(cx, res1, tmp->name, &pvalj);
231    JS_GetArrayLength(cx, res, &len);
232    jsval res1j = OBJECT_TO_JSVAL(res1);
233    JS_SetElement(cx,res,len,&res1j);
234#ifdef JS_DEBUG
235    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
236#endif
237    tmp=tmp->next;
238  } 
239  return res;
240}
241
242JSObject* JSObject_FromMap(JSContext *cx,map* t){
243  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
244  jsval resf =  OBJECT_TO_JSVAL(res);
245  map* tmpm=t;
246  while(tmpm!=NULL){
247    jsval jsstr = STRING_TO_JSVAL(JS_NewString(cx,tmpm->value,strlen(tmpm->value)));
248    JS_SetProperty(cx, res, tmpm->name,&jsstr);
249#ifdef JS_DEBUG
250    fprintf(stderr,"%s => %s\n",tmpm->name,tmpm->value);
251#endif
252    tmpm=tmpm->next;
253  }
254  return res;
255}
256
257maps* mapsFromJSObject(JSContext *cx,jsval t){
258  maps *res=NULL;
259  maps *tres=NULL;
260  jsint oi=0;
261  JSObject* tt=JSVAL_TO_OBJECT(t);
262#ifdef JS_DEBUG
263  fprintf(stderr,"Is finally an array ?\n");
264  if(JS_IsArrayObject(cx,tt)){
265    fprintf(stderr,"Is finally an array !\n");
266  }
267  else
268    fprintf(stderr,"Is not an array !\n");
269#endif
270  jsint len;
271  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
272  if(hasLen==JS_FALSE){
273#ifdef JS_DEBUG
274    fprintf(stderr,"outputs array is empty\n");
275#endif
276  }
277#ifdef JS_DEBUG
278  fprintf(stderr,"outputs array length : %d\n",len);
279#endif
280  for(oi=0;oi < len;oi++){
281#ifdef JS_DEBUG
282    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
283#endif
284    jsval tmp1;
285    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
286    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
287    JSIdArray *idp=JS_Enumerate(cx,otmp1);
288    if(idp!=NULL) {
289      int index;
290      jsdouble argNum;
291#ifdef JS_DEBUG
292      fprintf(stderr,"Properties length :  %d \n",idp->length);
293#endif
294      for (index=0,argNum=idp->length;index<argNum;index++) { 
295        jsval id = idp->vector[index];
296        jsval vp;
297        JSString* str; 
298        JS_IdToValue(cx,id,&vp);
299        char *c, *tmp;
300        JSString *jsmsg;
301        size_t len1;
302        jsmsg = JS_ValueToString(cx,vp);
303        len1 = JS_GetStringLength(jsmsg);
304#ifdef JS_DEBUG
305        fprintf(stderr,"Enumerate id : %d => %s\n",oi,JS_GetStringBytes(jsmsg));
306#endif
307        jsval nvp=JSVAL_NULL;
308        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), JS_GetStringBytes(jsmsg), &nvp)==JS_FALSE))
309#ifdef JS_DEBUG
310        fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,JS_GetStringBytes(jsmsg));
311#endif
312        if(JSVAL_IS_OBJECT(nvp)){
313#ifdef JS_DEBUG
314          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
315#endif
316        }
317#ifdef JS_DEBUG
318        else
319          fprintf(stderr,"JSVAL NVP IS NOT OBJECT !!\n");
320#endif
321        JSObject *nvp1;
322        JS_ValueToObject(cx,nvp,&nvp1);
323        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
324        if(JSVAL_IS_OBJECT(nvp1j)){
325#ifdef JS_DEBUG
326          fprintf(stderr,"JSVAL NVP1J IS OBJECT\n");
327#endif
328          tres=(maps*)malloc(MAPS_SIZE);
329          tres->name=strdup(JS_GetStringBytes(jsmsg));
330          tres->content=mapFromJSObject(cx,nvp1j);
331          tres->next=NULL;
332#ifdef JS_DEBUG
333          dumpMaps(res);
334#endif
335          if(res==NULL)
336            res=dupMaps(&tres);
337          else
338            addMapsToMaps(&res,tres);
339          freeMaps(&tres);
340          free(tres);
341          tres=NULL;
342#ifdef JS_DEBUG
343          dumpMaps(res);
344#endif
345        }
346#ifdef JS_DEBUG
347        else
348          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
349#endif
350      }
351    }
352  }
353#ifdef JS_DEBUG
354  dumpMaps(res);
355#endif
356  return res;
357}
358
359map* mapFromJSObject(JSContext *cx,jsval t){
360  map *res=NULL;
361  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
362#ifdef JS_DEBUG
363  fprintf(stderr,"Properties %p\n",(void*)t);
364#endif
365  if(idp!=NULL) {
366    int index;
367    jsdouble argNum;
368#ifdef JS_DEBUG
369    fprintf(stderr,"Properties length :  %d \n",idp->length);
370#endif
371    for (index=0,argNum=idp->length;index<argNum;index++) { 
372      jsval id = idp->vector[index];
373      jsval vp;
374      JSString* str; 
375      JS_IdToValue(cx,id,&vp);
376      char *c, *tmp;
377      JSString *jsmsg,*jsmsg1;
378      size_t len,len1;
379      jsmsg = JS_ValueToString(cx,vp);
380      len = JS_GetStringLength(jsmsg);
381      jsval nvp;
382      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), JS_GetStringBytes(jsmsg), &nvp);
383      jsmsg1 = JS_ValueToString(cx,nvp);
384      len1 = JS_GetStringLength(jsmsg1);
385#ifdef JS_DEBUG
386      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
387#endif
388      if(res!=NULL){
389        fprintf(stderr,"%s - %s\n",JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
390        addToMap(res,JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
391      }
392      else{
393        res=createMap(JS_GetStringBytes(jsmsg),JS_GetStringBytes(jsmsg1));
394        res->next=NULL;
395      }
396      dumpMap(res);
397    }
398  }
399#ifdef JS_DEBUG
400  dumpMap(res);
401#endif
402  return res;
403}
404
405/* The error reporter callback. */
406void reportError(JSContext *cx, const char *message, JSErrorReport *report)
407{
408  sprintf(dbg,"%s:%u:%s\n",
409          report->filename ? report->filename : "<no filename>",
410          (unsigned int) report->lineno,
411          message);
412#ifdef JS_DEBUG
413  fprintf(stderr,"%s",dbg);
414#endif
415  fflush(stderr);
416}
417
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