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

Last change on this file since 26 was 26, checked in by djay, 10 years ago

ZOO-Kernel updates and bug fixes :

  • Fixing gestion of RawDataOutput? when the Service return SERVICE_FAILED an ExceptionReport? was returned to the client.
  • Use gcc when compiling service_internal.c to avoid strange error messages about switch ....
  • Function setMapInMaps was added in service.h to let users set the value of a specific map in a maps.
  • Fixing JavaScript? issue during the context destruction process.
  • Use the GetStatus? ZOO Service when it is available on the local installation for statusLocation.
  • Add some comments for ServiceStarted?, ServiceSucceeded?, ServiceFailed? and ServiceAccepted?.
  • Dynamic creation of a lenv maps in the main configuration file maps, containing the current status and a sid (Service ID). Those informations can be used later by the GetStatus? Service to let user check the on-going status during the Service runs.
  • Function updateStatus was added to service_internal.h which let the Services developers set the current percentCompleted value.

ZOO-Service updates and bug fixes :

  • Add GetStatus? Service and its demo longProcess Service. All are in the wps_status.zo Services Provider.
  • Use the setMapInMaps in the base-vect-ops code to enhance readibility.

ZOO-API updates :

  • Add the function ZOO.UpdateStatus? to the ZOO JavaScript? API which simply point on ZOOUpdateStatus which can be called as-is from JavaScript?. Use : ZOOUpdateStatus(conf,value) where conf is the main configuration file maps and value the the value of the current status.
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