source: trunk/zoo-project/zoo-kernel/service_json.c @ 965

Last change on this file since 965 was 965, checked in by djay, 20 months ago

Display inputs when not valid properly. Add element for list of values. Add required operationId and summary for every request, useful to validate the APIusing openapi-cli.

  • Property svn:keywords set to Id
File size: 72.1 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2017-2020 GeoLabs SARL. All rights reserved.
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_json.h"
26#include "json.h"
27#include <errno.h>
28#include "json_tokener.h"
29#include "stdlib.h"
30#include "mimetypes.h"
31#include "server_internal.h"
32#include "service_internal.h"
33#include <dirent.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38  /**
39   * Equivalent range keywords for WPS version 1 and 2
40   */
41  const char* rangeCorrespondances[4][2]={
42    { "rangeMin", "minimumValue" },
43    { "rangeMax", "maximumValue"},
44    { "rangeSpacing", "spacing" }, 
45    { "rangeClosure", "rangeClosure" }
46  };
47 
48
49  /**
50   * Convert a map to a json object
51   * @param myMap the map to be converted into json object
52   * @return a json_object pointer to the created json_object
53   */
54  json_object* mapToJson(map* myMap){
55    json_object *res=json_object_new_object();
56    map* cursor=myMap;
57    map* sizeMap=getMap(myMap,"size");
58    map* length=getMap(myMap,"length");
59    while(cursor!=NULL){
60      json_object *val=NULL;
61      if(length==NULL && sizeMap==NULL)
62        val=json_object_new_string(cursor->value);
63      else{
64        if(length==NULL && sizeMap!=NULL){
65          if(strncasecmp(cursor->name,"value",5)==0)
66            val=json_object_new_string_len(cursor->value,atoi(sizeMap->value));
67          else
68            val=json_object_new_string(cursor->value);
69        }
70        else{
71          // In other case we should consider array with potential sizes
72          int limit=atoi(length->value);
73          int i=0;
74          val=json_object_new_array();
75          for(i=0;i<limit;i++){
76            map* lsizeMap=getMapArray(myMap,"size",i);
77            if(lsizeMap!=NULL && strncasecmp(cursor->name,"value",5)==0){
78              json_object_array_add(val,json_object_new_string_len(cursor->value,atoi(sizeMap->value)));
79            }else{
80              json_object_array_add(val,json_object_new_string(cursor->value));
81            }
82          }
83        }
84      }
85      if(val!=NULL)
86        json_object_object_add(res,cursor->name,val);
87      cursor=cursor->next;
88    }
89    return res;
90  }
91
92  /**
93   * Convert a maps to a json object
94   * @param myMap the maps to be converted into json object
95   * @return a json_object pointer to the created json_object
96   */
97  json_object* mapsToJson(maps* myMap){
98    json_object *res=json_object_new_object();
99    maps* cursor=myMap;
100    while(cursor!=NULL){
101      json_object *obj=NULL;
102      if(cursor->content!=NULL){
103        obj=mapToJson(cursor->content);
104      }else
105        obj=json_object_new_object();
106      if(cursor->child!=NULL){
107        json_object *child=NULL;
108        child=mapsToJson(cursor->child);
109        json_object_object_add(obj,"child",child);
110      }
111      json_object_object_add(res,cursor->name,obj);
112      cursor=cursor->next;
113    }
114    return res;
115  }
116
117  /**
118   * Convert an elements to a json object
119   * @param myElements the elements pointer to be converted into a json object
120   * @return a json_object pointer to the created json_object
121   */
122  json_object* elementsToJson(elements* myElements){
123    json_object *res=json_object_new_object();
124    elements* cur=myElements;
125    while(cur!=NULL){
126      json_object *cres=json_object_new_object();
127      json_object_object_add(cres,"content",mapToJson(cur->content));
128      json_object_object_add(cres,"metadata",mapToJson(cur->metadata));
129      json_object_object_add(cres,"additional_parameters",mapToJson(cur->additional_parameters));
130      if(cur->format!=NULL){
131        json_object_object_add(cres,"format",json_object_new_string(cur->format));
132      }
133      if(cur->child==NULL){
134        if(cur->defaults!=NULL)
135          json_object_object_add(cres,"defaults",mapToJson(cur->defaults->content));
136        else
137          json_object_object_add(cres,"defaults",mapToJson(NULL));
138        iotype* scur=cur->supported;
139        json_object *resi=json_object_new_array();
140        while(scur!=NULL){
141          json_object_array_add(resi,mapToJson(scur->content));
142          scur=scur->next;
143        }
144        json_object_object_add(cres,"supported",resi);
145      }
146     
147      json_object_object_add(cres,"child",elementsToJson(cur->child));
148
149      json_object_object_add(res,cur->name,cres);
150      cur=cur->next;
151    }
152    return res;
153  }
154 
155  /**
156   * Convert an service to a json object
157   * @param myService the service pointer to be converted into a json object
158   * @return a json_object pointer to the created json_object
159   */
160  json_object* serviceToJson(service* myService){
161    json_object *res=json_object_new_object();
162    json_object_object_add(res,"name",json_object_new_string(myService->name));
163    json_object_object_add(res,"content",mapToJson(myService->content));
164    json_object_object_add(res,"metadata",mapToJson(myService->metadata));
165    json_object_object_add(res,"additional_parameters",mapToJson(myService->additional_parameters));
166    json_object_object_add(res,"inputs",elementsToJson(myService->inputs));
167    json_object_object_add(res,"outputs",elementsToJson(myService->outputs));
168    return res;
169  }
170
171  /**
172   * Add Allowed Range properties to a json_object
173   * @param m the main configuration maps pointer
174   * @param iot the iotype pointer
175   * @param prop the json_object pointer to add the allowed range properties
176   * @return a json_object pointer to the created json_object
177   */
178  void printAllowedRangesJ(maps* m,iotype* iot,json_object* prop){
179    map* tmpMap1;
180    json_object* prop4=json_object_new_object();
181    for(int i=0;i<4;i++){
182      tmpMap1=getMap(iot->content,rangeCorrespondances[i][0]);
183      if(tmpMap1!=NULL){
184        if(i<3)
185          json_object_object_add(prop4,rangeCorrespondances[i][1],json_object_new_string(tmpMap1->value));
186        else{
187          char* currentValue=NULL;
188          int limit=strlen(tmpMap1->value);
189          for(int j=0;j<limit;j++){
190            const char* tmpS="closed";
191            if(tmpMap1->value[j]=='o'){
192              tmpS="open";
193            }
194            if(currentValue==NULL){
195              currentValue=(char*)malloc((strlen(tmpS)+1)*sizeof(char));
196              sprintf(currentValue,"%s",tmpS);
197            }else{
198              char* tmpS1=zStrdup(currentValue);
199              currentValue=(char*)realloc(currentValue,(strlen(tmpS1)+strlen(tmpS)+2)*sizeof(char));
200              sprintf(currentValue,"%s-%s",tmpS1,tmpS);
201            }
202          }           
203          json_object_object_add(prop4,rangeCorrespondances[i][1],json_object_new_string(currentValue));
204        }
205      }
206    }
207    json_object_array_add(prop,prop4);
208  }
209 
210  /**
211   * Add literalDataDomains property to a json_object
212   * @param m the main configuration maps pointer
213   * @param in the elements pointer
214   * @param input the json_object pointer to add the literalDataDomains property
215   * @return a json_object pointer to the created json_object
216   */
217  void printLiteralDataJ(maps* m,elements* in,json_object* input){
218    json_object* prop0=json_object_new_array();
219    json_object* prop1=json_object_new_object();
220    json_object* prop2=json_object_new_object();
221    if(in->defaults!=NULL){
222      map* tmpMap1=getMap(in->defaults->content,"DataType");
223      if(tmpMap1!=NULL){
224        json_object_object_add(prop2,"name",json_object_new_string(tmpMap1->value));
225        char *tmp=(char*)malloc((strlen(tmpMap1->value)+35)*sizeof(char));
226        sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmpMap1->value);
227        json_object_object_add(prop2,"reference",json_object_new_string(tmp));
228        free(tmp);
229        json_object_object_add(prop1,"dataType",prop2);
230      }
231      tmpMap1=getMap(in->defaults->content,"value");
232      if(tmpMap1!=NULL)
233        json_object_object_add(prop1,"defaultValue",json_object_new_string(tmpMap1->value));
234      json_object* prop3=json_object_new_object();
235      tmpMap1=getMap(in->defaults->content,"rangeMin");
236      if(tmpMap1!=NULL){
237        json_object* prop5=json_object_new_array();
238        printAllowedRangesJ(m,in->defaults,prop5);
239        if(in->supported!=NULL){
240          iotype* iot=in->supported;
241          while(iot!=NULL){
242            printAllowedRangesJ(m,iot,prop5);
243            iot=iot->next;
244          }
245        }
246        json_object_object_add(prop3,"allowedRanges",prop5);
247      }
248      else{
249        tmpMap1=getMap(in->defaults->content,"range");
250        if(tmpMap1!=NULL){
251          // TODO: parse range = [rangeMin,rangeMax]
252        }else{ 
253          // AllowedValues
254          tmpMap1=getMap(in->defaults->content,"AllowedValues");
255          if(tmpMap1!=NULL){
256            char* saveptr;
257            json_object* prop5=json_object_new_array();
258            char *tmps = strtok_r (tmpMap1->value, ",", &saveptr);
259            while(tmps!=NULL){
260              json_object_array_add(prop5,json_object_new_string(tmps));
261              tmps = strtok_r (NULL, ",", &saveptr);
262            }
263            json_object_object_add(prop3,"allowedValues",prop5);
264           
265          }else{
266            json_object_object_add(prop3,"anyValue",json_object_new_boolean(true));
267          }
268        }
269      }
270      json_object_object_add(prop1,"valueDefinition",prop3);
271      json_object_array_add(prop0,prop1);
272    }
273    json_object_object_add(input,"literalDataDomains",prop0);
274  }
275
276  /**
277   * Add Format properties to a json_object
278   * @param m the main configuration maps pointer
279   * @param iot the current iotype pointer
280   * @param res the json_object pointer to add the properties to
281   * @param isDefault boolean specifying if the currrent iotype is default
282   * @param maxSize a map pointer to the maximumMegabytes param defined in the zcfg file for this input/output
283   */
284  void printFormatJ(maps* m,iotype* iot,json_object* res,bool isDefault,map* maxSize){
285    if(iot!=NULL){
286      map* tmpMap1=getMap(iot->content,"mimeType");
287      json_object* prop1=json_object_new_object();
288      json_object_object_add(prop1,"default",json_object_new_boolean(isDefault));
289      json_object_object_add(prop1,"mimeType",json_object_new_string(tmpMap1->value));
290      tmpMap1=getMap(iot->content,"encoding");
291      if(tmpMap1!=NULL)
292        json_object_object_add(prop1,"encoding",json_object_new_string(tmpMap1->value));
293      tmpMap1=getMap(iot->content,"schema");
294      if(tmpMap1!=NULL)
295        json_object_object_add(prop1,"schema",json_object_new_string(tmpMap1->value));
296      if(maxSize!=NULL)
297        json_object_object_add(prop1,"maximumMegabytes",json_object_new_int64(atoll(maxSize->value)));
298      json_object_array_add(res,prop1);
299    }
300  }
301
302  /**
303   * Add additionalParameters property to a json_object
304   * @param conf the main configuration maps pointer
305   * @param meta a map pointer to the current metadata informations
306   * @param doc the json_object pointer to add the property to
307   */
308  void printJAdditionalParameters(maps* conf,map* meta,json_object* doc){
309    map* cmeta=meta;
310    json_object* carr=json_object_new_array();
311    int hasElement=-1;
312    json_object* jcaps=json_object_new_object();
313    while(cmeta!=NULL){
314      json_object* jcmeta=json_object_new_object();
315      if(strcasecmp(cmeta->name,"role")!=0 &&
316         strcasecmp(cmeta->name,"href")!=0 &&
317         strcasecmp(cmeta->name,"title")!=0 &&
318         strcasecmp(cmeta->name,"length")!=0 ){
319        json_object_object_add(jcmeta,"name",json_object_new_string(cmeta->name));
320        json_object_object_add(jcmeta,"value",json_object_new_string(cmeta->value));
321        json_object_array_add(carr,jcmeta);
322        hasElement++;
323      }else{
324        if(strcasecmp(cmeta->name,"length")!=0)
325          json_object_object_add(jcaps,cmeta->name,json_object_new_string(cmeta->value));
326      }
327      cmeta=cmeta->next;
328    }
329    if(hasElement>=0){
330      json_object_object_add(jcaps,"additionalParameter",carr);
331      json_object_object_add(doc,"additionalParameters",jcaps);
332    }
333  }
334
335  /**
336   * Add metadata property to a json_object
337   * @param conf the main configuration maps pointer
338   * @param meta a map pointer to the current metadata informations
339   * @param doc the json_object pointer to add the property to
340   */
341  void printJMetadata(maps* conf,map* meta,json_object* doc){
342    map* cmeta=meta;
343    json_object* carr=json_object_new_array();
344    int hasElement=-1;
345    while(cmeta!=NULL){
346      json_object* jcmeta=json_object_new_object();
347      if(strcasecmp(cmeta->name,"role")==0 ||
348         strcasecmp(cmeta->name,"href")==0 ||
349         strcasecmp(cmeta->name,"title")==0 ){
350        json_object_object_add(jcmeta,cmeta->name,json_object_new_string(cmeta->value));
351        hasElement++;
352      }
353      json_object_array_add(carr,jcmeta);
354      cmeta=cmeta->next;
355    }
356    if(hasElement>=0)
357      json_object_object_add(doc,"metadata",carr);
358  }
359
360  /**
361   * Add metadata properties to a json_object
362   * @param m the main configuration maps pointer
363   * @param io a string
364   * @param in an elements pointer to the current input/output
365   * @param inputs the json_object pointer to add the property to
366   * @param serv the service pointer to extract the metadata from
367   */
368  void printIOTypeJ(maps* m, const char *io, elements* in,json_object* inputs,service* serv){
369    while(in!=NULL){
370      json_object* input=json_object_new_object();
371      json_object_object_add(input,"id",json_object_new_string(in->name));
372      map* tmpMap=getMap(in->content,"title");
373      if(tmpMap!=NULL)
374        json_object_object_add(input,"title",json_object_new_string(tmpMap->value));
375      tmpMap=getMap(in->content,"abstract");
376      if(tmpMap!=NULL)
377        json_object_object_add(input,"description",json_object_new_string(tmpMap->value));
378      if(strcmp(io,"input")==0){
379        tmpMap=getMap(in->content,"minOccurs");
380        if(tmpMap!=NULL)
381          json_object_object_add(input,"minOccurs",json_object_new_int(atoi(tmpMap->value)));
382        tmpMap=getMap(in->content,"maxOccurs");
383        if(tmpMap!=NULL){
384          if(strncasecmp(tmpMap->value,"unbounded",9)==0)
385            json_object_object_add(input,"maxOccurs",json_object_new_string(tmpMap->value));
386          else
387            json_object_object_add(input,"maxOccurs",json_object_new_int(atoi(tmpMap->value)));
388        }
389      }
390      if(in->format!=NULL){
391        json_object* input1=json_object_new_object();
392        json_object* prop0=json_object_new_array();
393        if(strcasecmp(in->format,"LiteralData")==0 ||
394           strcasecmp(in->format,"LiteralOutput")==0){
395          printLiteralDataJ(m,in,input1);
396        }else{
397          if(strcasecmp(in->format,"ComplexData")==0 ||
398             strcasecmp(in->format,"ComplexOutput")==0){
399            map* sizeMap=getMap(in->content,"maximumMegabytes");
400            printFormatJ(m,in->defaults,prop0,true,sizeMap);
401            iotype* sup=in->supported;
402            while(sup!=NULL){
403              printFormatJ(m,sup,prop0,false,sizeMap);
404              sup=sup->next;
405            }
406            json_object_object_add(input1,"formats",prop0);
407          }
408          else{
409            json_object* prop1=json_object_new_object();
410            json_object_object_add(prop1,"default",json_object_new_boolean(true));
411            map* tmpMap1=getMap(in->defaults->content,"crs");
412            if(tmpMap1==NULL)
413              return;
414            json_object_object_add(prop1,"crs",json_object_new_string(tmpMap1->value));
415            json_object_array_add(prop0,prop1);
416            iotype* sup=in->supported;
417            while(sup!=NULL){
418              json_object* prop1=json_object_new_object();
419              json_object_object_add(prop1,"default",json_object_new_boolean(false));
420              tmpMap1=getMap(sup->content,"crs");
421              json_object_object_add(prop1,"crs",json_object_new_string(tmpMap1->value));
422              json_object_array_add(prop0,prop1);
423              sup=sup->next;
424            }         
425            json_object_object_add(input1,"supportedCRS",prop0);
426          }
427        }
428        json_object_object_add(input,io,input1);
429      }
430      printJMetadata(m,in->metadata,input);
431      printJAdditionalParameters(m,in->additional_parameters,input);
432      json_object_array_add(inputs,input);     
433      in=in->next;
434    }
435   
436  }
437
438  /**
439   * Add all the capabilities properties to a json_object
440   * @param ref the registry pointer
441   * @param m the main configuration maps pointer
442   * @param doc0 the void (json_object) pointer to add the property to
443   * @param nc0 the void (json_object) pointer to add the property to
444   * @param serv the service pointer to extract the metadata from
445   */
446  void printGetCapabilitiesForProcessJ(registry *reg, maps* m,void* doc0,void* nc0,service* serv){
447    json_object* doc=(json_object*) doc0;
448    json_object* nc=(json_object*) nc0;
449    json_object *res;
450    if(doc!=NULL)
451      res=json_object_new_object();
452    else
453      res=(json_object*) nc0;
454     
455    map* tmpMap0=getMapFromMaps(m,"lenv","level");
456    char* rUrl=serv->name;
457    if(tmpMap0!=NULL && atoi(tmpMap0->value)>0){
458      int i=0;
459      maps* tmpMaps=getMaps(m,"lenv");
460      char* tmpName=NULL;
461      for(i=0;i<atoi(tmpMap0->value);i++){
462        char* key=(char*)malloc(15*sizeof(char));
463        sprintf(key,"sprefix_%d",i);
464        map* tmpMap1=getMap(tmpMaps->content,key);
465        if(i+1==atoi(tmpMap0->value))
466          if(tmpName==NULL){
467            tmpName=(char*) malloc((strlen(serv->name)+strlen(tmpMap1->value)+1)*sizeof(char));
468            sprintf(tmpName,"%s%s",tmpMap1->value,serv->name);
469          }else{
470            char* tmpStr=zStrdup(tmpName);
471            tmpName=(char*) realloc(tmpName,(strlen(tmpStr)+strlen(tmpMap1->value)+strlen(serv->name)+1)*sizeof(char));
472            sprintf(tmpName,"%s%s%s",tmpStr,tmpMap1->value,serv->name);
473            free(tmpStr);
474          }
475        else
476          if(tmpName==NULL){
477            tmpName=(char*) malloc((strlen(tmpMap1->value)+1)*sizeof(char));
478            sprintf(tmpName,"%s",tmpMap1->value);
479          }else{
480            char* tmpStr=zStrdup(tmpName);
481            tmpName=(char*) realloc(tmpName,(strlen(tmpStr)+strlen(tmpMap1->value)+1)*sizeof(char));
482            sprintf(tmpName,"%s%s",tmpStr,tmpMap1->value);
483            free(tmpStr);
484          }
485      }
486      json_object_object_add(res,"id",json_object_new_string(tmpName));
487      if(tmpName!=NULL){
488        rUrl=zStrdup(tmpName);
489        free(tmpName);
490      }
491    }
492    else
493      json_object_object_add(res,"id",json_object_new_string(serv->name));
494    if(serv->content!=NULL){
495      map* tmpMap=getMap(serv->content,"title");
496      if(tmpMap!=NULL){
497        json_object_object_add(res,"title",json_object_new_string(tmpMap->value));
498      }
499      tmpMap=getMap(serv->content,"abstract");
500      if(tmpMap!=NULL){
501        json_object_object_add(res,"description",json_object_new_string(tmpMap->value));
502      }
503      tmpMap=getMap(serv->content,"processVersion");
504      if(tmpMap!=NULL){
505        if(strlen(tmpMap->value)<5){
506          char *val=(char*)malloc((strlen(tmpMap->value)+5)*sizeof(char));
507          sprintf(val,"%s.0.0",tmpMap->value);
508          json_object_object_add(res,"version",json_object_new_string(val));
509          free(val);
510        }
511        else
512          json_object_object_add(res,"version",json_object_new_string(tmpMap->value));
513      }else
514        json_object_object_add(res,"version",json_object_new_string("1.0.0"));
515      int limit=4;
516      int i=0;
517      map* sType=getMap(serv->content,"serviceType");
518      for(;i<limit;i+=2){
519        json_object *res1=json_object_new_object();
520        json_object *res2=json_object_new_array();
521        char *saveptr;
522        char* dupStr=strdup(jcapabilities[i+1]);
523        char *tmps = strtok_r (dupStr, " ", &saveptr);
524        while(tmps!=NULL){
525          json_object_array_add(res2,json_object_new_string(tmps));
526          tmps = strtok_r (NULL, " ", &saveptr);
527        }
528        free(dupStr);
529        json_object_object_add(res,jcapabilities[i],res2);
530      }
531      json_object *res1=json_object_new_array();
532      json_object *res2=json_object_new_object();
533      json_object *res3=json_object_new_object();
534      map* pmTmp=getMapFromMaps(m,"lenv","requestType");
535      if(pmTmp!=NULL && strncasecmp(pmTmp->value,"desc",4)==0)
536        json_object_object_add(res2,"rel",json_object_new_string("process-desc"));
537      else{
538        json_object_object_add(res2,"rel",json_object_new_string("execute"));
539        json_object_object_add(res3,"rel",json_object_new_string("alternate"));
540        json_object_object_add(res3,"type",json_object_new_string("text/html"));
541      }
542      json_object_object_add(res2,"type",json_object_new_string("application/json"));
543      json_object_object_add(res2,"title",json_object_new_string("Process Description"));
544      map* tmpUrl=getMapFromMaps(m,"openapi","rootUrl");
545      char* tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(rUrl)+13)*sizeof(char));
546      sprintf(tmpStr,"%s/processes/%s/",tmpUrl->value,rUrl);
547      if(doc==NULL){
548        json_object_object_add(res2,"title",json_object_new_string("Execute End Point"));
549        json_object_object_add(res3,"title",json_object_new_string("Execute End Point"));
550        char* tmpStr1=zStrdup(tmpStr);
551        tmpStr=(char*) realloc(tmpStr,(strlen(tmpStr)+6)*sizeof(char));
552        sprintf(tmpStr,"%sjobs",tmpStr1);
553        free(tmpStr1);
554        char* tmpStr3=(char*) malloc((strlen(tmpStr)+6)*sizeof(char));
555        sprintf(tmpStr3,"%s.html",tmpStr);
556        json_object_object_add(res3,"href",json_object_new_string(tmpStr3));
557        free(tmpStr3);
558      }
559      json_object_object_add(res2,"href",json_object_new_string(tmpStr));
560      free(tmpStr);
561      json_object_array_add(res1,res2);
562      tmpUrl=getMapFromMaps(m,"openapi","partial_html_support");
563      if(tmpUrl!=NULL && strncasecmp(tmpUrl->value,"true",4)==0)
564        json_object_array_add(res1,res3);
565      else
566        json_object_put(res3);
567      json_object_object_add(res,"links",res1);
568    }
569    if(doc==NULL){
570      elements* in=serv->inputs;
571      json_object* inputs=json_object_new_array();
572      printIOTypeJ(m,"input",in,inputs,serv);
573      json_object_object_add(res,"inputs",inputs);
574
575      in=serv->outputs;
576      json_object* outputs=json_object_new_array();
577      printIOTypeJ(m,"output",in,outputs,serv);
578      json_object_object_add(res,"outputs",outputs);
579
580    }
581    if(strcmp(rUrl,serv->name)!=0)
582      free(rUrl);
583    if(doc!=NULL)
584      json_object_array_add(doc,res);
585  }
586
587  /**
588   * Print an OWS ExceptionReport Document and HTTP headers (when required)
589   * depending on the code.
590   * Set hasPrinted value to true in the [lenv] section.
591   *
592   * @param m the maps containing the settings of the main.cfg file
593   * @param s the map containing the text,code,locator keys (or a map array of the same keys)
594   */
595  void printExceptionReportResponseJ(maps* m,map* s){
596    if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
597      return;
598    int buffersize;
599    json_object *res=json_object_new_object();
600
601    maps* tmpMap=getMaps(m,"main");
602    const char *exceptionCode;
603   
604    map* tmp=getMap(s,"code");
605    if(tmp!=NULL){
606      if(strcmp(tmp->value,"OperationNotSupported")==0 ||
607         strcmp(tmp->value,"NoApplicableCode")==0)
608        exceptionCode="500 Not Implemented";
609      else
610        if(strcmp(tmp->value,"MissingParameterValue")==0 ||
611           strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
612           strcmp(tmp->value,"OptionNotSupported")==0 ||
613           strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
614           strcmp(tmp->value,"InvalidParameterValue")==0)
615          exceptionCode="400 Bad request";
616        else
617          if(strcmp(tmp->value,"NotFound")==0 ||
618             strcmp(tmp->value,"NoSuchProcess")==0 ||
619             strcmp(tmp->value,"NoSuchJob")==0 ||
620             strcmp(tmp->value,"ResultNotReady")==0)
621            exceptionCode="404 Not Found";
622          else
623            exceptionCode="500 Internal Server Error";
624      json_object_object_add(res,"code",json_object_new_string(tmp->value));
625    }
626    else{
627      exceptionCode="500 Internal Server Error";
628      json_object_object_add(res,"code",json_object_new_string("NoApplicableCode"));
629    }
630    if(getMapFromMaps(m,"lenv","no-headers")==NULL)
631      printHeaders(m);
632
633    tmp=getMapFromMaps(m,"lenv","status_code");
634    if(tmp!=NULL)
635      exceptionCode=tmp->value;
636    if(getMapFromMaps(m,"lenv","no-headers")==NULL){
637      if(m!=NULL){
638        map *tmpSid=getMapFromMaps(m,"lenv","sid");
639        if(tmpSid!=NULL){
640          if( getpid()==atoi(tmpSid->value) ){
641            printf("Status: %s\r\n\r\n",exceptionCode);
642          }
643        }
644        else{
645          printf("Status: %s\r\n\r\n",exceptionCode);
646        }
647      }else{
648        printf("Status: %s\r\n\r\n",exceptionCode);
649      }
650    }
651    tmp=getMap(s,"text");
652    if(tmp==NULL)
653      tmp=getMap(s,"message");
654    if(tmp==NULL)
655      tmp=getMapFromMaps(m,"lenv","message");
656    if(tmp!=NULL)
657      json_object_object_add(res,"description",json_object_new_string(tmp->value));
658    const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
659    if(getMapFromMaps(m,"lenv","jsonStr")==NULL)
660      setMapInMaps(m,"lenv","jsonStr",jsonStr);
661    maps* pmsTmp=getMaps(m,"lenv");
662    printf(jsonStr);
663    if(m!=NULL)
664      setMapInMaps(m,"lenv","hasPrinted","true");
665  }
666
667  /**
668   * Parse LiteralData value
669   * @param conf the maps containing the settings of the main.cfg file
670   * @param req json_object pointing to the input/output
671   * @param element
672   * @param output the maps to set current json structure
673   */
674  void parseJLiteral(maps* conf,json_object* req,elements* element,maps* output){
675    json_object* json_cinput=NULL;
676    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
677      output->content=createMap("value",json_object_get_string(json_cinput));
678    }
679    const char* tmpStrs[2]={
680      "dataType",
681      "uom"
682    };
683    for(int i=0;i<2;i++)
684      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
685        json_object* json_cinput1;
686        if(json_object_object_get_ex(json_cinput,"name",&json_cinput1)!=FALSE){
687          if(output->content==NULL)
688            output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
689          else
690            addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
691        }
692        if(json_object_object_get_ex(json_cinput,"reference",&json_cinput1)!=FALSE){
693          if(output->content==NULL)
694            output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
695          else
696            addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
697        }
698      }
699    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
700      if(output->content==NULL)
701        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
702      else
703        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
704    }
705  }
706
707  /**
708   * Parse ComplexData value
709   * @param conf the maps containing the settings of the main.cfg file
710   * @param req json_object pointing to the input/output
711   * @param element
712   * @param output the maps to set current json structure
713   * @param name the name of the request from http_requests
714   */
715  void parseJComplex(maps* conf,json_object* req,elements* element,maps* output,const char* name){
716    json_object* json_cinput=NULL;
717    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
718      json_object* json_value=NULL;
719      if(json_object_object_get_ex(json_cinput,"inlineValue",&json_value)!=FALSE)
720        output->content=createMap("value",json_object_get_string(json_value));
721      else{
722        if(json_object_object_get_ex(json_cinput,"href",&json_value)!=FALSE){
723          output->content=createMap("xlink:href",json_object_get_string(json_value));
724          int len=0;
725          int createdStr=0;
726          char *tmpStr="url";
727          char *tmpStr1="input";
728          if(getMaps(conf,"http_requests")==NULL){
729            maps* tmpMaps=createMaps("http_requests");
730            tmpMaps->content=createMap("length","1");
731            addMapsToMaps(&conf,tmpMaps);
732            freeMaps(&tmpMaps);
733            free(tmpMaps);
734          }else{
735            map* tmpMap=getMapFromMaps(conf,"http_requests","length");
736            int len=atoi(tmpMap->value);
737            createdStr=1;
738            tmpStr=(char*) malloc((12)*sizeof(char));
739            sprintf(tmpStr,"%d",len+1);
740            setMapInMaps(conf,"http_requests","length",tmpStr);
741            sprintf(tmpStr,"url_%d",len);
742            tmpStr1=(char*) malloc((14)*sizeof(char));
743            sprintf(tmpStr1,"input_%d",len);
744          }
745          setMapInMaps(conf,"http_requests",tmpStr,json_object_get_string(json_value));
746          setMapInMaps(conf,"http_requests",tmpStr1,name);
747          if(createdStr>0){
748            free(tmpStr);
749            free(tmpStr1);
750          }
751        }
752      }
753    }
754    if(json_object_object_get_ex(req,"format",&json_cinput)!=FALSE){
755      json_object_object_foreach(json_cinput, key, val) {
756        if(output->content==NULL)
757          output->content=createMap(key,json_object_get_string(val));
758        else
759          addToMap(output->content,key,json_object_get_string(val));
760       
761      }
762    }
763    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
764      if(output->content==NULL)
765        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
766      else
767        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
768    }
769  }
770
771  /**
772   * Parse BoundingBox value
773   * @param conf the maps containing the settings of the main.cfg file
774   * @param req json_object pointing to the input/output
775   * @param element
776   * @param output the maps to set current json structure
777   */
778  void parseJBoundingBox(maps* conf,json_object* req,elements* element,maps* output){
779    json_object* json_cinput=NULL;
780    if(json_object_object_get_ex(req,"bbox",&json_cinput)!=FALSE){
781      output->content=createMap("value",json_object_get_string(json_cinput));
782    }
783    if(json_object_object_get_ex(req,"crs",&json_cinput)!=FALSE){
784      if(output->content==NULL)
785        output->content=createMap("crs",json_object_get_string(json_cinput));
786      else
787        addToMap(output->content,"crs","http://www.opengis.net/def/crs/OGC/1.3/CRS84");
788    }
789    char* tmpStrs[2]={
790      "lowerCorner",
791      "upperCorner"
792    };
793    for(int i=0;i<2;i++)
794      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
795        if(output->content==NULL)
796          output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput));
797        else
798          addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput));
799      }
800    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
801      if(output->content==NULL)
802        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
803      else
804        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
805    }
806  }
807
808  /**
809   * Parse inputs / outputs
810   * @param conf the maps containing the settings of the main.cfg file
811   * @param req json_object pointing to the input/output
812   * @param ioElements the elements extracted from the zcfg
813   * @param ioMaps the produced maps containing inputs (or outputs)
814   * @param ioType the char* set to inputs or outputs
815   */
816  void parseJIO(maps* conf, json_object* req, elements* ioElements, maps** ioMaps,const char* ioType){
817    json_object* json_io=NULL;
818    if(json_object_object_get_ex(req,ioType,&json_io)!=FALSE){     
819      json_object* json_current_io=NULL;
820      size_t len=json_object_array_length(json_io);
821      for(int i=0;i<len;i++){
822        maps *cMaps=NULL;
823        json_current_io=json_object_array_get_idx(json_io,i);
824        json_object* cname=NULL;
825        if(json_object_object_get_ex(json_current_io,"id",&cname)!=FALSE){
826          cMaps=createMaps(json_object_get_string(cname));
827          elements* cio=getElements(ioElements,json_object_get_string(cname));
828          json_object* json_input;
829          json_object* json_cinput;
830          if(json_object_object_get_ex(json_current_io,"input",&json_input)!=FALSE){
831            if(json_object_object_get_ex(json_input,"dataType",&json_cinput)!=FALSE){
832              parseJLiteral(conf,json_input,cio,cMaps);
833            } else if(json_object_object_get_ex(json_input,"format",&json_cinput)!=FALSE){
834              parseJComplex(conf,json_input,cio,cMaps,json_object_get_string(cname));
835            } else if(json_object_object_get_ex(json_input,"bbox",&json_cinput)!=FALSE){
836              parseJBoundingBox(conf,json_input,cio,cMaps);
837            }// else error!
838            else{
839              if(json_object_object_get_ex(json_input,"value",&json_cinput)!=FALSE){
840                map* error=createMap("code","BadRequest");
841                char tmpS[1024];
842                sprintf(tmpS,_("Missing input for %s"),ioElements->name);
843                addToMap(error,"message",tmpS);
844                setMapInMaps(conf,"lenv","status_code","400 Bad Request");
845                printExceptionReportResponseJ(conf,error);
846                return;
847              }else{
848                if(json_object_get_type(json_cinput)==json_type_string){
849                  parseJLiteral(conf,json_input,cio,cMaps);
850                }else if(json_object_get_type(json_cinput)==json_type_object){
851                  json_object* json_ccinput=NULL;
852                  if(json_object_object_get_ex(json_cinput,"bbox",&json_ccinput)!=FALSE){
853                    parseJComplex(conf,json_input,cio,cMaps,json_object_get_string(cname));
854                  }
855                  else{
856                    parseJBoundingBox(conf,json_input,cio,cMaps);
857                  }
858                }else{
859                  if(strcmp(ioType,"input")==0){
860                    map* error=createMap("code","BadRequest");
861                    char tmpS1[1024];
862                    sprintf(tmpS1,_("Issue with input %s"),ioElements->name);
863                    addToMap(error,"message",tmpS1);
864                    setMapInMaps(conf,"lenv","status_code","400 Bad Request");
865                    printExceptionReportResponseJ(conf,error);
866                    return;
867                  }
868                }
869              }
870            }
871          }else{
872            if(strcmp(ioType,"input")==0){
873              map* error=createMap("code","BadRequest");
874              char tmpS1[1024];
875              sprintf(tmpS1,_("Missing input for %s"),ioElements->name);
876              addToMap(error,"message",tmpS1);
877              setMapInMaps(conf,"lenv","status_code","400 Bad Request");
878              printExceptionReportResponseJ(conf,error);
879              return;
880            }else{
881              // Outputs
882              if(json_object_object_get_ex(json_current_io,"transmissionMode",&json_cinput)!=FALSE){
883                if(cMaps->content==NULL)
884                  cMaps->content=createMap("transmissionMode",json_object_get_string(json_cinput));
885                else
886                  addToMap(cMaps->content,"transmissionMode",json_object_get_string(json_cinput));
887              }
888              if(json_object_object_get_ex(json_current_io,"format",&json_cinput)!=FALSE){
889                json_object_object_foreach(json_cinput, key, val) {
890                  if(cMaps->content==NULL)
891                    cMaps->content=createMap(key,json_object_get_string(val));
892                  else
893                    addToMap(cMaps->content,key,json_object_get_string(val));
894                }
895              }       
896            }
897          }
898        }
899        addToMap(cMaps->content,"inRequest","true");
900        if (ioMaps == NULL)
901          *ioMaps = dupMaps(&cMaps);
902        else
903          addMapsToMaps (ioMaps, cMaps);
904      }
905    }
906  }
907   
908     
909 
910  /**
911   * Parse Json Request
912   * @param conf the maps containing the settings of the main.cfg file
913   * @param s the current service metadata
914   * @param req the JSON object of the request body
915   * @param inputs the produced maps
916   * @param outputs the produced maps
917   */
918  void parseJRequest(maps* conf, service* s,json_object* req, map* request_inputs, maps** inputs,maps** outputs){
919    elements* io=s->inputs;
920
921    json_object* json_io=NULL;
922    int parsed=0;
923    char* tmpS="input";
924    maps* in=*inputs;
925    parseJIO(conf,req,s->inputs,inputs,"inputs");
926
927    if(parsed==0){
928      json_io=NULL;
929      if(json_object_object_get_ex(req,"outputs",&json_io)!=FALSE){
930        parseJIO(conf,req,s->outputs,outputs,"outputs");
931      }
932      json_io=NULL;
933      if(json_object_object_get_ex(req,"mode",&json_io)!=FALSE){
934        addToMap(request_inputs,"mode",json_object_get_string(json_io));
935        setMapInMaps(conf,"request","mode",json_object_get_string(json_io));
936      }
937      json_io=NULL;
938      if(json_object_object_get_ex(req,"response",&json_io)!=FALSE){
939        addToMap(request_inputs,"response",json_object_get_string(json_io));
940        setMapInMaps(conf,"request","response",json_object_get_string(json_io));
941      }
942      json_io=NULL;
943      if(json_object_object_get_ex(req,"subscriber",&json_io)!=FALSE){
944        maps* subscribers=createMaps("subscriber");
945        json_object* json_subscriber=NULL;
946        if(json_object_object_get_ex(json_io,"successUri",&json_subscriber)!=FALSE){
947          subscribers->content=createMap("successUri",json_object_get_string(json_subscriber));
948        }
949        if(json_object_object_get_ex(json_io,"inProgressUri",&json_subscriber)!=FALSE){
950          if(subscribers->content==NULL)
951            subscribers->content=createMap("inProgressUri",json_object_get_string(json_subscriber));
952          else
953            addToMap(subscribers->content,"inProgressUri",json_object_get_string(json_subscriber));
954        }
955        if(json_object_object_get_ex(json_io,"failedUri",&json_subscriber)!=FALSE){
956          if(subscribers->content==NULL)
957            subscribers->content=createMap("failedUri",json_object_get_string(json_subscriber));
958          else
959            addToMap(subscribers->content,"failedUri",json_object_get_string(json_subscriber));
960        }
961        addMapsToMaps(&conf,subscribers);
962        freeMaps(&subscribers);
963        free(subscribers);
964      }
965    }
966   
967  }
968
969  /**
970   * Print the jobs list
971   *
972   * @param conf the maps containing the settings of the main.cfg file
973   * @return the JSON object pointer to the jobs list
974   */
975  json_object* printJobList(maps* conf){
976    json_object* res=json_object_new_array();
977    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
978    map* oIdentifier=getMapFromMaps(conf,"lenv","oIdentifier");
979    char* cpath=(char*)malloc((strlen(tmpPath->value)+strlen(oIdentifier->value)+14)*sizeof(char));
980    sprintf(cpath,"%s/statusInfos/%s",tmpPath->value,oIdentifier->value);
981    struct dirent *dp;
982    DIR *dirp = opendir (cpath);
983    if(dirp!=NULL){
984      while ((dp = readdir (dirp)) != NULL){
985        char* extn = strstr(dp->d_name, ".json");
986        if(extn!=NULL){
987          json_object* cjob=json_object_new_object();
988          char* tmpStr=zStrdup(dp->d_name);
989          tmpStr[strlen(dp->d_name)-5]=0;
990          json_object_object_add(cjob,"id",json_object_new_string(tmpStr));
991          char *tmps1=(char*)malloc((strlen(cpath)+strlen(dp->d_name)+2)*sizeof(char));
992          sprintf (tmps1, "%s/%s", cpath, dp->d_name);
993          FILE* cdat=fopen(tmps1,"rb");
994          if(cdat!=NULL){
995            zStatStruct f_status;
996            int s=zStat(tmps1, &f_status);
997            char* mystring=(char*)malloc((f_status.st_size+1)*sizeof(char));
998            fread(mystring,1,f_status.st_size,cdat);
999            mystring[f_status.st_size]=0;           
1000            json_object *jobj = NULL;
1001            int slen = 0;
1002            enum json_tokener_error jerr;
1003            struct json_tokener* tok=json_tokener_new();
1004            do {
1005              slen = strlen(mystring);
1006              jobj = json_tokener_parse_ex(tok, mystring, slen);
1007            } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
1008            if (jerr != json_tokener_success) {
1009              fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
1010              return NULL;
1011            }
1012            if (tok->char_offset < slen){
1013              return NULL;
1014            }
1015            json_object_object_add(cjob,"infos",jobj);
1016            free(mystring);
1017            fclose(cdat);
1018          }
1019          free(tmpStr);
1020          json_object_array_add(res,cjob);
1021        }
1022      }
1023      closedir (dirp);
1024    }
1025    return res;
1026  }
1027 
1028  /**
1029   * Print the result of an execution
1030   *
1031   * @param conf the maps containing the settings of the main.cfg file
1032   * @param s service pointer to metadata
1033   * @param result outputs of the service
1034   * @param res the status of execution SERVICE_FAILED/SERVICE_SUCCEEDED
1035   * @return the JSON object pointer to the result
1036   */
1037  json_object* printJResult(maps* conf,service* s,maps* result,int res){
1038    json_object* eres1=json_object_new_object();
1039    if(res==SERVICE_FAILED){
1040      char* pacTmp=produceErrorMessage(conf);
1041      map* pamTmp=createMap("message",pacTmp);
1042      free(pacTmp);
1043      map* pmTmp=getMapFromMaps(conf,"lenv","code");
1044      if(pmTmp!=NULL)
1045        addToMap(pamTmp,"code",pmTmp->value);
1046      printExceptionReportResponseJ(conf,pamTmp);
1047      freeMap(&pamTmp);
1048      free(pamTmp);
1049      return NULL;
1050    }
1051    if(getMapFromMaps(conf,"lenv","no-headers")==NULL)
1052      printHeaders(conf);
1053    json_object* eres=json_object_new_array();
1054    maps* resu=result;
1055    int itn=0;
1056    while(resu!=NULL){
1057      json_object* res1=json_object_new_object();
1058      json_object_object_add(res1,"id",json_object_new_string(resu->name));
1059      map* tmpMap=getMap(resu->content,"mimeType");
1060      json_object* res3=json_object_new_object();
1061      if(tmpMap!=NULL)
1062        json_object_object_add(res3,"mimeType",json_object_new_string(tmpMap->value));
1063      if((tmpMap=getMap(resu->content,"value"))!=NULL ||
1064         (getMap(resu->content,"generated_file"))!=NULL){
1065        json_object* res2=json_object_new_object();
1066        map* tmpMap1=NULL;
1067        if((tmpMap1=getMap(resu->content,"transmissionMode"))!=NULL) {
1068          if(strcmp(tmpMap1->value,"value")==0) {
1069            map* tmpMap2=getMap(resu->content,"mimeType");
1070            if(tmpMap2!=NULL && strstr(tmpMap2->value,"json")!=NULL){
1071              json_object *jobj = NULL;
1072              int slen = 0;
1073              enum json_tokener_error jerr;
1074              struct json_tokener* tok=json_tokener_new();
1075              do {
1076                slen = strlen(tmpMap->value);
1077                jobj = json_tokener_parse_ex(tok, tmpMap->value, slen);
1078              } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
1079              if (jerr != json_tokener_success) {
1080                fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
1081                return eres1;
1082              }
1083              if (tok->char_offset < slen){
1084                return eres1;           
1085              }
1086              json_object_object_add(res3,"encoding",json_object_new_string("utf-8"));
1087              json_object_object_add(res2,"inlineValue",jobj);
1088            }else{
1089              map* tmp1=getMapFromMaps(conf,"main","tmpPath");
1090              map *gfile=getMap(resu->content,"generated_file");
1091              if(gfile!=NULL){
1092                gfile=getMap(resu->content,"expected_generated_file");
1093                if(gfile==NULL){
1094                  gfile=getMap(resu->content,"generated_file");
1095                }
1096                FILE* pfData=fopen(gfile->value,"rb");
1097                if(pfData!=NULL){
1098                  zStatStruct f_status;
1099                  int s=zStat(gfile->value, &f_status);
1100                  char* pcaTmp=(char*)malloc((f_status.st_size+1)*sizeof(char));
1101                  fread(pcaTmp,1,f_status.st_size,pfData);
1102                  pcaTmp[f_status.st_size]=0;       
1103                  fclose(pfData);
1104                  json_object_object_add(res2,"inlineValue",json_object_new_string(base64(pcaTmp,f_status.st_size)));
1105                  json_object_object_add(res3,"encoding",json_object_new_string("base64"));
1106                  free(pcaTmp);
1107                }
1108              }else{
1109                json_object_object_add(res3,"encoding",json_object_new_string("utf-8"));
1110                json_object_object_add(res2,"inlineValue",json_object_new_string(tmpMap->value));
1111              }
1112            }
1113          }
1114          else{
1115            // Create file for reference data if not existing
1116            map *gfile=getMap(resu->content,"generated_file");
1117            char *file_name=NULL;
1118            char *file_path=NULL;
1119            char *file_url=NULL;
1120            map *tmp1=getMapFromMaps(conf,"main","tmpPath");
1121            if(gfile!=NULL){
1122              gfile=getMap(resu->content,"expected_generated_file");
1123              if(gfile==NULL){
1124                gfile=getMap(resu->content,"generated_file");
1125              }
1126              if(strstr(gfile->value,tmp1->value)!=NULL)
1127                file_name=zStrdup(strstr(gfile->value,tmp1->value)+strlen(tmp1->value));
1128            }/*else*/
1129            {
1130              // Create file for reference data
1131              map *tmpUrl=getMapFromMaps(conf,"main","tmpUrl");
1132              map *usid=getMapFromMaps(conf,"lenv","usid");
1133              map *ext=getMap(resu->content,"extension");
1134              if(gfile==NULL){
1135                char file_ext[32];         
1136                if( ext != NULL && ext->value != NULL) {
1137                  strncpy(file_ext, ext->value, 32);
1138                }
1139                else {
1140                  // Obtain default file extension (see mimetypes.h).         
1141                  // If the MIME type is not recognized, txt is used as the default extension
1142                  map* mtype=getMap(resu->content,"mimeType");
1143                  getFileExtension(mtype != NULL ? mtype->value : NULL, file_ext, 32);
1144                }
1145                if(file_name!=NULL)
1146                  free(file_name);
1147             
1148                file_name=(char*)malloc((strlen(s->name)+strlen(usid->value)+strlen(file_ext)+strlen(resu->name)+45)*sizeof(char));
1149                sprintf(file_name,"ZOO_DATA_%s_%s_%s_%d.%s",s->name,resu->name,usid->value,itn,file_ext);
1150
1151                file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
1152                sprintf(file_path,"%s/%s",tmp1->value,file_name);
1153              }else{
1154                file_path=(char*)malloc((strlen(gfile->value)+1)*sizeof(char));
1155                sprintf(file_path,"%s",gfile->value);
1156              }
1157               
1158             
1159              itn++;
1160             
1161              file_url=(char*)malloc((strlen(tmpUrl->value)+
1162                                      strlen(file_name)+2)*sizeof(char));
1163              sprintf(file_url,"%s/%s",tmpUrl->value,file_name);
1164
1165              if(gfile==NULL){
1166                FILE *ofile=fopen(file_path,"wb");
1167                if(ofile==NULL){
1168                  char tmpMsg[1024];
1169                  sprintf(tmpMsg,
1170                          _("Unable to create the file \"%s\" for storing the %s final result."),
1171                          file_name,resu->name);
1172                  map* error=createMap("code","InternalError");
1173                  addToMap(error,"message",tmpMsg);
1174                  printExceptionReportResponseJ(conf,error);
1175                  free(file_name);
1176                  free(file_path);
1177                  return NULL;
1178                }
1179
1180                map* toto=getMap(resu->content,"value");
1181                if(toto==NULL){
1182                  char tmpMsg[1024];
1183                  sprintf(tmpMsg,
1184                          _("No value found for the requested output %s."),
1185                          resu->name);
1186                  map* error=createMap("code","InternalError");
1187                  addToMap(error,"message",tmpMsg);
1188                  printExceptionReportResponseJ(conf,error);
1189                  fclose(ofile);
1190                  free(file_name);
1191                  free(file_path);
1192                  return NULL;
1193                }
1194                map* size=getMap(resu->content,"size");
1195                if(size!=NULL && toto!=NULL)
1196                  fwrite(toto->value,1,(atoi(size->value))*sizeof(char),ofile);
1197                else
1198                  if(toto!=NULL && toto->value!=NULL)
1199                    fwrite(toto->value,1,
1200                           strlen(toto->value)*sizeof(char),ofile);
1201                fclose(ofile);
1202              }
1203              json_object_object_add(res2,"href",
1204                                     json_object_new_string(file_url));
1205              free(file_url);
1206              free(file_name);
1207              free(file_path);
1208             
1209            }
1210           
1211          }
1212        }
1213        json_object_object_add(res1,"value",res2);     
1214        json_object_object_add(res1,"format",res3);     
1215        json_object_array_add(eres,res1);
1216      }
1217      resu=resu->next;
1218    }
1219    json_object_object_add(eres1,"outputs",eres);
1220    const char* jsonStr =
1221      json_object_to_json_string_ext(eres1,JSON_C_TO_STRING_PLAIN);
1222    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1223    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1224    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1225    char *pacTmp=(char*)malloc((strlen(tmpPath->value)+strlen(cIdentifier->value)+strlen(sessId->value)+8)*sizeof(char));
1226    sprintf(pacTmp,"%s/%s_%s.json",
1227            tmpPath->value,cIdentifier->value,sessId->value);
1228    zStatStruct zsFStatus;
1229    int iS=zStat(pacTmp, &zsFStatus);
1230    if(iS==0 && zsFStatus.st_size>0){
1231      map* tmpPath1 = getMapFromMaps (conf, "main", "tmpUrl");
1232      char* pacTmpUrl=(char*)malloc((strlen(tmpPath1->value)+strlen(cIdentifier->value)+strlen(sessId->value)+8)*sizeof(char));;
1233      sprintf(pacTmpUrl,"%s/%s_%s.json",tmpPath1->value,
1234              cIdentifier->value,sessId->value);
1235      if(getMapFromMaps(conf,"lenv","gs_location")==NULL)
1236        setMapInMaps(conf,"headers","Location",pacTmpUrl);
1237      free(pacTmpUrl);
1238    }
1239    free(pacTmp);
1240    if(res==3){
1241      map* mode=getMapFromMaps(conf,"request","mode");
1242      if(mode!=NULL && strncasecmp(mode->value,"async",5)==0)
1243        setMapInMaps(conf,"headers","Status","201 Created");
1244      else
1245        setMapInMaps(conf,"headers","Status","200 Ok");
1246    }
1247    else{
1248      setMapInMaps(conf,"headers","Status","500 Issue running your service");
1249    }
1250    return eres1;
1251  }
1252
1253
1254  /**
1255   * Create the status links
1256   *
1257   * @param conf the maps containing the settings of the main.cfg file
1258   * @param result an integer (>0 for adding the /result link)
1259   * @param obj the JSON object pointer to add the links to
1260   * @return 0
1261   */
1262  int createStatusLinks(maps* conf,int result,json_object* obj){
1263    json_object* res=json_object_new_array();
1264    map *tmpPath = getMapFromMaps (conf, "openapi", "rootUrl");
1265    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1266    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1267    if(sessId==NULL){
1268      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1269    }
1270    char *Url0=(char*) malloc((strlen(tmpPath->value)+
1271                               strlen(cIdentifier->value)+
1272                               strlen(sessId->value)+18)*sizeof(char));
1273    int needResult=-1;
1274    char *message, *status;
1275    sprintf(Url0,"%s/processes/%s/jobs/%s",
1276            tmpPath->value,
1277            cIdentifier->value,
1278            sessId->value);
1279    if(getMapFromMaps(conf,"lenv","gs_location")==NULL)
1280      setMapInMaps(conf,"headers","Location",Url0);
1281    json_object* val=json_object_new_object();
1282    json_object_object_add(val,"title",
1283                           json_object_new_string(_("Status location")));
1284    json_object_object_add(val,"rel",
1285                           json_object_new_string(_("status")));
1286    json_object_object_add(val,"type",
1287                           json_object_new_string(_("application/json")));
1288    json_object_object_add(val,"href",json_object_new_string(Url0));
1289    json_object_array_add(res,val);
1290    if(result>0){
1291      free(Url0);
1292      Url0=(char*) malloc((strlen(tmpPath->value)+
1293                           strlen(cIdentifier->value)+strlen(sessId->value)+
1294                           25)*sizeof(char));
1295      sprintf(Url0,"%s/processes/%s/jobs/%s/results",
1296              tmpPath->value,
1297              cIdentifier->value,
1298              sessId->value);
1299      json_object* val1=json_object_new_object();
1300      json_object_object_add(val1,"title",
1301                             json_object_new_string(_("Result location")));
1302      json_object_object_add(val1,"rel",
1303                             json_object_new_string(_("results")));
1304      json_object_object_add(val1,"type",
1305                             json_object_new_string(_("application/json")));
1306      json_object_object_add(val1,"href",json_object_new_string(Url0));
1307      json_object_array_add(res,val1);
1308    }
1309    json_object_object_add(obj,"links",res);
1310    free(Url0);
1311    return 0;
1312  }
1313
1314  /**
1315   * Get the status file path
1316   *
1317   * @param conf the maps containing the settings of the main.cfg file
1318   * @return a char* containing the full status file path
1319   */
1320  char* json_getStatusFilePath(maps* conf){
1321    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1322    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1323    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1324    if(sessId!=NULL){
1325      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1326      if(sessId==NULL)
1327        sessId = getMapFromMaps (conf, "lenv", "usid");
1328    }else
1329      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1330    char *tmp1=(char*) malloc((strlen(tmpPath->value)+
1331                               strlen(cIdentifier->value)+14)*sizeof(char));
1332    sprintf(tmp1,"%s/statusInfos/%s",
1333            tmpPath->value,
1334            cIdentifier->value);
1335    if(mkdir(tmp1,0777) != 0 && errno != EEXIST){
1336      fprintf(stderr,"Issue creating directory %s\n",tmp1);
1337      return NULL;
1338    }
1339    tmp1=(char*) realloc(tmp1,(strlen(tmpPath->value)+
1340                         strlen(cIdentifier->value)+
1341                         strlen(sessId->value)+21)*sizeof(char));
1342    int needResult=0;
1343    char *message, *rstatus;
1344    sprintf(tmp1,"%s/statusInfos/%s/%s.json",
1345            tmpPath->value,
1346            cIdentifier->value,
1347            sessId->value);
1348    return tmp1;
1349  }
1350
1351  char* getResultPath(maps* conf,char* jobId){
1352    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1353    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1354    char *pacUrl=(char*) malloc((strlen(tmpPath->value)+
1355                                 strlen(cIdentifier->value)+
1356                                 strlen(jobId)+8)*sizeof(char));
1357    sprintf(pacUrl,"%s/%s_%s.json",tmpPath->value,
1358            cIdentifier->value,jobId);
1359    return pacUrl;
1360  }
1361
1362  json_object* parseJson(maps* conf,char* myString){
1363    json_object *pajObj = NULL;
1364    enum json_tokener_error jerr;
1365    struct json_tokener* tok=json_tokener_new();
1366    int slen = 0;
1367    do {
1368      slen = strlen(myString);
1369      pajObj = json_tokener_parse_ex(tok, myString, slen);
1370    } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
1371    if (jerr != json_tokener_success) {
1372      setMapInMaps(conf,"lenv","message",json_tokener_error_desc(jerr));
1373      fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
1374      return NULL;
1375    }
1376    if (tok->char_offset < slen){
1377      fprintf(stderr, "Error parsing json\n");
1378      return NULL;
1379    }
1380    return pajObj;
1381  }
1382 
1383  json_object* json_readFile(maps* conf,char* filePath){
1384    json_object *pajObj = NULL;
1385    zStatStruct zsFStatus;
1386    int iS=zStat(filePath, &zsFStatus);
1387    if(iS==0 && zsFStatus.st_size>0){
1388      FILE* cdat=fopen(filePath,"rb");
1389      if(cdat!=NULL){
1390        char* pacMyString=(char*)malloc((zsFStatus.st_size+1)*sizeof(char));
1391        fread(pacMyString,1,zsFStatus.st_size,cdat);
1392        pacMyString[zsFStatus.st_size]=0;
1393        fclose(cdat);
1394        pajObj=parseJson(conf,pacMyString);
1395        free(pacMyString);
1396      }
1397      else
1398        return NULL;
1399    }else
1400      return NULL;
1401    return pajObj;
1402  }
1403 
1404  json_object* createStatus(maps* conf,int status){
1405    int needResult=0;
1406    const char *rstatus;
1407    char *message;
1408    // Create statusInfo JSON object
1409    // cf. https://github.com/opengeospatial/wps-rest-binding/blob/master/core/
1410    //     openapi/schemas/statusInfo.yaml
1411    json_object* res=json_object_new_object();
1412    switch(status){
1413    case SERVICE_ACCEPTED:
1414      {
1415        message=_("ZOO-Kernel accepted to run your service!");
1416        rstatus="accepted";
1417        break;
1418      }
1419    case SERVICE_STARTED:
1420      {
1421        message=_("ZOO-Kernel is currently running your service!");
1422        map* pmStatus=getMapFromMaps(conf,"lenv","status");
1423        if(pmStatus!=NULL)
1424          setMapInMaps(conf,"lenv","PercentCompleted",pmStatus->value);
1425        pmStatus=getMapFromMaps(conf,"lenv","message");
1426        if(pmStatus!=NULL)
1427          setMapInMaps(conf,"lenv","gs_message",pmStatus->value);
1428        rstatus="running";
1429        break;
1430      }
1431    case SERVICE_PAUSED:
1432      {
1433        message=_("ZOO-Kernel pause your service!");
1434        rstatus="paused";
1435        break;
1436      }
1437    case SERVICE_SUCCEEDED:
1438      {
1439        message=_("ZOO-Kernel successfully run your service!");
1440        rstatus="successful";
1441        setMapInMaps(conf,"lenv","PercentCompleted","100");
1442        needResult=1;
1443        break;
1444      }
1445    case SERVICE_DISMISSED:
1446      {
1447        message=_("ZOO-Kernel successfully dismissed your service!");
1448        rstatus="dismissed";
1449        needResult=1;
1450        break;
1451      }
1452    default:
1453      {
1454        map* pmTmp=getMapFromMaps(conf,"lenv","force");
1455        if(pmTmp==NULL || strncasecmp(pmTmp->value,"false",5)==0){
1456          char* pacTmp=json_getStatusFilePath(conf);
1457          json_object* pjoStatus=json_readFile(conf,pacTmp);
1458          free(pacTmp);
1459          if(pjoStatus!=NULL){
1460            json_object* pjoMessage=NULL;
1461            if(json_object_object_get_ex(pjoStatus,"message",&pjoMessage)!=FALSE){
1462              message=(char*)json_object_get_string(pjoMessage);
1463            }
1464          }
1465          // TODO: Error
1466        }else{
1467          map* mMap=getMapFromMaps(conf,"lenv","gs_message");
1468          if(mMap!=NULL)
1469            setMapInMaps(conf,"lenv","message",mMap->value);
1470          message=produceErrorMessage(conf);
1471          needResult=-1;
1472        }
1473        rstatus="failed";
1474        break;
1475      }
1476    }
1477    setMapInMaps(conf,"lenv","message",message);
1478    setMapInMaps(conf,"lenv","status",rstatus);
1479
1480    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1481    if(sessId!=NULL){
1482      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1483      if(sessId==NULL)
1484        sessId = getMapFromMaps (conf, "lenv", "usid");
1485    }else
1486      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1487    if(sessId!=NULL)
1488      json_object_object_add(res,"jobID",json_object_new_string(sessId->value));
1489    json_object_object_add(res,"status",json_object_new_string(rstatus));
1490    map* mMap=getMapFromMaps(conf,"lenv","gs_message");
1491    if(mMap==NULL)
1492      json_object_object_add(res,"message",json_object_new_string(message));
1493    else{
1494      json_object_object_add(res,"message",json_object_new_string(mMap->value));
1495      if((mMap=getMapFromMaps(conf,"lenv","PercentCompleted"))!=NULL)
1496        json_object_object_add(res,"progress",json_object_new_int(atoi(mMap->value)));
1497    }
1498    if(status!=SERVICE_DISMISSED)
1499      createStatusLinks(conf,needResult,res);
1500    else{
1501      json_object* res1=json_object_new_array();
1502      map *tmpPath = getMapFromMaps (conf, "openapi", "rootUrl");
1503      map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1504      char *Url0=(char*) malloc((strlen(tmpPath->value)+
1505                                 strlen(cIdentifier->value)+
1506                                 17)*sizeof(char));
1507      sprintf(Url0,"%s/processes/%s/jobs",           
1508              tmpPath->value,
1509              cIdentifier->value);
1510      json_object* val=json_object_new_object();
1511      json_object_object_add(val,"title",
1512                             json_object_new_string(_("The job list for the current process")));
1513      json_object_object_add(val,"rel",
1514                             json_object_new_string(_("parent")));
1515      json_object_object_add(val,"type",
1516                             json_object_new_string(_("application/json")));
1517      json_object_object_add(val,"href",json_object_new_string(Url0));
1518      json_object_array_add(res1,val);
1519      free(Url0);
1520      json_object_object_add(res,"links",res1);
1521    }
1522    if(needResult<0)
1523      free(message);
1524    return res;
1525  }
1526 
1527  /**
1528   * Create the status file
1529   *
1530   * @param conf the maps containing the settings of the main.cfg file
1531   * @param status an integer (SERVICE_ACCEPTED,SERVICE_STARTED...)
1532   * @return an integer (0 in case of success, 1 in case of failure)
1533   */
1534  int createStatusFile(maps* conf,int status){
1535    json_object* res=createStatus(conf,status);
1536    char* tmp1=json_getStatusFilePath(conf);
1537    FILE* foutput1=fopen(tmp1,"w+");
1538    if(foutput1!=NULL){
1539      const char* jsonStr1=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
1540      fprintf(foutput1,"%s",jsonStr1);
1541      fclose(foutput1);
1542    }else{
1543      // Failure
1544      setMapInMaps(conf,"lenv","message",_("Unable to store the statusInfo!"));
1545      free(tmp1);
1546      return 1;
1547    }
1548    free(tmp1);
1549    return 0;
1550  }
1551
1552  /**
1553   * Create the status file
1554   *
1555   * @param conf the maps containing the settings of the main.cfg file
1556   * @return an integer (0 in case of success, 1 in case of failure)
1557   */
1558  int json_getStatusFile(maps* conf){
1559    char* tmp1=json_getStatusFilePath(conf);
1560    FILE* statusFile=fopen(tmp1,"rb");
1561
1562    map* tmpMap=getMapFromMaps(conf,"lenv","gs_usid");
1563    if(tmpMap!=NULL){
1564      char* tmpStr=_getStatus(conf,tmpMap->value);
1565      if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1566        char *tmpStr1=zStrdup(tmpStr);
1567        char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1568        free(tmpStr);
1569        tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1570        setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
1571        setMapInMaps(conf,"lenv","gs_message",tmpStr0);
1572        free(tmpStr0);
1573        free(tmpStr1);
1574        return 0;
1575      }else{
1576         
1577      }
1578    }
1579  }
1580
1581  /**
1582   * Produce the JSON object for api info object
1583   *
1584   * @param conf the maps containing the settings of the main.cfg file
1585   * @param res the JSON object for the api info
1586   */
1587  void produceApiInfo(maps* conf,json_object* res,json_object* res5){
1588    json_object *res1=json_object_new_object();
1589    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
1590    if(tmpMap!=NULL){
1591      json_object *res2=json_object_new_object();
1592      json_object_object_add(res2,"name",json_object_new_string(tmpMap->value));
1593      tmpMap=getMapFromMaps(conf,"provider","addressElectronicMailAddress");
1594      if(tmpMap!=NULL)
1595        json_object_object_add(res2,"email",json_object_new_string(tmpMap->value));
1596      tmpMap=getMapFromMaps(conf,"provider","providerSite");
1597      if(tmpMap!=NULL)
1598        json_object_object_add(res2,"url",json_object_new_string(tmpMap->value));
1599      json_object_object_add(res1,"contact",res2);
1600    }
1601    tmpMap=getMapFromMaps(conf,"identification","abstract");
1602    if(tmpMap!=NULL){
1603      json_object_object_add(res1,"description",json_object_new_string(tmpMap->value));
1604      json_object_object_add(res5,"description",json_object_new_string(tmpMap->value));
1605      tmpMap=getMapFromMaps(conf,"openapi","rootUrl");
1606      json_object_object_add(res5,"url",json_object_new_string(tmpMap->value));
1607    }
1608    tmpMap=getMapFromMaps(conf,"identification","title");
1609    if(tmpMap!=NULL)
1610      json_object_object_add(res1,"title",json_object_new_string(tmpMap->value));
1611    json_object_object_add(res1,"version",json_object_new_string(ZOO_VERSION));
1612    tmpMap=getMapFromMaps(conf,"identification","keywords");
1613    if(tmpMap!=NULL){
1614      char *saveptr;
1615      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
1616      json_object *res3=json_object_new_array();
1617      while (tmps != NULL){
1618        json_object_array_add(res3,json_object_new_string(tmps));
1619        tmps = strtok_r (NULL, ",", &saveptr);
1620      }
1621      json_object_object_add(res1,"x-keywords",res3);
1622    }
1623    maps* tmpMaps=getMaps(conf,"provider");
1624    if(tmpMaps!=NULL){
1625      json_object *res4=json_object_new_object();
1626      map* cItem=tmpMaps->content;
1627      while(cItem!=NULL){
1628        json_object_object_add(res4,cItem->name,json_object_new_string(cItem->value));
1629        cItem=cItem->next;
1630      }
1631      json_object_object_add(res1,"x-ows-servicecontact",res4);
1632    }
1633
1634    json_object *res4=json_object_new_object();
1635    tmpMap=getMapFromMaps(conf,"openapi","license_name");
1636    if(tmpMap!=NULL){
1637      json_object_object_add(res4,"name",json_object_new_string(tmpMap->value));
1638      tmpMap=getMapFromMaps(conf,"openapi","license_url");
1639      if(tmpMap!=NULL){
1640        json_object_object_add(res4,"url",json_object_new_string(tmpMap->value));     
1641      }
1642    }
1643    json_object_object_add(res1,"license",res4);
1644
1645    json_object_object_add(res,"info",res1);   
1646  }
1647
1648  // addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
1649  void addResponse(const map* useContent,json_object* res,const map* pmSchema,const map* pmType,const char* code,const char* msg){
1650    json_object *cc=json_object_new_object();
1651    if(pmSchema!=NULL)
1652      json_object_object_add(cc,"$ref",json_object_new_string(pmSchema->value));
1653    if(useContent!=NULL && strncasecmp(useContent->value,"true",4)!=0){
1654        json_object_object_add(res,code,cc);
1655    }else{
1656        json_object *cc0=json_object_new_object();
1657        if(pmSchema!=NULL)
1658          json_object_object_add(cc0,"schema",cc);
1659        json_object *cc1=json_object_new_object();
1660        if(pmType!=NULL)
1661          json_object_object_add(cc1,pmType->value,cc0);
1662        else
1663          json_object_object_add(cc1,"application/json",cc0);
1664        json_object *cc2=json_object_new_object();
1665        json_object_object_add(cc2,"content",cc1);
1666        json_object_object_add(cc2,"description",json_object_new_string(msg));
1667        json_object_object_add(res,code,cc2);
1668    }
1669  }
1670
1671  void addParameter(maps* conf,const char* oName,const char* fName,const char* in,json_object* res){
1672    maps* tmpMaps1=getMaps(conf,oName);
1673    json_object *res8=json_object_new_object();
1674    if(tmpMaps1!=NULL){
1675      map* tmpMap=getMap(tmpMaps1->content,"title");
1676      if(tmpMap!=NULL)
1677        json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
1678      tmpMap=getMap(tmpMaps1->content,"abstract");
1679      if(tmpMap!=NULL)
1680        json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
1681      tmpMap=getMap(tmpMaps1->content,"example");
1682      if(tmpMap!=NULL)
1683        json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
1684      tmpMap=getMap(tmpMaps1->content,"required");
1685      if(tmpMap!=NULL){
1686        if(strcmp(tmpMap->value,"true")==0)
1687          json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
1688        else
1689          json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
1690      }
1691      else
1692        json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
1693      json_object_object_add(res8,"in",json_object_new_string(in));
1694      json_object_object_add(res8,"name",json_object_new_string(fName));
1695      json_object *res6=json_object_new_object();
1696      tmpMap=getMap(tmpMaps1->content,"type");
1697      if(tmpMap!=NULL)
1698        json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
1699      else
1700        json_object_object_add(res6,"type",json_object_new_string("string"));
1701       
1702      json_object_object_add(res8,"schema",res6);
1703       
1704    }   
1705    json_object_object_add(res,fName,res8);   
1706  }
1707 
1708  /**
1709   * Produce the JSON object for api parameter
1710   *
1711   * @param conf the maps containing the settings of the main.cfg file
1712   * @param res the JSON object to populate with the parameters
1713   */
1714  void produceApiParameters(maps* conf,json_object* res){
1715    json_object *res9=json_object_new_object();
1716    maps* tmpMaps1=getMaps(conf,"{id}");
1717    map* tmpMap2=getMapFromMaps(conf,"openapi","parameters");
1718    char *saveptr12;
1719    char *tmps12 = strtok_r (tmpMap2->value, ",", &saveptr12);
1720    while(tmps12!=NULL){
1721      char* pacId=(char*) malloc((strlen(tmps12)+3)*sizeof(char));
1722      sprintf(pacId,"{%s}",tmps12);
1723      addParameter(conf,pacId,tmps12,"path",res9);
1724      free(pacId);
1725      tmps12 = strtok_r (NULL, ",", &saveptr12);
1726    }   
1727    tmpMap2=getMapFromMaps(conf,"openapi","header_parameters");
1728    if(tmpMap2!=NULL){
1729      char *saveptr13;
1730      char *tmps13 = strtok_r (tmpMap2->value, ",", &saveptr13);
1731      while(tmps13!=NULL){
1732        char* pacId=zStrdup(tmps13);
1733        addParameter(conf,pacId,pacId,"header",res9);
1734        free(pacId);
1735        tmps13 = strtok_r (NULL, ",", &saveptr13);
1736      }
1737    }
1738    json_object_object_add(res,"parameters",res9);
1739    maps* pmResponses=getMaps(conf,"responses");
1740    if(pmResponses!=NULL){
1741      json_object *cc=json_object_new_object();
1742      map* pmLen=getMap(pmResponses->content,"length");
1743      int iLen=atoi(pmLen->value);
1744      map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
1745      for(int i=0;i<iLen;i++){
1746        map* cMap=getMapArray(pmResponses->content,"code",i);
1747        map* vMap=getMapArray(pmResponses->content,"schema",i);
1748        map* tMap=getMapArray(pmResponses->content,"type",i);
1749        map* tMap0=getMapArray(pmResponses->content,"title",i);
1750        if(vMap!=NULL)
1751          addResponse(pmUseContent,cc,vMap,tMap,cMap->value,(tMap0==NULL)?"successful operation":tMap0->value);
1752      }
1753      json_object_object_add(res,"responses",cc);
1754    }
1755  }
1756
1757  void produceApiComponents(maps*conf,json_object* res){
1758    json_object* res1=json_object_new_object();
1759    produceApiParameters(conf,res1);
1760    json_object_object_add(res,"components",res1);
1761  }
1762 
1763  /**
1764   * Produce the JSON object for /api
1765   *
1766   * @param conf the maps containing the settings of the main.cfg file
1767   * @param res the JSON object to populate
1768   */
1769  void produceApi(maps* conf,json_object* res){
1770    // TODO: add 401 Gone for dismiss request
1771    json_object *res9=json_object_new_object();
1772    json_object *res10=json_object_new_object();
1773    maps* tmpMaps1=getMaps(conf,"{id}");
1774    produceApiComponents(conf,res);
1775    json_object *res4=json_object_new_object();
1776    setMapInMaps(conf,"headers","Content-Type","application/openapi+json; version=3.0;charset=UTF-8");
1777
1778    produceApiInfo(conf,res,res4);
1779    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
1780
1781    tmpMap=getMapFromMaps(conf,"openapi","version");
1782    if(tmpMap!=NULL)
1783      json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
1784    else
1785      json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
1786
1787    tmpMap=getMapFromMaps(conf,"openapi","paths");
1788    if(tmpMap!=NULL){
1789      json_object *res5=json_object_new_object();
1790      char *saveptr;
1791      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
1792      int cnt=0;
1793      maps* tmpMaps;
1794      json_object *paths=json_object_new_object();
1795      while (tmps != NULL){
1796        tmpMaps=getMaps(conf,tmps+1);
1797        json_object *method=json_object_new_object();
1798        if(tmpMaps!=NULL){
1799          if(getMap(tmpMaps->content,"length")==NULL)
1800            addToMap(tmpMaps->content,"length","1");
1801          map* len=getMap(tmpMaps->content,"length");
1802           
1803          for(int i=0;i<atoi(len->value);i++){
1804            json_object *methodc=json_object_new_object();
1805            map* cMap=getMapArray(tmpMaps->content,"method",i);
1806            map* vMap=getMapArray(tmpMaps->content,"title",i);
1807            if(vMap!=NULL)
1808              json_object_object_add(methodc,"summary",json_object_new_string(vMap->value));
1809            vMap=getMapArray(tmpMaps->content,"abstract",i);
1810            if(vMap!=NULL)
1811              json_object_object_add(methodc,"description",json_object_new_string(vMap->value));
1812            vMap=getMapArray(tmpMaps->content,"tags",i);
1813            if(vMap!=NULL){
1814              json_object *cc=json_object_new_array();
1815              json_object_array_add(cc,json_object_new_string(vMap->value));
1816              json_object_object_add(methodc,"tags",cc);
1817              json_object_object_add(methodc,"operationId",json_object_new_string(vMap->value));
1818
1819            }
1820            json_object *responses=json_object_new_object();
1821            json_object *cc3=json_object_new_object();
1822            map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
1823            vMap=getMapArray(tmpMaps->content,"schema",i);
1824            if(vMap!=NULL){
1825              map* tMap=getMapArray(tmpMaps->content,"type",i);
1826              addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
1827              vMap=getMapArray(tmpMaps->content,"eschema",i);
1828              if(vMap!=NULL && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
1829                addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
1830            }else{
1831              map* tMap=getMapFromMaps(conf,tmps,"type");
1832              map* pMap=createMap("ok","true");
1833              addResponse(pMap,cc3,vMap,tMap,"200","successful operation");
1834              if(cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
1835                addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
1836            }
1837            vMap=getMapArray(tmpMaps->content,"ecode",i);
1838            if(vMap!=NULL){
1839              char *saveptr0;
1840              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
1841              while(tmps1!=NULL){
1842                char* tmpStr=(char*)malloc((strlen(tmps1)+24)*sizeof(char));
1843                sprintf(tmpStr,"#/components/responses/%s",tmps1);
1844                vMap=createMap("ok",tmpStr);
1845                map* pMap=createMap("ok","false");
1846                //TODO: fix successful operation with correct value
1847                addResponse(pMap,cc3,vMap,NULL,tmps1,"successful operation");
1848                tmps1 = strtok_r (NULL, ",", &saveptr0);
1849              }
1850            }else{
1851              if(strstr(tmps,"{id}")!=NULL){
1852                vMap=getMapFromMaps(conf,"exception","schema");
1853                map* tMap=getMapFromMaps(conf,"exception","type");
1854                if(vMap!=NULL)
1855                  addResponse(pmUseContent,cc3,vMap,tMap,"404",
1856                              (strstr(tmps,"{jobID}")==NULL)?"The process with id {id} does not exist.":"The process with id {id} or job with id {jobID} does not exist.");
1857              }
1858            }
1859            json_object_object_add(methodc,"responses",cc3);
1860            vMap=getMapArray(tmpMaps->content,"parameters",i);
1861            if(vMap!=NULL){
1862              char *saveptr0;
1863              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
1864              json_object *cc2=json_object_new_array();
1865              int cnt=0;
1866              while(tmps1!=NULL){
1867                char* tmpStr=(char*)malloc((strlen(tmps1)+2)*sizeof(char));
1868                sprintf(tmpStr,"#%s",tmps1);
1869                json_object *cc1=json_object_new_object();
1870                json_object_object_add(cc1,"$ref",json_object_new_string(tmpStr));
1871                json_object_array_add(cc2,cc1);
1872                free(tmpStr);
1873                cnt++;
1874                tmps1 = strtok_r (NULL, ",", &saveptr0);
1875              }
1876              json_object_object_add(methodc,"parameters",cc2);
1877            }
1878            if(i==1 && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0){
1879              maps* tmpMaps1=getMaps(conf,"requestBody");
1880              if(tmpMaps1!=NULL){
1881                vMap=getMap(tmpMaps1->content,"schema");
1882                if(vMap!=NULL){
1883                  json_object *cc=json_object_new_object();
1884                  json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
1885                  json_object *cc0=json_object_new_object();
1886                  json_object_object_add(cc0,"schema",cc);
1887                  json_object *cc1=json_object_new_object();
1888                  map* tmpMap3=getMap(tmpMaps->content,"type");
1889                  if(tmpMap3!=NULL)
1890                    json_object_object_add(cc1,tmpMap3->value,cc0);
1891                  else
1892                    json_object_object_add(cc1,"application/json",cc0);
1893                  json_object *cc2=json_object_new_object();
1894                  json_object_object_add(cc2,"content",cc1);
1895                  vMap=getMap(tmpMaps1->content,"abstract");
1896                  if(vMap!=NULL)
1897                    json_object_object_add(cc2,"description",json_object_new_string(vMap->value));
1898                  json_object_object_add(cc2,"required",json_object_new_boolean(true));
1899                  json_object_object_add(methodc,"requestBody",cc2);
1900
1901                }               
1902              }
1903              // TODO: callbacks
1904              tmpMaps1=getMaps(conf,"callbacks");
1905              if(tmpMaps1!=NULL){
1906                map* pmTmp2=getMap(tmpMaps1->content,"length");
1907                int iLen=atoi(pmTmp2->value);
1908                json_object *pajRes=json_object_new_object();
1909                for(int i=0;i<iLen;i++){
1910                  map* pmState=getMapArray(tmpMaps1->content,"state",i);
1911                  map* pmUri=getMapArray(tmpMaps1->content,"uri",i);
1912                  map* pmSchema=getMapArray(tmpMaps1->content,"schema",i);
1913                  map* pmType=getMapArray(tmpMaps1->content,"type",i);
1914                  map* pmTitle=getMapArray(tmpMaps1->content,"title",i);
1915                  json_object *pajSchema=json_object_new_object();
1916                  if(pmSchema!=NULL)
1917                    json_object_object_add(pajSchema,"$ref",json_object_new_string(pmSchema->value));
1918                  json_object *pajType=json_object_new_object();
1919                  json_object_object_add(pajType,"schema",pajSchema);
1920                  json_object *pajContent=json_object_new_object();
1921                  if(pmType!=NULL)
1922                    json_object_object_add(pajContent,pmType->value,pajType);
1923                  else           
1924                    json_object_object_add(pajContent,"application/json",pajType);
1925                  json_object *pajRBody=json_object_new_object();
1926                  json_object_object_add(pajRBody,"content",pajContent);
1927                 
1928                  json_object *pajDescription=json_object_new_object();
1929                  json_object *pajPost=json_object_new_object();
1930                  if(pmTitle!=NULL){
1931                    json_object_object_add(pajDescription,"description",json_object_new_string(pmTitle->value));
1932                    json_object_object_add(pajPost,"summary",json_object_new_string(pmTitle->value));
1933                  }
1934                  json_object *pajResponse=json_object_new_object();
1935                  json_object_object_add(pajResponse,"200",pajDescription);
1936
1937                  json_object_object_add(pajPost,"requestBody",pajRBody);
1938                  json_object_object_add(pajPost,"responses",pajResponse);
1939                  json_object_object_add(pajPost,"operationId",json_object_new_string(pmState->value));
1940
1941                  json_object *pajMethod=json_object_new_object();
1942                  json_object_object_add(pajMethod,"post",pajPost);
1943
1944                 
1945                  char* pacUri=(char*) malloc((strlen(pmUri->value)+29)*sizeof(char));
1946                  sprintf(pacUri,"{$request.body#/subscriber/%s}",pmUri->value);
1947
1948                  json_object *pajFinal=json_object_new_object();
1949                  json_object_object_add(pajFinal,pacUri,pajMethod);
1950                  json_object_object_add(pajRes,pmState->value,pajFinal);
1951
1952                }
1953                json_object_object_add(methodc,"callbacks",pajRes);
1954              }
1955            }
1956            map* mMap=getMapArray(tmpMaps->content,"method",i);
1957            if(mMap!=NULL)
1958              json_object_object_add(method,mMap->value,methodc);
1959            else
1960              json_object_object_add(method,"get",methodc);
1961
1962          }
1963
1964          tmpMap=getMapFromMaps(conf,"openapi","version");
1965          if(tmpMap!=NULL)
1966            json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
1967          else
1968            json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
1969          if(strstr(tmps,"/root")!=NULL)
1970            json_object_object_add(paths,"/",method);
1971          else
1972            json_object_object_add(paths,tmps,method);
1973        }
1974        tmps = strtok_r (NULL, ",", &saveptr);
1975        cnt++;
1976      }
1977      json_object_object_add(res,"paths",paths);
1978    }
1979     
1980    tmpMap=getMapFromMaps(conf,"openapi","links");
1981    if(tmpMap!=NULL){
1982       
1983    }
1984   
1985    json_object *res3=json_object_new_array();
1986    json_object_array_add(res3,res4);
1987    json_object_object_add(res,"servers",res3);
1988  }
1989 
1990#ifdef __cplusplus
1991}
1992#endif
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