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

Last change on this file since 788 was 784, checked in by djay, 10 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