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

Last change on this file since 331 was 329, checked in by djay, 13 years ago

Store metapath even for POST requests. Correct load of js when metapath was used.

File size: 14.0 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2010 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.h"
26
27static char dbg[1024];
28
29JSBool
30JSAlert(JSContext *cx, uintN argc, jsval *argv1)
31{
32  jsval *argv = JS_ARGV(cx,argv1);
33  int i=0;
34  JS_MaybeGC(cx);
35  for(i=0;i<argc;i++){
36    JSString* jsmsg = JS_ValueToString(cx,argv[i]);
37    fprintf(stderr,"[ZOO-API:JS] %s\n",JS_EncodeString(cx,jsmsg));
38  }
39  JS_MaybeGC(cx);
40 
41  return JS_TRUE;
42}
43
44int zoo_js_support(maps** main_conf,map* request,service* s,
45                   maps **inputs,maps **outputs)
46{
47  maps* main=*main_conf;
48  maps* _inputs=*inputs;
49  maps* _outputs=*outputs;
50
51  /* The class of the global object. */
52  JSClass global_class = {
53    "global", JSCLASS_GLOBAL_FLAGS,
54    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
55    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
56    JSCLASS_NO_OPTIONAL_MEMBERS
57  };
58
59  /* JS variables. */
60  JSRuntime *rt;
61  JSContext *cx;
62  JSObject  *global;
63
64  /* Create a JS runtime. */
65  rt = JS_NewRuntime(8L * 1024L * 1024L);
66  if (rt == NULL)
67    return 1;
68 
69  /* Create a context. */
70  cx = JS_NewContext(rt,8192);
71  if (cx == NULL){
72    return 1;
73  }
74  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT );//| JSOPTION_METHODJIT);
75  JS_SetVersion(cx, JSVERSION_LATEST);
76  JS_SetErrorReporter(cx, reportError);
77
78  /* Create the global object. */
79  //#ifdef JS_NewCompartmentAndGlobalObject
80  global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
81  //#else
82  //global = JS_NewObject(cx, &global_class, NULL,NULL);
83  //#endif
84
85  /* Populate the global object with the standard globals,
86     like Object and Array. */
87  if (!JS_InitStandardClasses(cx, global)){
88    return 1;
89  }
90
91  if (!JS_DefineFunction(cx, global, "ZOORequest", JSRequest, 4, 0))
92    return 1;
93  if (!JS_DefineFunction(cx, global, "ZOOUpdateStatus", JSUpdateStatus, 2, 0))
94    return 1;
95  if (!JS_DefineFunction(cx, global, "alert", JSAlert, 2, 0))
96    return 1;
97
98  map* tmpm1=getMap(request,"metapath");
99  char ntmp[1024];
100  getcwd(ntmp,1024);
101
102  /**
103   * Load the first part of the ZOO-API
104   */
105  char api0[strlen(tmpm1->value)+strlen(ntmp)+16];
106  sprintf(api0,"%s/%s/ZOO-proj4js.js",ntmp,tmpm1->value);
107#ifdef JS_DEBUG
108  fprintf(stderr,"Trying to load %s\n",api0);
109#endif
110  JSObject *api_script1=loadZooApiFile(cx,global,api0);
111  fflush(stderr);
112
113  char api1[strlen(tmpm1->value)+strlen(ntmp)+11];
114  sprintf(api1,"%s/%s/ZOO-api.js",ntmp,tmpm1->value);
115#ifdef JS_DEBUG
116  fprintf(stderr,"Trying to load %s\n",api1);
117#endif
118  JSObject *api_script2=loadZooApiFile(cx,global,api1);
119  fflush(stderr);
120
121  /* Your application code here. This may include JSAPI calls
122     to create your own custom JS objects and run scripts. */
123  maps* out=*outputs;
124  int res=SERVICE_FAILED;
125  maps* mc=*main_conf;
126  map* tmpm2=getMap(s->content,"serviceProvider");
127
128  char filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+3];
129  sprintf(filename,"%s/%s/%s",ntmp,tmpm1->value,tmpm2->value);
130  filename[strlen(tmpm1->value)+strlen(tmpm2->value)+strlen(ntmp)+2]=0;
131#ifdef JS_DEBUG
132  fprintf(stderr,"FILENAME %s\n",filename);
133#endif
134  struct stat file_status;
135  stat(filename, &file_status);
136  char source[file_status.st_size];
137  uint16 lineno;
138  jsval rval;
139  JSBool ok ;
140  JSObject *script = JS_CompileFile(cx, global, filename);
141  if(script!=NULL){
142    (void)JS_ExecuteScript(cx, global, script, &rval);
143  }
144  else{
145    char tmp1[1024];
146    sprintf(tmp1,"Unable to load JavaScript file %s",filename);
147    map* err=createMap("text",tmp1);
148    addMapToMap(&err,createMap("code","NoApplicableCode"));
149    printExceptionReportResponse(mc,err);
150    JS_DestroyContext(cx);
151    JS_DestroyRuntime(rt);
152    JS_ShutDown();
153    exit(-1);
154  }
155  /* Call a function in obj's scope. */
156  jsval argv[3];
157  JSObject *jsargv1=JSObject_FromMaps(cx,*main_conf);
158  argv[0] = OBJECT_TO_JSVAL(jsargv1);
159  JSObject *jsargv2=JSObject_FromMaps(cx,*inputs);
160  argv[1] = OBJECT_TO_JSVAL(jsargv2);
161  JSObject *jsargv3=JSObject_FromMaps(cx,*outputs);
162  argv[2] = OBJECT_TO_JSVAL(jsargv3);
163  jsval rval1=JSVAL_NULL;
164#ifdef JS_DEBUG
165  fprintf(stderr, "object %p\n", (void *) argv[2]);
166#endif
167
168  ok = JS_CallFunctionName(cx, global, s->name, 3, argv, &rval1);
169
170#ifdef JS_DEBUG
171  fprintf(stderr, "object %p\n", (void *) argv[2]);
172#endif
173
174  JSObject *d;
175  if (ok==JS_TRUE && JSVAL_IS_OBJECT(rval1)==JS_TRUE) {
176#ifdef JS_DEBUG
177    fprintf(stderr,"Function run sucessfully !\n");
178#endif
179    /* Should get a number back from the service function call. */
180    ok = JS_ValueToObject(cx, rval1, &d);
181  }else{
182    /* Unable to run JS function */
183    char tmp1[1024];
184    if(strlen(dbg)==0)
185      sprintf(dbg,"No result was found after the function call");
186    sprintf(tmp1,"Unable to run %s from the JavaScript file %s : \n %s",s->name,filename,dbg);
187#ifdef JS_DEBUG
188    fprintf(stderr,"%s",tmp1);
189#endif
190    map* err=createMap("text",tmp1);
191    addToMap(err,"code","NoApplicableCode");
192    printExceptionReportResponse(*main_conf,err);
193    freeMap(&err);
194    free(err);
195    JS_DestroyContext(cx);
196    JS_DestroyRuntime(rt);
197    JS_ShutDown();
198    // Should return -1 here but the unallocation won't work from zoo_service_loader.c line 1847
199    exit(-1);
200  }
201
202  jsval t=OBJECT_TO_JSVAL(d);
203  if(JS_IsArrayObject(cx,d)){
204#ifdef JS_DEBUG
205    fprintf(stderr,"An array was returned !\n");
206#endif
207    jsint len;
208    if((JS_GetArrayLength(cx, d, &len)==JS_FALSE)){
209#ifdef JS_DEBUG
210      fprintf(stderr,"outputs array is empty\n");
211#endif
212    }
213    jsval tmp1;
214    JSBool hasResult=JS_GetElement(cx,d,0,&tmp1);
215    res=JSVAL_TO_INT(tmp1);
216#ifdef JS_DEBUG
217    fprintf(stderr," * %d * \n",res);
218#endif
219    jsval tmp2;
220    JSBool hasElement=JS_GetElement(cx,d,1,&tmp2);
221    if(hasElement==JS_TRUE){
222      *outputs=mapsFromJSObject(cx,tmp2);
223    }
224  }
225  else{
226#ifdef JS_DEBUG
227    fprintf(stderr,"The serice didn't return an array !\n");
228#endif
229    jsval tmp1;
230    JSBool hasResult=JS_GetProperty(cx,d,"result",&tmp1);
231    res=JSVAL_TO_INT(tmp1);
232
233#ifdef JS_DEBUG
234    fprintf(stderr," * %d * \n",res);
235#endif
236    jsval tmp2;
237    JSBool hasElement=JS_GetProperty(cx,d,"outputs",&tmp2);
238#ifdef JS_DEBUG
239    if(!hasElement)
240      fprintf(stderr,"No outputs property returned\n");
241    if(JS_IsArrayObject(cx,JSVAL_TO_OBJECT(tmp2)))
242      fprintf(stderr,"outputs is array an as expected\n");
243    else
244      fprintf(stderr,"outputs is not an array as expected\n");
245#endif
246    *outputs=mapsFromJSObject(cx,tmp2);
247#ifdef JS_DEBUG
248    dumpMaps(outputs);
249#endif
250  }
251
252  /* Cleanup. */
253  JS_DestroyContext(cx);
254  JS_DestroyRuntime(rt);
255  JS_ShutDown();
256#ifdef JS_DEBUG
257  fprintf(stderr,"Returned value %d\n",res);
258#endif
259  return res;
260}
261
262JSObject * loadZooApiFile(JSContext *cx,JSObject  *global, char* filename){
263  struct stat api_status;
264  int s=stat(filename, &api_status);
265  if(s==0){
266    jsval rval;
267    JSBool ok ;
268    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
269    if(script!=NULL){
270      (void)JS_ExecuteScript(cx, JS_GetGlobalObject(cx), script, &rval);
271#ifdef JS_DEBUG
272      fprintf(stderr,"**************\n%s correctly loaded\n**************\n",filename);
273#endif
274      return script;
275    }
276#ifdef JS_DEBUG
277    else
278      fprintf(stderr,"\n**************\nUnable to run %s\n**************\n",filename);
279#endif
280  }
281#ifdef JS_DEBUG
282  else
283    fprintf(stderr,"\n**************\nUnable to load %s\n**************\n",filename);
284#endif
285  return NULL;
286}
287
288JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
289
290  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
291  //JSObject *res = JS_NewArrayObject(cx, 0, NULL);
292  if(res==NULL)
293    fprintf(stderr,"Array Object is NULL!\n");
294  maps* tmp=t;
295
296  while(tmp!=NULL){
297    jsuint len;
298    JSObject* res1=JS_NewObject(cx, NULL, NULL, NULL);
299    JSObject *pval=JSObject_FromMap(cx,tmp->content);
300    jsval pvalj=OBJECT_TO_JSVAL(pval);
301    JS_SetProperty(cx, res, tmp->name, &pvalj);
302
303#ifdef JS_DEBUG
304    fprintf(stderr,"Length of the Array %d, element : %s added \n",len,tmp->name);
305#endif
306    tmp=tmp->next;
307  } 
308  return res;
309}
310
311JSObject* JSObject_FromMap(JSContext *cx,map* t){
312  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
313  jsval resf =  OBJECT_TO_JSVAL(res);
314  map* tmpm=t;
315  while(tmpm!=NULL){
316    jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
317    JS_SetProperty(cx, res, tmpm->name,&jsstr);
318#ifdef JS_DEBUG
319    fprintf(stderr,"%s => %s\n",tmpm->name,tmpm->value);
320#endif
321    tmpm=tmpm->next;
322  }
323  return res;
324}
325
326maps* mapsFromJSObject(JSContext *cx,jsval t){
327  maps *res=NULL;
328  maps *tres=NULL;
329  jsint oi=0;
330  JSObject* tt=JSVAL_TO_OBJECT(t);
331#ifdef JS_DEBUG
332  fprintf(stderr,"Is finally an array ?\n");
333  if(JS_IsArrayObject(cx,tt)){
334    fprintf(stderr,"Is finally an array !\n");
335  }
336  else
337    fprintf(stderr,"Is not an array !\n");
338#endif
339  jsint len;
340  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
341  if(hasLen==JS_FALSE){
342#ifdef JS_DEBUG
343    fprintf(stderr,"outputs array is empty\n");
344#endif
345  }
346#ifdef JS_DEBUG
347  fprintf(stderr,"outputs array length : %d\n",len);
348#endif
349  for(oi=0;oi < len;oi++){
350#ifdef JS_DEBUG
351    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
352#endif
353    jsval tmp1;
354    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
355    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
356    JSIdArray *idp=JS_Enumerate(cx,otmp1);
357    if(idp!=NULL) {
358      int index;
359      jsdouble argNum;
360#ifdef JS_DEBUG
361      fprintf(stderr,"Properties length :  %d \n",idp->length);
362#endif
363      tres=(maps*)malloc(MAPS_SIZE);
364      tres->name=NULL;
365      tres->content=NULL;
366      tres->next=NULL;
367
368      for (index=0,argNum=idp->length;index<argNum;index++) { 
369        jsval id = idp->vector[index];
370        jsval vp;
371        JSString* str; 
372        JS_IdToValue(cx,id,&vp);
373        char *c, *tmp;
374        JSString *jsmsg;
375        size_t len1;
376        jsmsg = JS_ValueToString(cx,vp);
377        len1 = JS_GetStringLength(jsmsg);
378#ifdef JS_DEBUG
379        fprintf(stderr,"Enumerate id : %d => %s\n",oi,JS_EncodeString(cx,jsmsg));
380#endif
381        jsval nvp=JSVAL_NULL;
382        if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), JS_EncodeString(cx,jsmsg), &nvp)==JS_FALSE)){
383#ifdef JS_DEBUG
384          fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,JS_EncodeString(cx,jsmsg));
385#endif
386        }
387       
388        if(JSVAL_IS_OBJECT(nvp)){
389#ifdef JS_DEBUG
390          fprintf(stderr,"JSVAL NVP IS OBJECT\n");
391#endif
392        }
393
394        JSObject *nvp1=JSVAL_NULL;
395        JS_ValueToObject(cx,nvp,&nvp1);
396        jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
397        if(JSVAL_IS_OBJECT(nvp1j)){
398          JSString *jsmsg1;
399          JSObject *nvp2=JSVAL_NULL;
400          jsmsg1 = JS_ValueToString(cx,nvp1j);
401          len1 = JS_GetStringLength(jsmsg1);
402#ifdef JS_DEBUG
403          fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
404#endif
405          if(strcasecmp(JS_EncodeString(cx,jsmsg1),"[object Object]")==0){
406            tres->name=strdup(JS_EncodeString(cx,jsmsg));
407            tres->content=mapFromJSObject(cx,nvp1j);
408          }
409          else
410            if(strcasecmp(JS_EncodeString(cx,jsmsg),"name")==0){
411              tres->name=strdup(JS_EncodeString(cx,jsmsg1));
412            }
413            else{
414              if(tres->content==NULL)
415                tres->content=createMap(JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
416              else
417                addToMap(tres->content,JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
418            }
419        }
420#ifdef JS_DEBUG
421        else
422          fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
423#endif
424
425      }
426#ifdef JS_DEBUG
427      dumpMaps(tres);
428#endif
429      if(res==NULL)
430        res=dupMaps(&tres);
431      else
432        addMapsToMaps(&res,tres);
433      freeMaps(&tres);
434      free(tres);
435      tres=NULL;
436
437    }
438  }
439#ifdef JS_DEBUG
440  dumpMaps(res);
441#endif
442  return res;
443}
444
445map* mapFromJSObject(JSContext *cx,jsval t){
446  map *res=NULL;
447  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
448#ifdef JS_DEBUG
449  fprintf(stderr,"Properties %p\n",(void*)t);
450#endif
451  if(idp!=NULL) {
452    int index;
453    jsdouble argNum;
454#ifdef JS_DEBUG
455    fprintf(stderr,"Properties length :  %d \n",idp->length);
456#endif
457    for (index=0,argNum=idp->length;index<argNum;index++) { 
458      jsval id = idp->vector[index];
459      jsval vp;
460      JSString* str; 
461      JS_IdToValue(cx,id,&vp);
462      char *c, *tmp;
463      JSString *jsmsg,*jsmsg1;
464      size_t len,len1;
465      jsmsg = JS_ValueToString(cx,vp);
466      len = JS_GetStringLength(jsmsg);
467      jsval nvp;
468      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), JS_EncodeString(cx,jsmsg), &nvp);
469      jsmsg1 = JS_ValueToString(cx,nvp);
470      len1 = JS_GetStringLength(jsmsg1);
471#ifdef JS_DEBUG
472      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
473#endif
474      if(res!=NULL){
475#ifdef JS_DEBUG
476        fprintf(stderr,"%s - %s\n",JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
477#endif
478        addToMap(res,JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
479      }
480      else{
481        res=createMap(JS_EncodeString(cx,jsmsg),JS_EncodeString(cx,jsmsg1));
482        res->next=NULL;
483      }
484#ifdef JS_DEBUG
485      dumpMap(res);
486#endif
487    }
488  }
489#ifdef JS_DEBUG
490  dumpMap(res);
491#endif
492  return res;
493}
494
495/* The error reporter callback. */
496void reportError(JSContext *cx, const char *message, JSErrorReport *report)
497{
498  sprintf(dbg,"%s:%u:%s\n",
499          report->filename ? report->filename : "<no filename>",
500          (unsigned int) report->lineno,
501          message);
502#ifdef JS_DEBUG
503  fprintf(stderr,"%s",dbg);
504#endif
505  fflush(stderr);
506}
507
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