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

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

Give the capability to store the main.cfg file in sysconfdir and the services in servicePath if defined in the [main] section.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 26.5 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    jsval pvalj=OBJECT_TO_JSVAL(pval);
428    JS_SetProperty(cx, res, tmp->name, &pvalj);
429#ifdef JS_DEBUG
430    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
431#endif
432    tmp=tmp->next;
433  } 
434  return res;
435}
436
437/**
438 * Convert a map to a JavaScript Object
439 *
440 * @param cx the JavaScript context
441 * @param t the map to convert
442 * @return a new JavaScript Object
443 */
444JSObject* JSObject_FromMap(JSContext *cx,map* t){
445  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
446  map* tmpm=t;
447  map* isArray=getMap(t,"isArray");
448  map* isBinary=getMap(t,"size");
449  map* tmap=getMapType(t);
450#ifdef JS_DEBUG
451  if(tmap==NULL)
452    fprintf(stderr,"tmap is null !\n");
453  else
454    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
455#endif
456  while(isArray==NULL && tmpm!=NULL){
457    jsval jsstr;
458    if(isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0)
459      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,atoi(isBinary->value)));
460    else
461      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
462    JS_SetProperty(cx, res, tmpm->name,&jsstr);
463#ifdef JS_DEBUG
464    fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
465#endif
466    tmpm=tmpm->next;
467  }
468  if(isArray!=NULL){
469    map* len=getMap(t,"length");
470    int cnt=atoi(len->value);
471    JSObject* values=JS_NewArrayObject( cx, cnt, NULL );
472    JSObject* mvalues=JS_NewArrayObject( cx, cnt, NULL );
473    map *tmpm1,*tmpm2,*tmpm3;
474    int i=0;
475    for(i=0;i<cnt;i++){
476      tmpm1=getMapArray(t,"value",i);
477      tmpm2=getMapArray(t,tmap->name,i);
478      tmpm3=getMapArray(t,"size",i);
479      if(tmpm1!=NULL){
480        jsval jsstr;
481        if(tmpm3!=NULL)
482          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,atoi(tmpm3->value)));
483        else
484          jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,strlen(tmpm1->value)));
485        JS_SetElement( cx, values, i, &jsstr );
486      }
487      if(tmpm2!=NULL){
488        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm2->value,strlen(tmpm2->value)));
489        JS_SetElement( cx, mvalues, i, &jsstr );
490      }
491    }
492    jsval jvalues=OBJECT_TO_JSVAL(values);
493    jsval jmvalues=OBJECT_TO_JSVAL(mvalues);
494    JS_SetProperty(cx, res,"value",&jvalues);
495    JS_SetProperty(cx, res,tmap->name,&jmvalues);
496    while(tmpm!=NULL){
497      if(strncasecmp(tmpm->name,"value",5)!=0 && strncasecmp(tmpm->name,"size",4)!=0 && strncasecmp(tmpm->name,tmap->name,strlen(tmap->name))!=0){
498        jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
499        JS_SetProperty(cx, res, tmpm->name,&jsstr);
500      }
501#ifdef JS_DEBUG
502      fprintf(stderr,"[JS] %s => %s\n",tmpm->name,tmpm->value);
503#endif
504      tmpm=tmpm->next;
505    }
506  }
507  return res;
508}
509
510/**
511 * Convert a JavaScript Object to a maps
512 *
513 * @param cx the JavaScript context
514 * @param t the JavaScript Object to convert
515 * @return a new maps containing the JavaScript Object
516 */
517maps* mapsFromJSObject(JSContext *cx,jsval t){
518  maps *res=NULL;
519  maps *tres=NULL;
520  jsint oi=0;
521  JSObject* tt=JSVAL_TO_OBJECT(t);
522  if(JS_IsArrayObject(cx,tt)){
523#ifdef JS_DEBUG
524    fprintf(stderr,"Is finally an array !\n");
525#endif
526  }
527  else{
528#ifdef JS_DEBUG
529    fprintf(stderr,"Is not an array !\n");
530#endif
531    JSIdArray *idp=JS_Enumerate(cx,tt);
532    if(idp!=NULL) {
533      int index;
534      jsdouble argNum;
535#ifdef JS_DEBUG
536      fprintf(stderr,"Properties length :  %d \n",idp->length);
537#endif
538     
539      for (index=0,argNum=idp->length;index<argNum;index++) { 
540        jsval id = idp->vector[index];
541        jsval vp;
542        JS_IdToValue(cx,id,&vp);
543        char *tmp;
544        JSString *jsmsg;
545        size_t len1;
546        jsmsg = JS_ValueToString(cx,vp);
547        len1 = JS_GetStringLength(jsmsg);
548       
549        tmp=JS_EncodeString(cx,jsmsg);
550        tres=(maps*)malloc(MAPS_SIZE);
551        tres->name=zStrdup(tmp);
552        tres->content=NULL;
553        tres->next=NULL;
554
555        jsval nvp=JSVAL_NULL;
556        if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
557#ifdef JS_DEBUG
558          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
559#endif
560        }
561        free(tmp);
562        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
563        JS_ValueToObject(cx,nvp,&nvp1);
564        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
565        if(JSVAL_IS_OBJECT(nvp1j)){
566          tres->content=mapFromJSObject(cx,nvp1j);
567        }
568
569        if(res==NULL)
570          res=dupMaps(&tres);
571        else
572          addMapsToMaps(&res,tres);
573        freeMaps(&tres);
574        free(tres);
575        tres=NULL;
576               
577      }
578      JS_DestroyIdArray(cx,idp);
579    }
580  }
581
582  jsuint len;
583  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
584#ifdef JS_DEBUG
585  if(hasLen==JS_FALSE){
586    fprintf(stderr,"outputs array is empty\n");
587  }
588  fprintf(stderr,"outputs array length : %d\n",len);
589#endif
590  for(oi=0;hasLen && oi < len;oi++){
591#ifdef JS_DEBUG
592    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
593#endif
594    jsval tmp1;
595    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
596    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
597    JSIdArray *idp=JS_Enumerate(cx,otmp1);
598    if(idp!=NULL) {
599      int index;
600      jsdouble argNum;
601#ifdef JS_DEBUG
602      fprintf(stderr,"Properties length :  %d \n",idp->length);
603#endif
604      tres=(maps*)malloc(MAPS_SIZE);
605      tres->name=NULL;
606      tres->content=NULL;
607      tres->next=NULL;
608
609      for (index=0,argNum=idp->length;index<argNum;index++) { 
610        jsval id = idp->vector[index];
611        jsval vp;
612        JS_IdToValue(cx,id,&vp);
613        char *tmp;
614        JSString *jsmsg;
615        size_t len1;
616        jsmsg = JS_ValueToString(cx,vp);
617        len1 = JS_GetStringLength(jsmsg);
618        tmp=JS_EncodeString(cx,jsmsg);
619#ifdef JS_DEBUG
620        fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
621#endif
622        jsval nvp=JSVAL_NULL;
623        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
624#ifdef JS_DEBUG
625          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
626#endif
627        }
628        free(tmp);
629        if(JSVAL_IS_OBJECT(nvp)){
630#ifdef JS_DEBUG
631          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
632#endif
633        }
634
635        JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
636        JS_ValueToObject(cx,nvp,&nvp1);
637        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
638        if(JSVAL_IS_OBJECT(nvp1j)){
639          JSString *jsmsg1;
640          char *tmp1, *tmp2;
641          JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
642          jsmsg1 = JS_ValueToString(cx,nvp1j);
643          len1 = JS_GetStringLength(jsmsg1);
644          tmp1=JS_EncodeString(cx,jsmsg1);
645          tmp2=JS_EncodeString(cx,jsmsg);
646#ifdef JS_DEBUG
647          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
648#endif
649          if(strcasecmp(tmp1,"[object Object]")==0){
650            tres->name=zStrdup(tmp2);
651            tres->content=mapFromJSObject(cx,nvp1j);
652          }
653          else
654            if(strcasecmp(tmp2,"name")==0){
655              tres->name=zStrdup(tmp1);
656            }
657            else{
658              if(tres->content==NULL)
659                tres->content=createMap(tmp2,tmp1);
660              else
661                addToMap(tres->content,tmp2,tmp1);
662            }
663          free(tmp1);
664          free(tmp2);
665        }
666#ifdef JS_DEBUG
667        else
668          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
669#endif
670      }
671#ifdef JS_DEBUG
672      dumpMaps(tres);
673#endif
674      if(res==NULL)
675        res=dupMaps(&tres);
676      else
677        addMapsToMaps(&res,tres);
678      freeMaps(&tres);
679      free(tres);
680      tres=NULL;
681      JS_DestroyIdArray(cx,idp);
682    }
683  }
684#ifdef JS_DEBUG
685  dumpMaps(res);
686#endif
687  return res;
688}
689
690/**
691 * Convert a JavaScript Object to a map
692 *
693 * @param cx the JavaScript context
694 * @param t the JavaScript Object to convert
695 * @return a new map containing the JavaScript Object
696 */
697map* mapFromJSObject(JSContext *cx,jsval t){
698  map *res=NULL;
699  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
700#ifdef JS_DEBUG
701  fprintf(stderr,"Properties %p\n",(void*)t);
702#endif
703  if(idp!=NULL) {
704    int index;
705    jsdouble argNum;
706#ifdef JS_DEBUG
707    fprintf(stderr,"Properties length :  %d \n",idp->length);
708#endif
709    for (index=0,argNum=idp->length;index<argNum;index++) { 
710      jsval id = idp->vector[index];
711      jsval vp;
712      JS_IdToValue(cx,id,&vp);
713      char *tmp, *tmp1;
714      JSString *jsmsg,*jsmsg1;
715      size_t len,len1;
716      jsmsg = JS_ValueToString(cx,vp);
717      len = JS_GetStringLength(jsmsg);
718      jsval nvp;
719      tmp=JS_EncodeString(cx,jsmsg);
720      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
721      jsmsg1 = JS_ValueToString(cx,nvp);
722      len1 = JS_GetStringLength(jsmsg1);
723      tmp1=JS_EncodeString(cx,jsmsg1);
724#ifdef JS_DEBUG
725      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
726#endif
727      if(res!=NULL){
728#ifdef JS_DEBUG
729        fprintf(stderr,"%s - %s\n",tmp,tmp1);
730#endif
731        addToMap(res,tmp,tmp1);
732      }
733      else{
734        res=createMap(tmp,tmp1);
735        res->next=NULL;
736      }
737      free(tmp);
738      free(tmp1);
739#ifdef JS_DEBUG
740      dumpMap(res);
741#endif
742    }
743    JS_DestroyIdArray(cx,idp);
744  }
745#ifdef JS_DEBUG
746  dumpMap(res);
747#endif
748  return res;
749}
750
751/**
752 * Print debug information messages on stderr
753 *
754 * @param cx the JavaScript context
755 * @param message the error message
756 * @param report the JavaScript Error Report
757 */
758void reportError(JSContext *cx, const char *message, JSErrorReport *report)
759{
760  sprintf(dbg,"%s:%u:%s\n",
761          report->filename ? report->filename : "<no filename>",
762          (unsigned int) report->lineno,
763          message);
764#ifdef JS_DEBUG
765  fprintf(stderr,"%s",dbg);
766#endif
767  fflush(stderr);
768}
769
770/**
771 * Convert a JavaScript value to a char*
772 *
773 * @param context the JavaScript context
774 * @param arg the JavaScript value
775 * @return a new char*
776 * @warning be sure to free the resources returned by this function
777 */
778char* JSValToChar(JSContext* context, jsval* arg) {
779  char *c;
780  char *tmp;
781  JSString *jsmsg;
782  size_t len;
783  int i;
784  if(!JSVAL_IS_STRING(*arg)) {
785    return NULL;
786  }
787  jsmsg = JS_ValueToString(context,*arg);
788  len = JS_GetStringLength(jsmsg);
789  tmp = JS_EncodeString(context,jsmsg);
790  c = (char*)malloc((len+1)*sizeof(char));
791  c[len] = '\0';
792#ifdef ULINET_DEBUG
793  fprintf(stderr,"%d \n",len);
794#endif
795  for(i = 0;i < len;i++) {
796    c[i] = tmp[i];
797    c[i+1] = 0;
798  }
799#ifdef ULINET_DEBUG
800  fprintf(stderr,"%s \n",c);
801#endif
802  return c;
803}
804
805/**
806 * Set the HTTP header of a request
807 *
808 * @param handle the HINTERNET handle
809 * @param cx the JavaScript context
810 * @param header the JavaScript Array containing the headers to send
811 * @return the HINTERNET handle
812 */
813HINTERNET setHeader(HINTERNET* handle,JSContext *cx,JSObject *header){
814  jsuint length=0;
815  jsint i=0;
816  char *tmp1;
817#ifdef ULINET_DEBUG
818  fprintf(stderr,"setHeader\n");
819#endif
820  if(JS_IsArrayObject(cx,header)){
821#ifdef ULINET_DEBUG
822    fprintf(stderr,"header is an array\n");
823#endif
824    JS_GetArrayLength(cx,header,&length);
825#ifdef ULINET_DEBUG
826    fprintf(stderr,"header is an array of %d elements\n",length);
827#endif
828    handle->ihandle[handle->nb].header=NULL;
829    for(i=0;i<length;i++){
830      jsval tmp;
831      JS_GetElement(cx,header,i,&tmp);
832      tmp1=JSValToChar(cx,&tmp);
833#ifdef ULINET_DEBUG
834      curl_easy_setopt(handle->ihandle[handle->nb].handle,CURLOPT_VERBOSE,1);
835      fprintf(stderr,"Element of array n° %d, value : %s\n",i,tmp1);
836#endif
837      handle->ihandle[handle->nb].header=curl_slist_append(handle->ihandle[handle->nb].header, tmp1);
838      free(tmp1);
839    }
840  }
841  else{
842    fprintf(stderr,"not an array !!!!!!!\n");
843  }
844  return *handle;
845}
846
847/**
848 * The function used as ZOOTranslate from the JavaScript environment.
849 * Use the ZOO-Services messages translation function from the Python
850 * environment (ZOO-API)
851 *
852 * @param cx the JavaScript context
853 * @param argc the number of parameters
854 * @param argv1 the parameter values
855 * @return true
856 */
857JSBool
858JSTranslate(JSContext *cx, uintN argc, jsval *argv1)
859{
860  jsval *argv = JS_ARGV(cx,argv1);
861  char *str=JSValToChar(cx,&argv[0]);
862  char *tmpValue=_ss(str);
863  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue)))); 
864  JS_MaybeGC(cx);
865  return JS_TRUE;
866}
867
868/**
869 * The function used as ZOORequest from the JavaScript environment (ZOO-API)
870 *
871 * @param cx the JavaScript context
872 * @param argc the number of parameters
873 * @param argv1 the parameter values
874 * @return true
875 * @see setHeader
876 */
877JSBool
878JSRequest(JSContext *cx, uintN argc, jsval *argv1)
879{
880  jsval *argv = JS_ARGV(cx,argv1);
881  HINTERNET hInternet;
882  JSObject *header;
883  char *url;
884  char *method;
885  char* tmpValue;
886  size_t dwRead;
887  JS_MaybeGC(cx);
888  hInternet=InternetOpen("ZooWPSClient\0",
889                         INTERNET_OPEN_TYPE_PRECONFIG,
890                         NULL,NULL, 0);
891  if(!CHECK_INET_HANDLE(hInternet))
892    return JS_FALSE;
893  if(argc>=2){
894    method=JSValToChar(cx,&argv[0]);
895    url=JSValToChar(cx,&argv[1]);
896  }
897  else{
898    method=zStrdup("GET");
899    url=JSValToChar(cx,argv);
900  }
901  hInternet.waitingRequests[hInternet.nb]=strdup(url);
902  if(argc==4){
903    char *body;
904    body=JSValToChar(cx,&argv[2]);
905    header=JSVAL_TO_OBJECT(argv[3]);
906#ifdef ULINET_DEBUG
907    fprintf(stderr,"URL (%s) \nBODY (%s)\n",url,body);
908#endif
909    if(JS_IsArrayObject(cx,header))
910      setHeader(&hInternet,cx,header);
911#ifdef ULINET_DEBUG
912    fprintf(stderr,"BODY (%s)\n",body);
913#endif
914    InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
915                    INTERNET_FLAG_NO_CACHE_WRITE,0);   
916    processDownloads(&hInternet);
917    free(body);
918  }else{
919    if(argc==3){
920      char *body=JSValToChar(cx,&argv[2]);
921      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],body,strlen(body),
922                      INTERNET_FLAG_NO_CACHE_WRITE,0);
923      processDownloads(&hInternet);
924      free(body);
925    }else{
926      InternetOpenUrl(&hInternet,hInternet.waitingRequests[hInternet.nb],NULL,0,
927                      INTERNET_FLAG_NO_CACHE_WRITE,0);
928      processDownloads(&hInternet);
929    }
930  }
931  tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
932  InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
933#ifdef ULINET_DEBUG
934  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
935#endif
936  if(dwRead==0){
937    JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,"Unable to access the file.",strlen("Unable to access the file."))));
938    return JS_TRUE;
939  }
940
941#ifdef ULINET_DEBUG
942  fprintf(stderr,"content downloaded (%d) (%s) \n",dwRead,tmpValue);
943#endif
944  JS_SET_RVAL(cx, argv1,STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpValue,strlen(tmpValue))));
945  free(url);
946  if(argc>=2)
947    free(method);
948  InternetCloseHandle(&hInternet);
949  JS_MaybeGC(cx);
950  return JS_TRUE;
951}
952
953/**
954 * The function used as ZOOUpdateStatus from the JavaScript environment
955 * (ZOO-API).
956 *
957 * @param cx the JavaScript context
958 * @param argc the number of parameters
959 * @param argv1 the parameter values
960 * @return true
961 * @see setHeader,_updateStatus
962 */
963JSBool
964JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
965{
966  jsval *argv = JS_ARGV(cx,argv1);
967  JS_MaybeGC(cx);
968  int istatus=0;
969  char *status=NULL;
970  maps *conf;
971  if(argc>2){
972#ifdef JS_DEBUG
973    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
974#endif
975    return JS_FALSE;
976  }
977  conf=mapsFromJSObject(cx,argv[0]);
978  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
979    char tmpStatus[4];
980    sprintf(tmpStatus,"%i",istatus);
981    tmpStatus[3]=0;
982    status=strdup(tmpStatus);
983  }
984  if(getMapFromMaps(conf,"lenv","status")!=NULL){
985    if(status!=NULL){
986      setMapInMaps(conf,"lenv","status",status);
987      free(status);
988    }
989    else
990      setMapInMaps(conf,"lenv","status","15");
991    _updateStatus(conf);
992  }
993  freeMaps(&conf);
994  free(conf);
995  JS_MaybeGC(cx);
996  return JS_TRUE;
997}
998
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