source: trunk/zoo-project/zoo-kernel/service_internal_js.c @ 844

Last change on this file since 844 was 828, checked in by djay, 8 years ago

Add support for headers definition to requests run from js ZOO-API.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 27.3 KB
RevLine 
[580]1/*
[1]2 * Author : Gérald FENOY
3 *
[360]4 * Copyright (c) 2009-2012 GeoLabs SARL
[1]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
[640]25#include "service_internal_js.h"
26#include "response_print.h"
[1]27
[383]28#ifndef JSCLASS_GLOBAL_FLAGS
29#define JSCLSAS_GLOBAL_FLAGS 0
30#endif
31
[1]32static char dbg[1024];
33
[580]34/**
35 * The function used as alert from the JavaScript environment (ZOO-API)
36 *
37 * @param cx the JavaScript context
38 * @param argc the number of parameters
39 * @param argv1 the parameter values
40 * @return true
41 */
[274]42JSBool
43JSAlert(JSContext *cx, uintN argc, jsval *argv1)
44{
45  jsval *argv = JS_ARGV(cx,argv1);
46  int i=0;
47  JS_MaybeGC(cx);
48  for(i=0;i<argc;i++){
49    JSString* jsmsg = JS_ValueToString(cx,argv[i]);
[471]50    char *tmp=JS_EncodeString(cx,jsmsg);
51    fprintf(stderr,"[ZOO-API:JS] %s\n",tmp);
52    free(tmp);
[274]53  }
54  JS_MaybeGC(cx);
55 
56  return JS_TRUE;
57}
58
[580]59/**
60 * The function used as importScript from the JavaScript environment (ZOO-API)
61 *
62 * @param cx the JavaScript context
63 * @param argc the number of parameters
64 * @param argv1 the parameter values
65 * @return true
66 */
[336]67JSBool
68JSLoadScripts(JSContext *cx, uintN argc, jsval *argv1)
69{
70  JS_MaybeGC(cx);
71
72  jsval *argv = JS_ARGV(cx,argv1);
73  int i=0;
74  JS_MaybeGC(cx);
75  for(i=0;i<argc;i++){
76    char *filename = JSValToChar(cx,&argv[i]);
77#ifdef JS_DEBUG
78    fprintf(stderr,"Trying to load %s\n",api0);
[364]79    fflush(stderr);
[336]80#endif
[784]81    JSObject *api_script1=loadZooApiFile(cx,JS_GetGlobalObject(cx),filename);
[336]82  }
83  JS_MaybeGC(cx);
84  JS_SET_RVAL(cx, argv1, JSVAL_VOID);
85 
86  return JS_TRUE;
87}
88
[580]89/**
90 * Load a JavaScript file then run the function corresponding to the service by
91 * passing the conf, inputs and outputs parameters by value as JavaScript
92 * Objects.
93 *
94 * @param main_conf the conf maps containing the main.cfg settings
95 * @param request the map containing the HTTP request
96 * @param s the service structure
97 * @param inputs the maps containing the inputs
98 * @param outputs the maps containing the outputs
[581]99 * @return SERVICE_SUCCEEDED or SERVICE_FAILED if the service run, -1
[580]100 *  if the service failed to load or throw error at runtime.
101 */
102int zoo_js_support(maps** main_conf,map* request,service* s,maps **inputs,maps **outputs)
[1]103{
[640]104  /*maps* main=*main_conf;
[9]105  maps* _inputs=*inputs;
[640]106  maps* _outputs=*outputs;*/
[9]107
[1]108  /* The class of the global object. */
[383]109  JSClass global_class= {
[1]110    "global", JSCLASS_GLOBAL_FLAGS,
[364]111    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
[1]112    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
113    JSCLASS_NO_OPTIONAL_MEMBERS
114  };
115
116  /* JS variables. */
117  JSRuntime *rt;
118  JSContext *cx;
119  JSObject  *global;
120
121  /* Create a JS runtime. */
122  rt = JS_NewRuntime(8L * 1024L * 1024L);
123  if (rt == NULL)
124    return 1;
[9]125 
[1]126  /* Create a context. */
[384]127  cx = JS_NewContext(rt,8192);
[1]128  if (cx == NULL){
129    return 1;
130  }
[383]131  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
[1]132  JS_SetVersion(cx, JSVERSION_LATEST);
133  JS_SetErrorReporter(cx, reportError);
134
135  /* Create the global object. */
[328]136  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
[1]137
138  /* Populate the global object with the standard globals,
139     like Object and Array. */
140  if (!JS_InitStandardClasses(cx, global)){
141    return 1;
142  }
[274]143
[403]144  /* Define specific function and global variable to share with JS runtime
145   */
[368]146  jsval tmp=INT_TO_JSVAL(3);
147  if (!JS_SetProperty(cx, global, "SERVICE_SUCCEEDED", &tmp))
148    return 1;
149  tmp=INT_TO_JSVAL(4);
150  if (!JS_SetProperty(cx, global, "SERVICE_FAILED", &tmp))
151    return 1;
[1]152  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
153    return 1;
[377]154  if (!JS_DefineFunction(cx, global, "ZOOTranslate", JSTranslate, 4, 0))
155    return 1;
[26]156  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
157    return 1;
[274]158  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
[336]159    return 1; 
160  if (!JS_DefineFunction(cx, global, "importScripts", JSLoadScripts, 1, 0))
[274]161    return 1;
[1]162
[336]163  /**
164   * Add private context object
165   */
166  void* cxPrivate = request;
167  JS_SetContextPrivate(cx,cxPrivate);
[505]168
[42]169  map* tmpm1=getMap(request,"metapath");
170  char ntmp[1024];
[784]171  map* cwdMap=getMapFromMaps(*main_conf,"main","servicePath");
172  if(cwdMap!=NULL)
173    sprintf(ntmp,"%s",cwdMap->value);
174  else
175    getcwd(ntmp,1024);
[42]176
177  /**
178   * Load the first part of the ZOO-API
179   */
[505]180  char *api0=(char*)malloc((strlen(ntmp)+17)*sizeof(char));
181  sprintf(api0,"%s/ZOO-proj4js.js",ntmp);
[274]182#ifdef JS_DEBUG
[42]183  fprintf(stderr,"Trying to load %s\n",api0);
[274]184#endif
185  JSObject *api_script1=loadZooApiFile(cx,global,api0);
[471]186  free(api0);
[42]187  fflush(stderr);
188
[505]189  char *api1=(char*)malloc((strlen(ntmp)+13)*sizeof(char));
190  sprintf(api1,"%s/ZOO-api.js",ntmp);
[274]191#ifdef JS_DEBUG
[42]192  fprintf(stderr,"Trying to load %s\n",api1);
[274]193#endif
194  JSObject *api_script2=loadZooApiFile(cx,global,api1);
[471]195  free(api1);
[42]196  fflush(stderr);
197
[1]198  /* Your application code here. This may include JSAPI calls
199     to create your own custom JS objects and run scripts. */
[640]200  //maps* out=*outputs;
[1]201  int res=SERVICE_FAILED;
[640]202  //maps* mc=*main_conf;
[1]203  map* tmpm2=getMap(s->content,"serviceProvider");
[42]204
[364]205  char *filename=(char*)malloc(strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+3);
[329]206  sprintf(filename,"%s/%s/%s",ntmp,tmpm1->value,tmpm2->value);
207  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2]=0;
[274]208#ifdef JS_DEBUG
[26]209  fprintf(stderr,"FILENAME %s\n",filename);
[274]210#endif
[1]211  struct stat file_status;
212  stat(filename, &file_status);
[471]213  //char *source=(char*)malloc(file_status.st_size);
[640]214  //uint16 lineno;
[1]215  jsval rval;
216  JSBool ok ;
[274]217  JSObject *script = JS_CompileFile(cx, global, filename);
[9]218  if(script!=NULL){
[1]219    (void)JS_ExecuteScript(cx, global, script, &rval);
220  }
221  else{
222    char tmp1[1024];
223    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
[471]224    free(filename);
[576]225    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
[471]226    JS_MaybeGC(cx);
[1]227    JS_DestroyContext(cx);
228    JS_DestroyRuntime(rt);
229    JS_ShutDown();
[471]230    return -1;
[1]231  }
[471]232 
[383]233
[1]234  /* Call a function in obj's scope. */
235  jsval argv[3];
[9]236  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
237  argv[0] = OBJECT_TO_JSVAL(jsargv1);
238  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
239  argv[1] = OBJECT_TO_JSVAL(jsargv2);
240  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
241  argv[2] = OBJECT_TO_JSVAL(jsargv3);
242  jsval rval1=JSVAL_NULL;
[1]243#ifdef JS_DEBUG
244  fprintf(stderr, "object %p\n", (void *) argv[2]);
245#endif
246
247  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
248
249#ifdef JS_DEBUG
250  fprintf(stderr, "object %p\n", (void *) argv[2]);
251#endif
252
253  JSObject *d;
[9]254  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
[1]255#ifdef JS_DEBUG
256    fprintf(stderr,"Function run sucessfully !\n");
257#endif
258    /* Should get a number back from the service function call. */
259    ok = JS_ValueToObject(cx, rval1, &d);
260  }else{
261    /* Unable to run JS function */
262    char tmp1[1024];
[9]263    if(strlen(dbg)==0)
264      sprintf(dbg,"No result was found after the function call");
[274]265    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
266#ifdef JS_DEBUG
[1]267    fprintf(stderr,"%s",tmp1);
[274]268#endif
[576]269    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
[471]270    free(filename);
271    JS_MaybeGC(cx);
[1]272    JS_DestroyContext(cx);
273    JS_DestroyRuntime(rt);
274    JS_ShutDown();
[9]275    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
[471]276    return -1;
[1]277  }
278
[640]279  //jsval t=OBJECT_TO_JSVAL(d);
[9]280  if(JS_IsArrayObject(cx,d)){
[1]281#ifdef JS_DEBUG
282    fprintf(stderr,"An array was returned !\n");
283#endif
[364]284    jsuint       len;
[9]285    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
[1]286#ifdef JS_DEBUG
287      fprintf(stderr,"outputs array is empty\n");
288#endif
289    }
290    jsval tmp1;
[9]291    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
[1]292    res=JSVAL_TO_INT(tmp1);
293#ifdef JS_DEBUG
294    fprintf(stderr," * %d * \n",res);
295#endif
[383]296    if(res==SERVICE_SUCCEEDED){
297      jsval tmp2;
298      JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
299      if(hasElement==JS_TRUE){
300        freeMaps(outputs);
301        free(*outputs);
302        *outputs=mapsFromJSObject(cx,tmp2);
303      }
304    }else{
305      jsval tmp3;
306      JSBool hasConf=JS_GetElement(cx,d,1,&tmp3);
307      if(hasConf==JS_TRUE){
308        freeMaps(main_conf);
309        free(*main_conf);
310        *main_conf=mapsFromJSObject(cx,tmp3);
311      }
[9]312    }
[383]313
[1]314  }
315  else{
[9]316#ifdef JS_DEBUG
[383]317    fprintf(stderr,"The service didn't return an array !\n");
[9]318#endif
[383]319    /**
320     * Extract result
321     */
[1]322    jsval tmp1;
[9]323    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
[1]324    res=JSVAL_TO_INT(tmp1);
325
[9]326#ifdef JS_DEBUG
[1]327    fprintf(stderr," * %d * \n",res);
[9]328#endif
[383]329    /**
330     * Extract outputs when available.
331     */
[1]332    jsval tmp2;
[9]333    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
[383]334    if(!JSVAL_IS_VOID(tmp2) && hasElement==JS_TRUE){
335      freeMaps(outputs);
336      free(*outputs);   
337      *outputs=mapsFromJSObject(cx,tmp2);
338    }
339    JS_MaybeGC(cx);
[274]340#ifdef JS_DEBUG
[383]341    if(JSVAL_IS_VOID(tmp2))
[1]342      fprintf(stderr,"No outputs property returned\n");
[383]343    else{
344      if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
345        fprintf(stderr,"outputs is an array as expected\n");
346      else
347        fprintf(stderr,"outputs is not an array as expected\n");
348    }
349    JS_MaybeGC(cx);
[274]350#endif
[383]351
352    /**
353     * Extract conf when available.
354     */
355    jsval tmp3;
356    JSBool hasConf=JS_GetProperty(cx,d,"conf",&tmp3);
357    if(!JSVAL_IS_VOID(tmp3) && hasConf==JS_TRUE){
358      freeMaps(main_conf);
359      free(*main_conf);
360      *main_conf=mapsFromJSObject(cx,tmp3);
361    }
362    JS_MaybeGC(cx);
363
[1]364#ifdef JS_DEBUG
[364]365    dumpMaps(*outputs);
[1]366#endif
367  }
368  /* Cleanup. */
[383]369  JS_MaybeGC(cx);
[274]370  JS_DestroyContext(cx);
[1]371  JS_DestroyRuntime(rt);
372  JS_ShutDown();
[471]373  free(filename);
[1]374#ifdef JS_DEBUG
375  fprintf(stderr,"Returned value %d\n",res);
376#endif
377  return res;
378}
379
[580]380/**
381 * Load a JavaScript file
382 *
383 * @param cx the JavaScript context
[586]384 * @param global the global JavaScript object (not used)
[580]385 * @param filename the file name to load
[781]386 * @return a JavaScript Object on success, NULL if an errro occurred
[580]387 */
[274]388JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
[42]389  struct stat api_status;
390  int s=stat(filename, &api_status);
391  if(s==0){
392    jsval rval;
[274]393    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
[42]394    if(script!=NULL){
[274]395      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
396#ifdef JS_DEBUG
[42]397      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
[274]398#endif
[42]399      return script;
400    }
[274]401#ifdef JS_DEBUG
[42]402    else
403      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
[274]404#endif
[42]405  }
[274]406#ifdef JS_DEBUG
[42]407  else
408    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
[274]409#endif
[42]410  return NULL;
411}
412
[580]413/**
414 * Convert a maps to a JavaScript Object
415 *
416 * @param cx the JavaScript context
417 * @param t the maps to convert
418 * @return a new JavaScript Object
419 */
[1]420JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
[328]421  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
[9]422  if(res==NULL)
423    fprintf(stderr,"Array Object is NULL!\n");
[1]424  maps* tmp=t;
425  while(tmp!=NULL){
426    JSObject *pval=JSObject_FromMap(cx,tmp->content);
[790]427    if(tmp->child!=NULL){
428      JSObject *pvalc=JSObject_FromMaps(cx,tmp->child);
429      jsval pvaljc=OBJECT_TO_JSVAL(pvalc);
430      JS_SetProperty(cx, pval, "child", &pvaljc);
431    }
[1]432    jsval pvalj=OBJECT_TO_JSVAL(pval);
[328]433    JS_SetProperty(cx, res, tmp->name, &pvalj);
[1]434#ifdef JS_DEBUG
435    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
436#endif
437    tmp=tmp->next;
438  } 
439  return res;
440}
441
[580]442/**
443 * Convert a map to a JavaScript Object
444 *
445 * @param cx the JavaScript context
446 * @param t the map to convert
447 * @return a new JavaScript Object
448 */
[1]449JSObject* JSObject_FromMap(JSContext *cx,map* t){
450  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
451  map* tmpm=t;
[360]452  map* isArray=getMap(t,"isArray");
453  map* isBinary=getMap(t,"size");
454  map* tmap=getMapType(t);
[403]455#ifdef JS_DEBUG
[360]456  if(tmap==NULL)
457    fprintf(stderr,"tmap is null !\n");
458  else
459    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
[364]460#endif
[640]461  while(isArray==NULL && tmpm!=NULL){
[410]462    jsval jsstr;
[752]463    if(isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0)
[410]464      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,atoi(isBinary->value)));
465    else
466      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
467    JS_SetProperty(cx, res, tmpm->name,&jsstr);
[1]468#ifdef JS_DEBUG
[410]469    fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
[1]470#endif
[410]471    tmpm=tmpm->next;
[1]472  }
[410]473  if(isArray!=NULL){
[360]474    map* len=getMap(t,"length");
475    int cnt=atoi(len->value);
476    JSObject* values=JS_NewArrayObject( cx, cnt, NULL );
477    JSObject* mvalues=JS_NewArrayObject( cx, cnt, NULL );
[752]478    map *tmpm1,*tmpm2,*tmpm3;
[360]479    int i=0;
480    for(i=0;i<cnt;i++){
481      tmpm1=getMapArray(t,"value",i);
482      tmpm2=getMapArray(t,tmap->name,i);
[752]483      tmpm3=getMapArray(t,"size",i);
[360]484      if(tmpm1!=NULL){
[752]485        jsval jsstr;
486        if(tmpm3!=NULL)
487          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,atoi(tmpm3->value)));
488        else
489          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,strlen(tmpm1->value)));
[360]490        JS_SetElement( cx, values, i, &jsstr );
491      }
492      if(tmpm2!=NULL){
493        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm2->value,strlen(tmpm2->value)));
494        JS_SetElement( cx, mvalues, i, &jsstr );
495      }
496    }
497    jsval jvalues=OBJECT_TO_JSVAL(values);
498    jsval jmvalues=OBJECT_TO_JSVAL(mvalues);
499    JS_SetProperty(cx, res,"value",&jvalues);
500    JS_SetProperty(cx, res,tmap->name,&jmvalues);
[752]501    while(tmpm!=NULL){
502      if(strncasecmp(tmpm->name,"value",5)!=0 && strncasecmp(tmpm->name,"size",4)!=0 && strncasecmp(tmpm->name,tmap->name,strlen(tmap->name))!=0){
503        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
504        JS_SetProperty(cx, res, tmpm->name,&jsstr);
505      }
506#ifdef JS_DEBUG
507      fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
508#endif
509      tmpm=tmpm->next;
510    }
[360]511  }
[1]512  return res;
513}
514
[580]515/**
516 * Convert a JavaScript Object to a maps
517 *
518 * @param cx the JavaScript context
519 * @param t the JavaScript Object to convert
520 * @return a new maps containing the JavaScript Object
521 */
[1]522maps* mapsFromJSObject(JSContext *cx,jsval t){
523  maps *res=NULL;
524  maps *tres=NULL;
[9]525  jsint oi=0;
526  JSObject* tt=JSVAL_TO_OBJECT(t);
[333]527  if(JS_IsArrayObject(cx,tt)){
[1]528#ifdef JS_DEBUG
529    fprintf(stderr,"Is finally an array !\n");
[333]530#endif
[1]531  }
[333]532  else{
533#ifdef JS_DEBUG
[1]534    fprintf(stderr,"Is not an array !\n");
535#endif
[333]536    JSIdArray *idp=JS_Enumerate(cx,tt);
537    if(idp!=NULL) {
538      int index;
539      jsdouble argNum;
540#ifdef JS_DEBUG
541      fprintf(stderr,"Properties length :  %d \n",idp->length);
542#endif
543     
544      for (index=0,argNum=idp->length;index<argNum;index++) { 
545        jsval id = idp->vector[index];
546        jsval vp;
547        JS_IdToValue(cx,id,&vp);
[640]548        char *tmp;
[333]549        JSString *jsmsg;
550        size_t len1;
551        jsmsg = JS_ValueToString(cx,vp);
552        len1 = JS_GetStringLength(jsmsg);
[471]553       
554        tmp=JS_EncodeString(cx,jsmsg);
[790]555        tres=createMaps(tmp);
[333]556
557        jsval nvp=JSVAL_NULL;
[471]558        if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
[333]559#ifdef JS_DEBUG
[471]560          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
[333]561#endif
562        }
[471]563        free(tmp);
[364]564        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
[333]565        JS_ValueToObject(cx,nvp,&nvp1);
566        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
567        if(JSVAL_IS_OBJECT(nvp1j)){
568          tres->content=mapFromJSObject(cx,nvp1j);
569        }
570
[790]571        jsval nvp0=JSVAL_NULL;
572        JSObject *nvp01=JSVAL_TO_OBJECT(JSVAL_NULL);
573        if((JS_GetProperty(cx, nvp1, "child", &nvp0)==JS_FALSE)){
574#ifdef JS_DEBUG
575          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
576#endif
577        }
578        JS_ValueToObject(cx,nvp0,&nvp01);
579        jsval nvp01j=OBJECT_TO_JSVAL(nvp01);
580        if(!JSVAL_IS_NULL(nvp01j)){
581          tres->child=mapsFromJSObject(cx,nvp01j);
582        }
583
[333]584        if(res==NULL)
585          res=dupMaps(&tres);
586        else
587          addMapsToMaps(&res,tres);
588        freeMaps(&tres);
589        free(tres);
590        tres=NULL;
591      }
[471]592      JS_DestroyIdArray(cx,idp);
[333]593    }
594  }
595
[364]596  jsuint len;
[9]597  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
[383]598#ifdef JS_DEBUG
[9]599  if(hasLen==JS_FALSE){
[1]600    fprintf(stderr,"outputs array is empty\n");
601  }
602  fprintf(stderr,"outputs array length : %d\n",len);
603#endif
[640]604  for(oi=0;hasLen && oi < len;oi++){
[1]605#ifdef JS_DEBUG
[9]606    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
[1]607#endif
608    jsval tmp1;
[9]609    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
610    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
611    JSIdArray *idp=JS_Enumerate(cx,otmp1);
[1]612    if(idp!=NULL) {
613      int index;
614      jsdouble argNum;
615#ifdef JS_DEBUG
616      fprintf(stderr,"Properties length :  %d \n",idp->length);
617#endif
[274]618      tres=(maps*)malloc(MAPS_SIZE);
619      tres->name=NULL;
620      tres->content=NULL;
621      tres->next=NULL;
622
[1]623      for (index=0,argNum=idp->length;index<argNum;index++) { 
[9]624        jsval id = idp->vector[index];
[1]625        jsval vp;
626        JS_IdToValue(cx,id,&vp);
[640]627        char *tmp;
[1]628        JSString *jsmsg;
629        size_t len1;
630        jsmsg = JS_ValueToString(cx,vp);
631        len1 = JS_GetStringLength(jsmsg);
[471]632        tmp=JS_EncodeString(cx,jsmsg);
[1]633#ifdef JS_DEBUG
[471]634        fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
[1]635#endif
[9]636        jsval nvp=JSVAL_NULL;
[471]637        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
[1]638#ifdef JS_DEBUG
[471]639          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
[1]640#endif
[274]641        }
[471]642        free(tmp);
[1]643        if(JSVAL_IS_OBJECT(nvp)){
644#ifdef JS_DEBUG
645          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
646#endif
647        }
[274]648
[364]649        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
[1]650        JS_ValueToObject(cx,nvp,&nvp1);
651        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
652        if(JSVAL_IS_OBJECT(nvp1j)){
[274]653          JSString *jsmsg1;
[471]654          char *tmp1, *tmp2;
[364]655          JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
[274]656          jsmsg1 = JS_ValueToString(cx,nvp1j);
657          len1 = JS_GetStringLength(jsmsg1);
[471]658          tmp1=JS_EncodeString(cx,jsmsg1);
659          tmp2=JS_EncodeString(cx,jsmsg);
[277]660#ifdef JS_DEBUG
[471]661          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
[277]662#endif
[471]663          if(strcasecmp(tmp1,"[object Object]")==0){
664            tres->name=zStrdup(tmp2);
[274]665            tres->content=mapFromJSObject(cx,nvp1j);
666          }
[1]667          else
[471]668            if(strcasecmp(tmp2,"name")==0){
669              tres->name=zStrdup(tmp1);
[274]670            }
671            else{
672              if(tres->content==NULL)
[471]673                tres->content=createMap(tmp2,tmp1);
[274]674              else
[471]675                addToMap(tres->content,tmp2,tmp1);
[274]676            }
[471]677          free(tmp1);
678          free(tmp2);
[1]679        }
680#ifdef JS_DEBUG
681        else
682          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
683#endif
684      }
[277]685#ifdef JS_DEBUG
[274]686      dumpMaps(tres);
[277]687#endif
[274]688      if(res==NULL)
689        res=dupMaps(&tres);
690      else
691        addMapsToMaps(&res,tres);
692      freeMaps(&tres);
693      free(tres);
694      tres=NULL;
[471]695      JS_DestroyIdArray(cx,idp);
[1]696    }
697  }
[277]698#ifdef JS_DEBUG
[1]699  dumpMaps(res);
[277]700#endif
[1]701  return res;
702}
703
[580]704/**
705 * Convert a JavaScript Object to a map
706 *
707 * @param cx the JavaScript context
708 * @param t the JavaScript Object to convert
709 * @return a new map containing the JavaScript Object
710 */
[1]711map* mapFromJSObject(JSContext *cx,jsval t){
712  map *res=NULL;
[9]713  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
[1]714#ifdef JS_DEBUG
715  fprintf(stderr,"Properties %p\n",(void*)t);
716#endif
717  if(idp!=NULL) {
718    int index;
719    jsdouble argNum;
720#ifdef JS_DEBUG
721    fprintf(stderr,"Properties length :  %d \n",idp->length);
722#endif
723    for (index=0,argNum=idp->length;index<argNum;index++) { 
[9]724      jsval id = idp->vector[index];
[1]725      jsval vp;
726      JS_IdToValue(cx,id,&vp);
[640]727      char *tmp, *tmp1;
[1]728      JSString *jsmsg,*jsmsg1;
729      size_t len,len1;
730      jsmsg = JS_ValueToString(cx,vp);
731      len = JS_GetStringLength(jsmsg);
732      jsval nvp;
[471]733      tmp=JS_EncodeString(cx,jsmsg);
734      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
[1]735      jsmsg1 = JS_ValueToString(cx,nvp);
736      len1 = JS_GetStringLength(jsmsg1);
[471]737      tmp1=JS_EncodeString(cx,jsmsg1);
[1]738#ifdef JS_DEBUG
[471]739      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
[1]740#endif
[790]741      if(strcasecmp(tmp,"child")!=0){
742        if(res!=NULL){
[26]743#ifdef JS_DEBUG
[790]744          fprintf(stderr,"%s - %s\n",tmp,tmp1);
[26]745#endif
[790]746          addToMap(res,tmp,tmp1);
747        }
748        else{
749          res=createMap(tmp,tmp1);
750          res->next=NULL;
751        }
[9]752      }
[471]753      free(tmp);
754      free(tmp1);
[26]755#ifdef JS_DEBUG
[9]756      dumpMap(res);
[26]757#endif
[1]758    }
[471]759    JS_DestroyIdArray(cx,idp);
[1]760  }
761#ifdef JS_DEBUG
762  dumpMap(res);
763#endif
764  return res;
765}
766
[580]767/**
768 * Print debug information messages on stderr
769 *
770 * @param cx the JavaScript context
771 * @param message the error message
772 * @param report the JavaScript Error Report
773 */
[1]774void reportError(JSContext *cx, const char *message, JSErrorReport *report)
775{
776  sprintf(dbg,"%s:%u:%s\n",
777          report->filename ? report->filename : "<no filename>",
778          (unsigned int) report->lineno,
779          message);
780#ifdef JS_DEBUG
781  fprintf(stderr,"%s",dbg);
782#endif
783  fflush(stderr);
784}
785
[580]786/**
787 * Convert a JavaScript value to a char*
788 *
789 * @param context the JavaScript context
790 * @param arg the JavaScript value
791 * @return a new char*
[781]792 * @warning be sure to free the resources returned by this function
[580]793 */
[368]794char* JSValToChar(JSContext* context, jsval* arg) {
795  char *c;
796  char *tmp;
797  JSString *jsmsg;
798  size_t len;
799  int i;
800  if(!JSVAL_IS_STRING(*arg)) {
801    return NULL;
802  }
803  jsmsg = JS_ValueToString(context,*arg);
804  len = JS_GetStringLength(jsmsg);
805  tmp = JS_EncodeString(context,jsmsg);
806  c = (char*)malloc((len+1)*sizeof(char));
807  c[len] = '\0';
808#ifdef ULINET_DEBUG
809  fprintf(stderr,"%d \n",len);
810#endif
811  for(i = 0;i < len;i++) {
812    c[i] = tmp[i];
813    c[i+1] = 0;
814  }
815#ifdef ULINET_DEBUG
816  fprintf(stderr,"%s \n",c);
817#endif
818  return c;
819}
820
[580]821/**
822 * Set the HTTP header of a request
823 *
824 * @param handle the HINTERNET handle
825 * @param cx the JavaScript context
826 * @param header the JavaScript Array containing the headers to send
827 * @return the HINTERNET handle
828 */
[492]829HINTERNET setHeader(HINTERNET* handle,JSContext *cx,JSObject *header){
[368]830  jsuint length=0;
831  jsint i=0;
832  char *tmp1;
833#ifdef ULINET_DEBUG
834  fprintf(stderr,"setHeader\n");
835#endif
836  if(JS_IsArrayObject(cx,header)){
837#ifdef ULINET_DEBUG
838    fprintf(stderr,"header is an array\n");
839#endif
840    JS_GetArrayLength(cx,header,&length);
841#ifdef ULINET_DEBUG
842    fprintf(stderr,"header is an array of %d elements\n",length);
843#endif
[492]844    handle->ihandle[handle->nb].header=NULL;
[368]845    for(i=0;i<length;i++){
846      jsval tmp;
847      JS_GetElement(cx,header,i,&tmp);
848      tmp1=JSValToChar(cx,&tmp);
849#ifdef ULINET_DEBUG
[492]850      curl_easy_setopt(handle->ihandle[handle->nb].handle,CURLOPT_VERBOSE,1);
[368]851      fprintf(stderr,"Element of array n° %d, value : %s\n",i,tmp1);
852#endif
[492]853      handle->ihandle[handle->nb].header=curl_slist_append(handle->ihandle[handle->nb].header, tmp1);
[368]854      free(tmp1);
855    }
856  }
857  else{
858    fprintf(stderr,"not an array !!!!!!!\n");
859  }
[492]860  return *handle;
[368]861}
862
[580]863/**
864 * The function used as ZOOTranslate from the JavaScript environment.
865 * Use the ZOO-Services messages translation function from the Python
866 * environment (ZOO-API)
867 *
868 * @param cx the JavaScript context
869 * @param argc the number of parameters
870 * @param argv1 the parameter values
871 * @return true
872 */
[368]873JSBool
[377]874JSTranslate(JSContext *cx, uintN argc, jsval *argv1)
875{
876  jsval *argv = JS_ARGV(cx,argv1);
877  char *str=JSValToChar(cx,&argv[0]);
878  char *tmpValue=_ss(str);
879  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue)))); 
880  JS_MaybeGC(cx);
881  return JS_TRUE;
882}
883
[580]884/**
885 * The function used as ZOORequest from the JavaScript environment (ZOO-API)
886 *
887 * @param cx the JavaScript context
888 * @param argc the number of parameters
889 * @param argv1 the parameter values
890 * @return true
891 * @see setHeader
892 */
[377]893JSBool
[368]894JSRequest(JSContext *cx, uintN argc, jsval *argv1)
895{
896  jsval *argv = JS_ARGV(cx,argv1);
897  HINTERNET hInternet;
898  JSObject *header;
899  char *url;
900  char *method;
901  char* tmpValue;
902  size_t dwRead;
903  JS_MaybeGC(cx);
904  hInternet=InternetOpen("ZooWPSClient\0",
905                         INTERNET_OPEN_TYPE_PRECONFIG,
906                         NULL,NULL, 0);
907  if(!CHECK_INET_HANDLE(hInternet))
908    return JS_FALSE;
909  if(argc>=2){
910    method=JSValToChar(cx,&argv[0]);
911    url=JSValToChar(cx,&argv[1]);
912  }
913  else{
[453]914    method=zStrdup("GET");
[368]915    url=JSValToChar(cx,argv);
916  }
[492]917  hInternet.waitingRequests[hInternet.nb]=strdup(url);
[368]918  if(argc==4){
919    char *body;
920    body=JSValToChar(cx,&argv[2]);
921    header=JSVAL_TO_OBJECT(argv[3]);
922#ifdef ULINET_DEBUG
923    fprintf(stderr,"URL (%s) \nBODY (%s)\n",url,body);
924#endif
925    if(JS_IsArrayObject(cx,header))
[492]926      setHeader(&hInternet,cx,header);
[368]927#ifdef ULINET_DEBUG
928    fprintf(stderr,"BODY (%s)\n",body);
929#endif
[492]930    InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
931                    INTERNET_FLAG_NO_CACHE_WRITE,0);   
932    processDownloads(&hInternet);
[368]933    free(body);
934  }else{
935    if(argc==3){
[828]936      if(strncasecmp(method,"GET",3)==0){
937        header=JSVAL_TO_OBJECT(argv[2]);
938        if(JS_IsArrayObject(cx,header)){
939          setHeader(&hInternet,cx,header);
940        }
941        InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
942                        INTERNET_FLAG_NO_CACHE_WRITE,0);
943        processDownloads(&hInternet);
944      }else{
945        char *body=JSValToChar(cx,&argv[2]);
946        InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
947                        INTERNET_FLAG_NO_CACHE_WRITE,0);
948        processDownloads(&hInternet);
949        free(body);
950      }
[492]951    }else{
952      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
953                      INTERNET_FLAG_NO_CACHE_WRITE,0);
954      processDownloads(&hInternet);
[368]955    }
956  }
[492]957  tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
958  InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
[368]959#ifdef ULINET_DEBUG
960  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
961#endif
962  if(dwRead==0){
963    JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,"Unable to access the file.",strlen("Unable to access the file."))));
964    return JS_TRUE;
965  }
966
967#ifdef ULINET_DEBUG
968  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
969#endif
970  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue))));
971  free(url);
972  if(argc>=2)
973    free(method);
[492]974  InternetCloseHandle(&hInternet);
[368]975  JS_MaybeGC(cx);
976  return JS_TRUE;
977}
[580]978
979/**
980 * The function used as ZOOUpdateStatus from the JavaScript environment
981 * (ZOO-API).
982 *
983 * @param cx the JavaScript context
984 * @param argc the number of parameters
985 * @param argv1 the parameter values
986 * @return true
[581]987 * @see setHeader,_updateStatus
[580]988 */
989JSBool
990JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
991{
992  jsval *argv = JS_ARGV(cx,argv1);
993  JS_MaybeGC(cx);
994  int istatus=0;
995  char *status=NULL;
996  maps *conf;
997  if(argc>2){
998#ifdef JS_DEBUG
999    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
1000#endif
1001    return JS_FALSE;
1002  }
1003  conf=mapsFromJSObject(cx,argv[0]);
1004  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
1005    char tmpStatus[4];
1006    sprintf(tmpStatus,"%i",istatus);
1007    tmpStatus[3]=0;
1008    status=strdup(tmpStatus);
1009  }
1010  if(getMapFromMaps(conf,"lenv","status")!=NULL){
1011    if(status!=NULL){
1012      setMapInMaps(conf,"lenv","status",status);
1013      free(status);
1014    }
1015    else
1016      setMapInMaps(conf,"lenv","status","15");
1017    _updateStatus(conf);
1018  }
1019  freeMaps(&conf);
1020  free(conf);
1021  JS_MaybeGC(cx);
1022  return JS_TRUE;
1023}
1024
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