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
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2012 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal_js.h"
26#include "response_print.h"
27
28#ifndef JSCLASS_GLOBAL_FLAGS
29#define JSCLSAS_GLOBAL_FLAGS 0
30#endif
31
32static char dbg[1024];
33
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 */
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]);
50    char *tmp=JS_EncodeString(cx,jsmsg);
51    fprintf(stderr,"[ZOO-API:JS] %s\n",tmp);
52    free(tmp);
53  }
54  JS_MaybeGC(cx);
55 
56  return JS_TRUE;
57}
58
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 */
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);
79    fflush(stderr);
80#endif
81    JSObject *api_script1=loadZooApiFile(cx,JS_GetGlobalObject(cx),filename);
82  }
83  JS_MaybeGC(cx);
84  JS_SET_RVAL(cx, argv1, JSVAL_VOID);
85 
86  return JS_TRUE;
87}
88
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
99 * @return SERVICE_SUCCEEDED or SERVICE_FAILED if the service run, -1
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)
103{
104  /*maps* main=*main_conf;
105  maps* _inputs=*inputs;
106  maps* _outputs=*outputs;*/
107
108  /* The class of the global object. */
109  JSClass global_class= {
110    "global", JSCLASS_GLOBAL_FLAGS,
111    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
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;
125 
126  /* Create a context. */
127  cx = JS_NewContext(rt,8192);
128  if (cx == NULL){
129    return 1;
130  }
131  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
132  JS_SetVersion(cx, JSVERSION_LATEST);
133  JS_SetErrorReporter(cx, reportError);
134
135  /* Create the global object. */
136  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
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  }
143
144  /* Define specific function and global variable to share with JS runtime
145   */
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;
152  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
153    return 1;
154  if (!JS_DefineFunction(cx, global, "ZOOTranslate", JSTranslate, 4, 0))
155    return 1;
156  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
157    return 1;
158  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
159    return 1; 
160  if (!JS_DefineFunction(cx, global, "importScripts", JSLoadScripts, 1, 0))
161    return 1;
162
163  /**
164   * Add private context object
165   */
166  void* cxPrivate = request;
167  JS_SetContextPrivate(cx,cxPrivate);
168
169  map* tmpm1=getMap(request,"metapath");
170  char ntmp[1024];
171  map* cwdMap=getMapFromMaps(*main_conf,"main","servicePath");
172  if(cwdMap!=NULL)
173    sprintf(ntmp,"%s",cwdMap->value);
174  else
175    getcwd(ntmp,1024);
176
177  /**
178   * Load the first part of the ZOO-API
179   */
180  char *api0=(char*)malloc((strlen(ntmp)+17)*sizeof(char));
181  sprintf(api0,"%s/ZOO-proj4js.js",ntmp);
182#ifdef JS_DEBUG
183  fprintf(stderr,"Trying to load %s\n",api0);
184#endif
185  JSObject *api_script1=loadZooApiFile(cx,global,api0);
186  free(api0);
187  fflush(stderr);
188
189  char *api1=(char*)malloc((strlen(ntmp)+13)*sizeof(char));
190  sprintf(api1,"%s/ZOO-api.js",ntmp);
191#ifdef JS_DEBUG
192  fprintf(stderr,"Trying to load %s\n",api1);
193#endif
194  JSObject *api_script2=loadZooApiFile(cx,global,api1);
195  free(api1);
196  fflush(stderr);
197
198  /* Your application code here. This may include JSAPI calls
199     to create your own custom JS objects and run scripts. */
200  //maps* out=*outputs;
201  int res=SERVICE_FAILED;
202  //maps* mc=*main_conf;
203  map* tmpm2=getMap(s->content,"serviceProvider");
204
205  char *filename=(char*)malloc(strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+3);
206  sprintf(filename,"%s/%s/%s",ntmp,tmpm1->value,tmpm2->value);
207  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2]=0;
208#ifdef JS_DEBUG
209  fprintf(stderr,"FILENAME %s\n",filename);
210#endif
211  struct stat file_status;
212  stat(filename, &file_status);
213  //char *source=(char*)malloc(file_status.st_size);
214  //uint16 lineno;
215  jsval rval;
216  JSBool ok ;
217  JSObject *script = JS_CompileFile(cx, global, filename);
218  if(script!=NULL){
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);
224    free(filename);
225    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
226    JS_MaybeGC(cx);
227    JS_DestroyContext(cx);
228    JS_DestroyRuntime(rt);
229    JS_ShutDown();
230    return -1;
231  }
232 
233
234  /* Call a function in obj's scope. */
235  jsval argv[3];
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;
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;
254  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
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];
263    if(strlen(dbg)==0)
264      sprintf(dbg,"No result was found after the function call");
265    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
266#ifdef JS_DEBUG
267    fprintf(stderr,"%s",tmp1);
268#endif
269    errorException(*main_conf,tmp1,"NoApplicableCode",NULL);
270    free(filename);
271    JS_MaybeGC(cx);
272    JS_DestroyContext(cx);
273    JS_DestroyRuntime(rt);
274    JS_ShutDown();
275    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
276    return -1;
277  }
278
279  //jsval t=OBJECT_TO_JSVAL(d);
280  if(JS_IsArrayObject(cx,d)){
281#ifdef JS_DEBUG
282    fprintf(stderr,"An array was returned !\n");
283#endif
284    jsuint       len;
285    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
286#ifdef JS_DEBUG
287      fprintf(stderr,"outputs array is empty\n");
288#endif
289    }
290    jsval tmp1;
291    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
292    res=JSVAL_TO_INT(tmp1);
293#ifdef JS_DEBUG
294    fprintf(stderr," * %d * \n",res);
295#endif
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      }
312    }
313
314  }
315  else{
316#ifdef JS_DEBUG
317    fprintf(stderr,"The service didn't return an array !\n");
318#endif
319    /**
320     * Extract result
321     */
322    jsval tmp1;
323    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
324    res=JSVAL_TO_INT(tmp1);
325
326#ifdef JS_DEBUG
327    fprintf(stderr," * %d * \n",res);
328#endif
329    /**
330     * Extract outputs when available.
331     */
332    jsval tmp2;
333    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
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);
340#ifdef JS_DEBUG
341    if(JSVAL_IS_VOID(tmp2))
342      fprintf(stderr,"No outputs property returned\n");
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);
350#endif
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
364#ifdef JS_DEBUG
365    dumpMaps(*outputs);
366#endif
367  }
368  /* Cleanup. */
369  JS_MaybeGC(cx);
370  JS_DestroyContext(cx);
371  JS_DestroyRuntime(rt);
372  JS_ShutDown();
373  free(filename);
374#ifdef JS_DEBUG
375  fprintf(stderr,"Returned value %d\n",res);
376#endif
377  return res;
378}
379
380/**
381 * Load a JavaScript file
382 *
383 * @param cx the JavaScript context
384 * @param global the global JavaScript object (not used)
385 * @param filename the file name to load
386 * @return a JavaScript Object on success, NULL if an errro occurred
387 */
388JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
389  struct stat api_status;
390  int s=stat(filename, &api_status);
391  if(s==0){
392    jsval rval;
393    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
394    if(script!=NULL){
395      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
396#ifdef JS_DEBUG
397      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
398#endif
399      return script;
400    }
401#ifdef JS_DEBUG
402    else
403      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
404#endif
405  }
406#ifdef JS_DEBUG
407  else
408    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
409#endif
410  return NULL;
411}
412
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 */
420JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
421  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
422  if(res==NULL)
423    fprintf(stderr,"Array Object is NULL!\n");
424  maps* tmp=t;
425  while(tmp!=NULL){
426    JSObject *pval=JSObject_FromMap(cx,tmp->content);
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    }
432    jsval pvalj=OBJECT_TO_JSVAL(pval);
433    JS_SetProperty(cx, res, tmp->name, &pvalj);
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
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 */
449JSObject* JSObject_FromMap(JSContext *cx,map* t){
450  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
451  map* tmpm=t;
452  map* isArray=getMap(t,"isArray");
453  map* isBinary=getMap(t,"size");
454  map* tmap=getMapType(t);
455#ifdef JS_DEBUG
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);
460#endif
461  while(isArray==NULL && tmpm!=NULL){
462    jsval jsstr;
463    if(isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0)
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);
468#ifdef JS_DEBUG
469    fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
470#endif
471    tmpm=tmpm->next;
472  }
473  if(isArray!=NULL){
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 );
478    map *tmpm1,*tmpm2,*tmpm3;
479    int i=0;
480    for(i=0;i<cnt;i++){
481      tmpm1=getMapArray(t,"value",i);
482      tmpm2=getMapArray(t,tmap->name,i);
483      tmpm3=getMapArray(t,"size",i);
484      if(tmpm1!=NULL){
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)));
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);
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    }
511  }
512  return res;
513}
514
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 */
522maps* mapsFromJSObject(JSContext *cx,jsval t){
523  maps *res=NULL;
524  maps *tres=NULL;
525  jsint oi=0;
526  JSObject* tt=JSVAL_TO_OBJECT(t);
527  if(JS_IsArrayObject(cx,tt)){
528#ifdef JS_DEBUG
529    fprintf(stderr,"Is finally an array !\n");
530#endif
531  }
532  else{
533#ifdef JS_DEBUG
534    fprintf(stderr,"Is not an array !\n");
535#endif
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);
548        char *tmp;
549        JSString *jsmsg;
550        size_t len1;
551        jsmsg = JS_ValueToString(cx,vp);
552        len1 = JS_GetStringLength(jsmsg);
553       
554        tmp=JS_EncodeString(cx,jsmsg);
555        tres=createMaps(tmp);
556
557        jsval nvp=JSVAL_NULL;
558        if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
559#ifdef JS_DEBUG
560          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
561#endif
562        }
563        free(tmp);
564        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
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
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
584        if(res==NULL)
585          res=dupMaps(&tres);
586        else
587          addMapsToMaps(&res,tres);
588        freeMaps(&tres);
589        free(tres);
590        tres=NULL;
591      }
592      JS_DestroyIdArray(cx,idp);
593    }
594  }
595
596  jsuint len;
597  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
598#ifdef JS_DEBUG
599  if(hasLen==JS_FALSE){
600    fprintf(stderr,"outputs array is empty\n");
601  }
602  fprintf(stderr,"outputs array length : %d\n",len);
603#endif
604  for(oi=0;hasLen && oi < len;oi++){
605#ifdef JS_DEBUG
606    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
607#endif
608    jsval tmp1;
609    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
610    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
611    JSIdArray *idp=JS_Enumerate(cx,otmp1);
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
618      tres=(maps*)malloc(MAPS_SIZE);
619      tres->name=NULL;
620      tres->content=NULL;
621      tres->next=NULL;
622
623      for (index=0,argNum=idp->length;index<argNum;index++) { 
624        jsval id = idp->vector[index];
625        jsval vp;
626        JS_IdToValue(cx,id,&vp);
627        char *tmp;
628        JSString *jsmsg;
629        size_t len1;
630        jsmsg = JS_ValueToString(cx,vp);
631        len1 = JS_GetStringLength(jsmsg);
632        tmp=JS_EncodeString(cx,jsmsg);
633#ifdef JS_DEBUG
634        fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
635#endif
636        jsval nvp=JSVAL_NULL;
637        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
638#ifdef JS_DEBUG
639          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
640#endif
641        }
642        free(tmp);
643        if(JSVAL_IS_OBJECT(nvp)){
644#ifdef JS_DEBUG
645          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
646#endif
647        }
648
649        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
650        JS_ValueToObject(cx,nvp,&nvp1);
651        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
652        if(JSVAL_IS_OBJECT(nvp1j)){
653          JSString *jsmsg1;
654          char *tmp1, *tmp2;
655          JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
656          jsmsg1 = JS_ValueToString(cx,nvp1j);
657          len1 = JS_GetStringLength(jsmsg1);
658          tmp1=JS_EncodeString(cx,jsmsg1);
659          tmp2=JS_EncodeString(cx,jsmsg);
660#ifdef JS_DEBUG
661          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
662#endif
663          if(strcasecmp(tmp1,"[object Object]")==0){
664            tres->name=zStrdup(tmp2);
665            tres->content=mapFromJSObject(cx,nvp1j);
666          }
667          else
668            if(strcasecmp(tmp2,"name")==0){
669              tres->name=zStrdup(tmp1);
670            }
671            else{
672              if(tres->content==NULL)
673                tres->content=createMap(tmp2,tmp1);
674              else
675                addToMap(tres->content,tmp2,tmp1);
676            }
677          free(tmp1);
678          free(tmp2);
679        }
680#ifdef JS_DEBUG
681        else
682          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
683#endif
684      }
685#ifdef JS_DEBUG
686      dumpMaps(tres);
687#endif
688      if(res==NULL)
689        res=dupMaps(&tres);
690      else
691        addMapsToMaps(&res,tres);
692      freeMaps(&tres);
693      free(tres);
694      tres=NULL;
695      JS_DestroyIdArray(cx,idp);
696    }
697  }
698#ifdef JS_DEBUG
699  dumpMaps(res);
700#endif
701  return res;
702}
703
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 */
711map* mapFromJSObject(JSContext *cx,jsval t){
712  map *res=NULL;
713  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
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++) { 
724      jsval id = idp->vector[index];
725      jsval vp;
726      JS_IdToValue(cx,id,&vp);
727      char *tmp, *tmp1;
728      JSString *jsmsg,*jsmsg1;
729      size_t len,len1;
730      jsmsg = JS_ValueToString(cx,vp);
731      len = JS_GetStringLength(jsmsg);
732      jsval nvp;
733      tmp=JS_EncodeString(cx,jsmsg);
734      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
735      jsmsg1 = JS_ValueToString(cx,nvp);
736      len1 = JS_GetStringLength(jsmsg1);
737      tmp1=JS_EncodeString(cx,jsmsg1);
738#ifdef JS_DEBUG
739      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
740#endif
741      if(strcasecmp(tmp,"child")!=0){
742        if(res!=NULL){
743#ifdef JS_DEBUG
744          fprintf(stderr,"%s - %s\n",tmp,tmp1);
745#endif
746          addToMap(res,tmp,tmp1);
747        }
748        else{
749          res=createMap(tmp,tmp1);
750          res->next=NULL;
751        }
752      }
753      free(tmp);
754      free(tmp1);
755#ifdef JS_DEBUG
756      dumpMap(res);
757#endif
758    }
759    JS_DestroyIdArray(cx,idp);
760  }
761#ifdef JS_DEBUG
762  dumpMap(res);
763#endif
764  return res;
765}
766
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 */
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
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*
792 * @warning be sure to free the resources returned by this function
793 */
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
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 */
829HINTERNET setHeader(HINTERNET* handle,JSContext *cx,JSObject *header){
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
844    handle->ihandle[handle->nb].header=NULL;
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
850      curl_easy_setopt(handle->ihandle[handle->nb].handle,CURLOPT_VERBOSE,1);
851      fprintf(stderr,"Element of array n° %d, value : %s\n",i,tmp1);
852#endif
853      handle->ihandle[handle->nb].header=curl_slist_append(handle->ihandle[handle->nb].header, tmp1);
854      free(tmp1);
855    }
856  }
857  else{
858    fprintf(stderr,"not an array !!!!!!!\n");
859  }
860  return *handle;
861}
862
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 */
873JSBool
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
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 */
893JSBool
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{
914    method=zStrdup("GET");
915    url=JSValToChar(cx,argv);
916  }
917  hInternet.waitingRequests[hInternet.nb]=strdup(url);
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))
926      setHeader(&hInternet,cx,header);
927#ifdef ULINET_DEBUG
928    fprintf(stderr,"BODY (%s)\n",body);
929#endif
930    InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
931                    INTERNET_FLAG_NO_CACHE_WRITE,0);   
932    processDownloads(&hInternet);
933    free(body);
934  }else{
935    if(argc==3){
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      }
951    }else{
952      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
953                      INTERNET_FLAG_NO_CACHE_WRITE,0);
954      processDownloads(&hInternet);
955    }
956  }
957  tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
958  InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
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);
974  InternetCloseHandle(&hInternet);
975  JS_MaybeGC(cx);
976  return JS_TRUE;
977}
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
987 * @see setHeader,_updateStatus
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