source: branches/prototype-v0/zoo-project/zoo-kernel/service_internal_js.c @ 839

Last change on this file since 839 was 839, checked in by djay, 7 years ago

Update the source code for HPC support. Automatically adding nested outputs for the HPC support (should this be available for every support?). Add capability to store the metadata in the Collection DataBase?. Addition of the zcfg2sql to import any existing ZCFG file into the Collection DB. Add the support to invoke a callback (for history purpose) in case a [callback] section contains at least one parameter defined (url). Add support to convert maps and map to JSON (for callback use only by now). Fix some memory leaks (some are still there).

  • 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){
[839]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