source: branches/branch-1.2/zoo-kernel/service_internal_js.c @ 301

Last change on this file since 301 was 301, checked in by djay, 13 years ago

Merge branch-1.2 r268:r296.

File size: 14.0 KB
RevLine 
[1]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
[26]25#include "service_internal.h"
[1]26
27static char dbg[1024];
28
[301]29JSBool
30JSAlert(JSContext *cx, uintN argc, jsval *argv1)
31{
32  jsval *argv = JS_ARGV(cx,argv1);
33  int i=0;
34  JS_MaybeGC(cx);
35  for(i=0;i<argc;i++){
36    JSString* jsmsg = JS_ValueToString(cx,argv[i]);
37    fprintf(stderr,"[ZOO-API:JS] %s\n",JS_EncodeString(cx,jsmsg));
38  }
39  JS_MaybeGC(cx);
40 
41  return JS_TRUE;
42}
43
[1]44int zoo_js_support(maps** main_conf,map* request,service* s,
45                   maps **inputs,maps **outputs)
46{
[9]47  maps* main=*main_conf;
48  maps* _inputs=*inputs;
49  maps* _outputs=*outputs;
50
[1]51  /* The class of the global object. */
52  JSClass global_class = {
53    "global", JSCLASS_GLOBAL_FLAGS,
54    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
55    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
56    JSCLASS_NO_OPTIONAL_MEMBERS
57  };
58
59  /* JS variables. */
60  JSRuntime *rt;
61  JSContext *cx;
62  JSObject  *global;
63
64  /* Create a JS runtime. */
65  rt = JS_NewRuntime(8L * 1024L * 1024L);
66  if (rt == NULL)
67    return 1;
[9]68 
[1]69  /* Create a context. */
[9]70  cx = JS_NewContext(rt,8192);
[1]71  if (cx == NULL){
72    return 1;
73  }
[301]74  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT );//| JSOPTION_METHODJIT);
[1]75  JS_SetVersion(cx, JSVERSION_LATEST);
76  JS_SetErrorReporter(cx, reportError);
77
78  /* Create the global object. */
[301]79  //global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
80  global = JS_NewObject(cx, &global_class, NULL,NULL);
[1]81
82  /* Populate the global object with the standard globals,
83     like Object and Array. */
84  if (!JS_InitStandardClasses(cx, global)){
85    return 1;
86  }
[301]87
[1]88  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
89    return 1;
[26]90  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
91    return 1;
[301]92  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
93    return 1;
[1]94
[42]95  map* tmpm1=getMap(request,"metapath");
96  char ntmp[1024];
97  getcwd(ntmp,1024);
98
99  /**
100   * Load the first part of the ZOO-API
101   */
102  char api0[strlen(tmpm1->value)+strlen(ntmp)+15];
103  sprintf(api0,"%s/%sZOO-proj4js.js",ntmp,tmpm1->value);
[301]104#ifdef JS_DEBUG
[42]105  fprintf(stderr,"Trying to load %s\n",api0);
[301]106#endif
107  JSObject *api_script1=loadZooApiFile(cx,global,api0);
[42]108  fflush(stderr);
109
110  char api1[strlen(tmpm1->value)+strlen(ntmp)+11];
111  sprintf(api1,"%s/%sZOO-api.js",ntmp,tmpm1->value);
[301]112#ifdef JS_DEBUG
[42]113  fprintf(stderr,"Trying to load %s\n",api1);
[301]114#endif
115  JSObject *api_script2=loadZooApiFile(cx,global,api1);
[42]116  fflush(stderr);
117
[1]118  /* Your application code here. This may include JSAPI calls
119     to create your own custom JS objects and run scripts. */
120  maps* out=*outputs;
121  int res=SERVICE_FAILED;
122  maps* mc=*main_conf;
123  map* tmpm2=getMap(s->content,"serviceProvider");
[42]124
[26]125  char filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2];
[1]126  sprintf(filename,"%s/%s%s",ntmp,tmpm1->value,tmpm2->value);
[26]127  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+1]=0;
[301]128#ifdef JS_DEBUG
[26]129  fprintf(stderr,"FILENAME %s\n",filename);
[301]130#endif
[1]131  struct stat file_status;
132  stat(filename, &file_status);
133  char source[file_status.st_size];
134  uint16 lineno;
135  jsval rval;
136  JSBool ok ;
[301]137  JSObject *script = JS_CompileFile(cx, global, filename);
[9]138  if(script!=NULL){
[1]139    (void)JS_ExecuteScript(cx, global, script, &rval);
140  }
141  else{
142    char tmp1[1024];
143    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
144    map* err=createMap("text",tmp1);
145    addMapToMap(&err,createMap("code","NoApplicableCode"));
146    printExceptionReportResponse(mc,err);
147    JS_DestroyContext(cx);
148    JS_DestroyRuntime(rt);
149    JS_ShutDown();
150    exit(-1);
151  }
152  /* Call a function in obj's scope. */
153  jsval argv[3];
[9]154  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
155  argv[0] = OBJECT_TO_JSVAL(jsargv1);
156  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
157  argv[1] = OBJECT_TO_JSVAL(jsargv2);
158  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
159  argv[2] = OBJECT_TO_JSVAL(jsargv3);
160  jsval rval1=JSVAL_NULL;
[1]161#ifdef JS_DEBUG
162  fprintf(stderr, "object %p\n", (void *) argv[2]);
163#endif
164
165  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
166
167#ifdef JS_DEBUG
168  fprintf(stderr, "object %p\n", (void *) argv[2]);
169#endif
170
171  JSObject *d;
[9]172  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
[1]173#ifdef JS_DEBUG
174    fprintf(stderr,"Function run sucessfully !\n");
175#endif
176    /* Should get a number back from the service function call. */
177    ok = JS_ValueToObject(cx, rval1, &d);
178  }else{
179    /* Unable to run JS function */
180    char tmp1[1024];
[9]181    if(strlen(dbg)==0)
182      sprintf(dbg,"No result was found after the function call");
[301]183    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
184#ifdef JS_DEBUG
[1]185    fprintf(stderr,"%s",tmp1);
[301]186#endif
[1]187    map* err=createMap("text",tmp1);
[9]188    addToMap(err,"code","NoApplicableCode");
[1]189    printExceptionReportResponse(*main_conf,err);
[9]190    freeMap(&err);
191    free(err);
[1]192    JS_DestroyContext(cx);
193    JS_DestroyRuntime(rt);
194    JS_ShutDown();
[9]195    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
[1]196    exit(-1);
197  }
198
199  jsval t=OBJECT_TO_JSVAL(d);
[9]200  if(JS_IsArrayObject(cx,d)){
[1]201#ifdef JS_DEBUG
202    fprintf(stderr,"An array was returned !\n");
203#endif
[9]204    jsint len;
205    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
[1]206#ifdef JS_DEBUG
207      fprintf(stderr,"outputs array is empty\n");
208#endif
209    }
210    jsval tmp1;
[9]211    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
[1]212    res=JSVAL_TO_INT(tmp1);
213#ifdef JS_DEBUG
214    fprintf(stderr," * %d * \n",res);
215#endif
216    jsval tmp2;
[9]217    JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
218    if(hasElement==JS_TRUE){
219      *outputs=mapsFromJSObject(cx,tmp2);
220    }
[1]221  }
222  else{
[9]223#ifdef JS_DEBUG
224    fprintf(stderr,"The serice didn't return an array !\n");
225#endif
[1]226    jsval tmp1;
[9]227    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
[1]228    res=JSVAL_TO_INT(tmp1);
229
[9]230#ifdef JS_DEBUG
[1]231    fprintf(stderr," * %d * \n",res);
[9]232#endif
[1]233    jsval tmp2;
[9]234    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
[301]235#ifdef JS_DEBUG
[1]236    if(!hasElement)
237      fprintf(stderr,"No outputs property returned\n");
[9]238    if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
[1]239      fprintf(stderr,"outputs is array an as expected\n");
240    else
241      fprintf(stderr,"outputs is not an array as expected\n");
[301]242#endif
[9]243    *outputs=mapsFromJSObject(cx,tmp2);
[1]244#ifdef JS_DEBUG
[301]245    dumpMaps(outputs);
[1]246#endif
247  }
248
249  /* Cleanup. */
[301]250  JS_DestroyContext(cx);
[1]251  JS_DestroyRuntime(rt);
252  JS_ShutDown();
253#ifdef JS_DEBUG
254  fprintf(stderr,"Returned value %d\n",res);
255#endif
256  return res;
257}
258
[301]259JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
[42]260  struct stat api_status;
261  int s=stat(filename, &api_status);
262  if(s==0){
263    jsval rval;
264    JSBool ok ;
[301]265    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
[42]266    if(script!=NULL){
[301]267      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
268#ifdef JS_DEBUG
[42]269      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
[301]270#endif
[42]271      return script;
272    }
[301]273#ifdef JS_DEBUG
[42]274    else
275      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
[301]276#endif
[42]277  }
[301]278#ifdef JS_DEBUG
[42]279  else
280    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
[301]281#endif
[42]282  return NULL;
283}
284
[1]285JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
286  JSObject *res = JS_NewArrayObject(cx, 0, NULL);
[9]287  if(res==NULL)
288    fprintf(stderr,"Array Object is NULL!\n");
[1]289  maps* tmp=t;
290  while(tmp!=NULL){
291    jsuint len;
292    JSObject* res1=JS_NewObject(cx, NULL, NULL, NULL);
293    JSObject *pval=JSObject_FromMap(cx,tmp->content);
294    jsval pvalj=OBJECT_TO_JSVAL(pval);
295    JS_SetProperty(cx, res1, tmp->name, &pvalj);
296    JS_GetArrayLength(cx, res, &len);
297    jsval res1j = OBJECT_TO_JSVAL(res1);
298    JS_SetElement(cx,res,len,&res1j);
299#ifdef JS_DEBUG
300    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
301#endif
302    tmp=tmp->next;
303  } 
304  return res;
305}
306
307JSObject* JSObject_FromMap(JSContext *cx,map* t){
308  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
309  jsval resf =  OBJECT_TO_JSVAL(res);
310  map* tmpm=t;
311  while(tmpm!=NULL){
[301]312    jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
[9]313    JS_SetProperty(cx, res, tmpm->name,&jsstr);
[1]314#ifdef JS_DEBUG
315    fprintf(stderr,"%s => %s\n",tmpm->name,tmpm->value);
316#endif
317    tmpm=tmpm->next;
318  }
319  return res;
320}
321
322maps* mapsFromJSObject(JSContext *cx,jsval t){
323  maps *res=NULL;
324  maps *tres=NULL;
[9]325  jsint oi=0;
326  JSObject* tt=JSVAL_TO_OBJECT(t);
[1]327#ifdef JS_DEBUG
328  fprintf(stderr,"Is finally an array ?\n");
[9]329  if(JS_IsArrayObject(cx,tt)){
[1]330    fprintf(stderr,"Is finally an array !\n");
331  }
332  else
333    fprintf(stderr,"Is not an array !\n");
334#endif
[9]335  jsint len;
336  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
337  if(hasLen==JS_FALSE){
[1]338#ifdef JS_DEBUG
339    fprintf(stderr,"outputs array is empty\n");
340#endif
341  }
342#ifdef JS_DEBUG
343  fprintf(stderr,"outputs array length : %d\n",len);
344#endif
[9]345  for(oi=0;oi < len;oi++){
[1]346#ifdef JS_DEBUG
[9]347    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
[1]348#endif
349    jsval tmp1;
[9]350    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
351    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
352    JSIdArray *idp=JS_Enumerate(cx,otmp1);
[1]353    if(idp!=NULL) {
354      int index;
355      jsdouble argNum;
356#ifdef JS_DEBUG
357      fprintf(stderr,"Properties length :  %d \n",idp->length);
358#endif
[301]359      tres=(maps*)malloc(MAPS_SIZE);
360      tres->name=NULL;
361      tres->content=NULL;
362      tres->next=NULL;
363
[1]364      for (index=0,argNum=idp->length;index<argNum;index++) { 
[9]365        jsval id = idp->vector[index];
[1]366        jsval vp;
367        JSString* str; 
368        JS_IdToValue(cx,id,&vp);
369        char *c, *tmp;
370        JSString *jsmsg;
371        size_t len1;
372        jsmsg = JS_ValueToString(cx,vp);
373        len1 = JS_GetStringLength(jsmsg);
374#ifdef JS_DEBUG
[301]375        fprintf(stderr,"Enumerate id : %d => %s\n",oi,JS_EncodeString(cx,jsmsg));
[1]376#endif
[9]377        jsval nvp=JSVAL_NULL;
[301]378        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), JS_EncodeString(cx,jsmsg), &nvp)==JS_FALSE)){
[1]379#ifdef JS_DEBUG
[301]380          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,JS_EncodeString(cx,jsmsg));
[1]381#endif
[301]382        }
383       
[1]384        if(JSVAL_IS_OBJECT(nvp)){
385#ifdef JS_DEBUG
386          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
387#endif
388        }
[301]389
390        JSObject *nvp1=JSVAL_NULL;
[1]391        JS_ValueToObject(cx,nvp,&nvp1);
392        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
393        if(JSVAL_IS_OBJECT(nvp1j)){
[301]394          JSString *jsmsg1;
395          JSObject *nvp2=JSVAL_NULL;
396          jsmsg1 = JS_ValueToString(cx,nvp1j);
397          len1 = JS_GetStringLength(jsmsg1);
[1]398#ifdef JS_DEBUG
[301]399          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
[1]400#endif
[301]401          if(strcasecmp(JS_EncodeString(cx,jsmsg1),"[object Object]")==0){
402            tres->name=strdup(JS_EncodeString(cx,jsmsg));
403            tres->content=mapFromJSObject(cx,nvp1j);
404          }
[1]405          else
[301]406            if(strcasecmp(JS_EncodeString(cx,jsmsg),"name")==0){
407              tres->name=strdup(JS_EncodeString(cx,jsmsg1));
408            }
409            else{
410              if(tres->content==NULL)
411                tres->content=createMap(JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
412              else
413                addToMap(tres->content,JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
414            }
[1]415        }
416#ifdef JS_DEBUG
417        else
418          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
419#endif
[301]420
[1]421      }
[301]422#ifdef JS_DEBUG
423      dumpMaps(tres);
424#endif
425      if(res==NULL)
426        res=dupMaps(&tres);
427      else
428        addMapsToMaps(&res,tres);
429      freeMaps(&tres);
430      free(tres);
431      tres=NULL;
432
[1]433    }
434  }
435#ifdef JS_DEBUG
436  dumpMaps(res);
437#endif
438  return res;
439}
440
441map* mapFromJSObject(JSContext *cx,jsval t){
442  map *res=NULL;
[9]443  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
[1]444#ifdef JS_DEBUG
445  fprintf(stderr,"Properties %p\n",(void*)t);
446#endif
447  if(idp!=NULL) {
448    int index;
449    jsdouble argNum;
450#ifdef JS_DEBUG
451    fprintf(stderr,"Properties length :  %d \n",idp->length);
452#endif
453    for (index=0,argNum=idp->length;index<argNum;index++) { 
[9]454      jsval id = idp->vector[index];
[1]455      jsval vp;
456      JSString* str; 
457      JS_IdToValue(cx,id,&vp);
458      char *c, *tmp;
459      JSString *jsmsg,*jsmsg1;
460      size_t len,len1;
461      jsmsg = JS_ValueToString(cx,vp);
462      len = JS_GetStringLength(jsmsg);
463      jsval nvp;
[301]464      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), JS_EncodeString(cx,jsmsg), &nvp);
[1]465      jsmsg1 = JS_ValueToString(cx,nvp);
466      len1 = JS_GetStringLength(jsmsg1);
467#ifdef JS_DEBUG
[301]468      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
[1]469#endif
[9]470      if(res!=NULL){
[26]471#ifdef JS_DEBUG
[301]472        fprintf(stderr,"%s - %s\n",JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
[26]473#endif
[301]474        addToMap(res,JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
[9]475      }
476      else{
[301]477        res=createMap(JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
[9]478        res->next=NULL;
479      }
[26]480#ifdef JS_DEBUG
[9]481      dumpMap(res);
[26]482#endif
[1]483    }
484  }
485#ifdef JS_DEBUG
486  dumpMap(res);
487#endif
488  return res;
489}
490
491/* The error reporter callback. */
492void reportError(JSContext *cx, const char *message, JSErrorReport *report)
493{
494  sprintf(dbg,"%s:%u:%s\n",
495          report->filename ? report->filename : "<no filename>",
496          (unsigned int) report->lineno,
497          message);
498#ifdef JS_DEBUG
499  fprintf(stderr,"%s",dbg);
500#endif
501  fflush(stderr);
502}
503
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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