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

Last change on this file was 986, checked in by djay, 3 years ago

Move the execute endpoint to /processes/{processID}. Fixes in oas.cfg: use opengeospatial/ogcapi-processes github repo for schemas URLs.

  • Property svn:keywords set to Id
File size: 70.4 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,"mediaType",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      }
538      else{
539        json_object_object_add(res2,"rel",json_object_new_string("execute"));
540      }
541      json_object_object_add(res3,"rel",json_object_new_string("alternate"));
542      json_object_object_add(res3,"type",json_object_new_string("text/html"));
543      json_object_object_add(res2,"type",json_object_new_string("application/json"));
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(pmTmp!=NULL && strncasecmp(pmTmp->value,"desc",4)!=0){
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      }else{
555        json_object_object_add(res2,"title",json_object_new_string("Process Description"));
556        json_object_object_add(res3,"title",json_object_new_string("Process Description"));
557      }
558      char* tmpStr3=(char*) malloc((strlen(tmpStr)+6)*sizeof(char));
559      sprintf(tmpStr3,"%s.html",tmpStr);
560      json_object_object_add(res3,"href",json_object_new_string(tmpStr3));
561      free(tmpStr3);
562      json_object_object_add(res2,"href",json_object_new_string(tmpStr));
563      free(tmpStr);
564      json_object_array_add(res1,res2);
565      tmpUrl=getMapFromMaps(m,"openapi","partial_html_support");
566      if(tmpUrl!=NULL && strncasecmp(tmpUrl->value,"true",4)==0)
567        json_object_array_add(res1,res3);
568      else
569        json_object_put(res3);
570      json_object_object_add(res,"links",res1);
571    }
572    if(doc==NULL){
573      elements* in=serv->inputs;
574      json_object* inputs=json_object_new_array();
575      printIOTypeJ(m,"input",in,inputs,serv);
576      json_object_object_add(res,"inputs",inputs);
577
578      in=serv->outputs;
579      json_object* outputs=json_object_new_array();
580      printIOTypeJ(m,"output",in,outputs,serv);
581      json_object_object_add(res,"outputs",outputs);
582
583    }
584    if(strcmp(rUrl,serv->name)!=0)
585      free(rUrl);
586    if(doc!=NULL)
587      json_object_array_add(doc,res);
588  }
589
590  /**
591   * Print an OWS ExceptionReport Document and HTTP headers (when required)
592   * depending on the code.
593   * Set hasPrinted value to true in the [lenv] section.
594   *
595   * @param m the maps containing the settings of the main.cfg file
596   * @param s the map containing the text,code,locator keys (or a map array of the same keys)
597   */
598  void printExceptionReportResponseJ(maps* m,map* s){
599    if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
600      return;
601    int buffersize;
602    json_object *res=json_object_new_object();
603
604    maps* tmpMap=getMaps(m,"main");
605    const char *exceptionCode;
606   
607    map* tmp=getMap(s,"code");
608    exceptionCode=produceStatusString(m,tmp);   
609    if(tmp!=NULL){
610      json_object_object_add(res,"code",json_object_new_string(tmp->value));
611    }
612    else{
613      json_object_object_add(res,"code",json_object_new_string("NoApplicableCode"));
614    }
615    if(getMapFromMaps(m,"lenv","no-headers")==NULL)
616      printHeaders(m);
617
618    tmp=getMapFromMaps(m,"lenv","status_code");
619    if(tmp!=NULL)
620      exceptionCode=tmp->value;
621    if(getMapFromMaps(m,"lenv","no-headers")==NULL){
622      if(m!=NULL){
623        map *tmpSid=getMapFromMaps(m,"lenv","sid");
624        if(tmpSid!=NULL){
625          if( getpid()==atoi(tmpSid->value) ){
626            printf("Status: %s\r\n\r\n",exceptionCode);
627          }
628        }
629        else{
630          printf("Status: %s\r\n\r\n",exceptionCode);
631        }
632      }else{
633        printf("Status: %s\r\n\r\n",exceptionCode);
634      }
635    }
636    tmp=getMap(s,"text");
637    if(tmp==NULL)
638      tmp=getMap(s,"message");
639    if(tmp==NULL)
640      tmp=getMapFromMaps(m,"lenv","message");
641    if(tmp!=NULL)
642      json_object_object_add(res,"description",json_object_new_string(tmp->value));
643    const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
644    if(getMapFromMaps(m,"lenv","jsonStr")==NULL)
645      setMapInMaps(m,"lenv","jsonStr",jsonStr);
646    maps* pmsTmp=getMaps(m,"lenv");
647    printf(jsonStr);
648    if(m!=NULL)
649      setMapInMaps(m,"lenv","hasPrinted","true");
650  }
651
652  /**
653   * Parse LiteralData value
654   * @param conf the maps containing the settings of the main.cfg file
655   * @param req json_object pointing to the input/output
656   * @param element
657   * @param output the maps to set current json structure
658   */
659  void parseJLiteral(maps* conf,json_object* req,elements* element,maps* output){
660    json_object* json_cinput=NULL;
661    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
662      output->content=createMap("value",json_object_get_string(json_cinput));
663    }
664    const char* tmpStrs[2]={
665      "dataType",
666      "uom"
667    };
668    for(int i=0;i<2;i++)
669      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
670        json_object* json_cinput1;
671        if(json_object_object_get_ex(json_cinput,"name",&json_cinput1)!=FALSE){
672          if(output->content==NULL)
673            output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
674          else
675            addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
676        }
677        if(json_object_object_get_ex(json_cinput,"reference",&json_cinput1)!=FALSE){
678          if(output->content==NULL)
679            output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
680          else
681            addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
682        }
683      }
684    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
685      if(output->content==NULL)
686        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
687      else
688        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
689    }
690  }
691
692  /**
693   * Parse ComplexData value
694   * @param conf the maps containing the settings of the main.cfg file
695   * @param req json_object pointing to the input/output
696   * @param element
697   * @param output the maps to set current json structure
698   * @param name the name of the request from http_requests
699   */
700  void parseJComplex(maps* conf,json_object* req,elements* element,maps* output,const char* name){
701    json_object* json_cinput=NULL;
702    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
703      output->content=createMap("value",json_object_get_string(json_cinput));
704    }
705    else{
706      json_object* json_value=NULL;
707      if(json_object_object_get_ex(req,"href",&json_value)!=FALSE){
708        output->content=createMap("xlink:href",json_object_get_string(json_value));
709        int len=0;
710        int createdStr=0;
711        char *tmpStr="url";
712        char *tmpStr1="input";
713        if(getMaps(conf,"http_requests")==NULL){
714          maps* tmpMaps=createMaps("http_requests");
715          tmpMaps->content=createMap("length","1");
716          addMapsToMaps(&conf,tmpMaps);
717          freeMaps(&tmpMaps);
718          free(tmpMaps);
719        }else{
720          map* tmpMap=getMapFromMaps(conf,"http_requests","length");
721          int len=atoi(tmpMap->value);
722          createdStr=1;
723          tmpStr=(char*) malloc((12)*sizeof(char));
724          sprintf(tmpStr,"%d",len+1);
725          setMapInMaps(conf,"http_requests","length",tmpStr);
726          sprintf(tmpStr,"url_%d",len);
727          tmpStr1=(char*) malloc((14)*sizeof(char));
728          sprintf(tmpStr1,"input_%d",len);
729        }
730        setMapInMaps(conf,"http_requests",tmpStr,json_object_get_string(json_value));
731        setMapInMaps(conf,"http_requests",tmpStr1,name);
732        if(createdStr>0){
733          free(tmpStr);
734          free(tmpStr1);
735        }
736      }
737    }
738    if(json_object_object_get_ex(req,"format",&json_cinput)!=FALSE){
739      json_object_object_foreach(json_cinput, key, val) {
740        if(output->content==NULL)
741          output->content=createMap(key,json_object_get_string(val));
742        else
743          addToMap(output->content,key,json_object_get_string(val));
744       
745      }
746    }
747    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
748      if(output->content==NULL)
749        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
750      else
751        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
752    }
753  }
754
755  /**
756   * Parse BoundingBox value
757   * @param conf the maps containing the settings of the main.cfg file
758   * @param req json_object pointing to the input/output
759   * @param element
760   * @param output the maps to set current json structure
761   */
762  void parseJBoundingBox(maps* conf,json_object* req,elements* element,maps* output){
763    json_object* json_cinput=NULL;
764    if(json_object_object_get_ex(req,"bbox",&json_cinput)!=FALSE){
765      output->content=createMap("value",json_object_get_string(json_cinput));
766    }
767    if(json_object_object_get_ex(req,"crs",&json_cinput)!=FALSE){
768      if(output->content==NULL)
769        output->content=createMap("crs",json_object_get_string(json_cinput));
770      else
771        addToMap(output->content,"crs","http://www.opengis.net/def/crs/OGC/1.3/CRS84");
772    }
773    char* tmpStrs[2]={
774      "lowerCorner",
775      "upperCorner"
776    };
777    for(int i=0;i<2;i++)
778      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
779        if(output->content==NULL)
780          output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput));
781        else
782          addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput));
783      }
784    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
785      if(output->content==NULL)
786        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
787      else
788        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
789    }
790  }
791
792  /**
793   * Parse a single input / output entity
794   *
795   * @param conf the maps containing the settings of the main.cfg file
796   * @param ioElements the elements extracted from the zcfg
797   * @param ioMaps the produced maps containing inputs (or outputs)
798   * @param ioType the char* set to inputs or outputs
799   * @param key char* the input/output name
800   * @param val json_object pointing to the input/output
801   * @param cMaps the outputed maps containing input (or output) metedata
802   */
803  void _parseJIOSingle(maps* conf,elements* cio, maps** ioMaps,const char* ioType,const char* key,json_object* val,maps* cMaps){
804    json_object* json_cinput;
805    if(json_object_object_get_ex(val,"dataType",&json_cinput)!=FALSE){
806      parseJLiteral(conf,val,cio,cMaps);
807    } else if(json_object_object_get_ex(val,"format",&json_cinput)!=FALSE){
808      parseJComplex(conf,val,cio,cMaps,key);
809    } else if(json_object_object_get_ex(val,"bbox",&json_cinput)!=FALSE){
810      parseJBoundingBox(conf,val,cio,cMaps);
811    }// else error!
812    else{
813      if(json_object_object_get_ex(val,"value",&json_cinput)!=FALSE){
814        map* error=createMap("code","BadRequest");
815        char tmpS[1024];
816        sprintf(tmpS,_("Missing input for %s"),cio->name);
817        addToMap(error,"message",tmpS);
818        setMapInMaps(conf,"lenv","status_code","400 Bad Request");
819        printExceptionReportResponseJ(conf,error);
820        return;
821      }else{
822        if(json_object_get_type(json_cinput)==json_type_string){
823          parseJLiteral(conf,val,cio,cMaps);
824        }else if(json_object_get_type(json_cinput)==json_type_object){
825          json_object* json_ccinput=NULL;
826          if(json_object_object_get_ex(json_cinput,"bbox",&json_ccinput)!=FALSE){
827            parseJComplex(conf,val,cio,cMaps,key);
828          }
829          else{
830            parseJBoundingBox(conf,val,cio,cMaps);
831          }
832        }else{
833          if(strcmp(ioType,"input")==0){
834            map* error=createMap("code","BadRequest");
835            char tmpS1[1024];
836            sprintf(tmpS1,_("Issue with input %s"),cio->name);
837            addToMap(error,"message",tmpS1);
838            setMapInMaps(conf,"lenv","status_code","400 Bad Request");
839            printExceptionReportResponseJ(conf,error);
840            return;
841          }
842        }
843      }
844    }   
845  }
846 
847  /**
848   * Parse a single input / output entity that can be an array
849   *
850   * @param conf the maps containing the settings of the main.cfg file
851   * @param ioElements the elements extracted from the zcfg
852   * @param ioMaps the produced maps containing inputs (or outputs)
853   * @param ioType the char* set to inputs or outputs
854   * @param key char* the input/output name
855   * @param val json_object pointing to the input/output
856   */
857  void parseJIOSingle(maps* conf,elements* ioElements, maps** ioMaps,const char* ioType,const char* key,json_object* val){
858    maps *cMaps=NULL;
859    cMaps=createMaps(key);
860    elements* cio=getElements(ioElements,key);   
861    if(json_object_is_type(val,json_type_array)){
862      int i=0;
863      size_t len=json_object_array_length(val);
864      for(i=0;i<len;i++){
865        json_object* json_current_io=json_object_array_get_idx(val,i);
866        maps* pmsExtra=createMaps(key);
867        _parseJIOSingle(conf,cio,ioMaps,ioType,key,json_current_io,pmsExtra);
868        map* pmCtx=pmsExtra->content;
869        while(pmCtx!=NULL){
870          if(cMaps->content==NULL)
871            cMaps->content=createMap(pmCtx->name,pmCtx->value);
872          else
873            setMapArray(cMaps->content,pmCtx->name,i,pmCtx->value);
874          pmCtx=pmCtx->next;
875        }
876        freeMaps(&pmsExtra);
877        free(pmsExtra);
878      }
879    }else{
880      _parseJIOSingle(conf,cio,ioMaps,ioType,key,val,cMaps);
881    }
882
883   
884    if(strcmp(ioType,"outputs")==0){
885      // Outputs
886      json_object* json_cinput;
887      if(json_object_object_get_ex(val,"transmissionMode",&json_cinput)!=FALSE){
888        if(cMaps->content==NULL)
889          cMaps->content=createMap("transmissionMode",json_object_get_string(json_cinput));
890        else
891          addToMap(cMaps->content,"transmissionMode",json_object_get_string(json_cinput));
892      }
893      if(json_object_object_get_ex(val,"format",&json_cinput)!=FALSE){
894        json_object_object_foreach(json_cinput, key1, val1) {
895          if(cMaps->content==NULL)
896            cMaps->content=createMap(key1,json_object_get_string(val1));
897          else
898            addToMap(cMaps->content,key1,json_object_get_string(val1));
899        }
900      }
901    }
902
903    addToMap(cMaps->content,"inRequest","true");
904    if (ioMaps == NULL)
905      *ioMaps = dupMaps(&cMaps);
906    else
907      addMapsToMaps (ioMaps, cMaps);
908
909    freeMaps(&cMaps);
910    free(cMaps);   
911  }
912 
913  /**
914   * Parse all the inputs / outputs entities
915   *
916   * @param conf the maps containing the settings of the main.cfg file
917   * @param req json_object pointing to the input/output
918   * @param ioElements the elements extracted from the zcfg
919   * @param ioMaps the produced maps containing inputs (or outputs)
920   * @param ioType the char* set to inputs or outputs
921   */
922  void parseJIO(maps* conf, json_object* req, elements* ioElements, maps** ioMaps,const char* ioType){
923    json_object* json_io=NULL;
924    if(json_object_object_get_ex(req,ioType,&json_io)!=FALSE){
925      json_object* json_current_io=NULL;
926      if(json_object_is_type(json_io,json_type_array)){
927        size_t len=json_object_array_length(json_io);
928        for(int i=0;i<len;i++){
929          maps *cMaps=NULL;
930          json_current_io=json_object_array_get_idx(json_io,i);
931          json_object* cname=NULL;
932          if(json_object_object_get_ex(json_current_io,"id",&cname)!=FALSE) {
933            json_object* json_input=NULL;
934            if(json_object_object_get_ex(json_current_io,"input",&json_input)!=FALSE) {     
935              parseJIOSingle(conf,ioElements,ioMaps,ioType,json_object_get_string(cname),json_input);
936            }else
937              parseJIOSingle(conf,ioElements,ioMaps,ioType,json_object_get_string(cname),json_current_io);
938          }
939        }
940      }else{
941        json_object_object_foreach(json_io, key, val) {
942          parseJIOSingle(conf,ioElements,ioMaps,ioType,key,val);
943        }
944      }
945    }
946  }
947   
948     
949 
950  /**
951   * Parse Json Request
952   * @param conf the maps containing the settings of the main.cfg file
953   * @param s the current service metadata
954   * @param req the JSON object of the request body
955   * @param inputs the produced maps
956   * @param outputs the produced maps
957   */
958  void parseJRequest(maps* conf, service* s,json_object* req, map* request_inputs, maps** inputs,maps** outputs){
959    elements* io=s->inputs;
960
961    json_object* json_io=NULL;
962    int parsed=0;
963    char* tmpS="input";
964    maps* in=*inputs;
965    parseJIO(conf,req,s->inputs,inputs,"inputs");
966    parseJIO(conf,req,s->outputs,outputs,"outputs");
967
968    if(parsed==0){
969      json_io=NULL;
970      if(json_object_object_get_ex(req,"mode",&json_io)!=FALSE){
971        addToMap(request_inputs,"mode",json_object_get_string(json_io));
972        setMapInMaps(conf,"request","mode",json_object_get_string(json_io));
973      }
974      json_io=NULL;
975      if(json_object_object_get_ex(req,"response",&json_io)!=FALSE){
976        addToMap(request_inputs,"response",json_object_get_string(json_io));
977        setMapInMaps(conf,"request","response",json_object_get_string(json_io));
978      }
979      json_io=NULL;
980      if(json_object_object_get_ex(req,"subscriber",&json_io)!=FALSE){
981        maps* subscribers=createMaps("subscriber");
982        json_object* json_subscriber=NULL;
983        if(json_object_object_get_ex(json_io,"successUri",&json_subscriber)!=FALSE){
984          subscribers->content=createMap("successUri",json_object_get_string(json_subscriber));
985        }
986        if(json_object_object_get_ex(json_io,"inProgressUri",&json_subscriber)!=FALSE){
987          if(subscribers->content==NULL)
988            subscribers->content=createMap("inProgressUri",json_object_get_string(json_subscriber));
989          else
990            addToMap(subscribers->content,"inProgressUri",json_object_get_string(json_subscriber));
991        }
992        if(json_object_object_get_ex(json_io,"failedUri",&json_subscriber)!=FALSE){
993          if(subscribers->content==NULL)
994            subscribers->content=createMap("failedUri",json_object_get_string(json_subscriber));
995          else
996            addToMap(subscribers->content,"failedUri",json_object_get_string(json_subscriber));
997        }
998        addMapsToMaps(&conf,subscribers);
999        freeMaps(&subscribers);
1000        free(subscribers);
1001      }
1002    }
1003   
1004  }
1005
1006  /**
1007   * Print the jobs status info
1008   * cf.
1009   *
1010   * @param conf the maps containing the settings of the main.cfg file
1011   * @return the JSON object pointer to the jobs list
1012   */
1013  json_object* printJobStatus(maps* pmsConf,char* pcJobId){
1014    json_object* pjoRes=NULL;
1015    runGetStatus(pmsConf,pcJobId,"GetStatus");
1016    map* pmError=getMapFromMaps(pmsConf,"lenv","error");
1017    if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
1018      printExceptionReportResponseJ(pmsConf,getMapFromMaps(pmsConf,"lenv","code"));
1019      return NULL;
1020    }else{
1021      map* pmStatus=getMapFromMaps(pmsConf,"lenv","status");
1022      setMapInMaps(pmsConf,"lenv","gs_location","false");
1023      setMapInMaps(pmsConf,"lenv","gs_usid",pcJobId);
1024      if(pmStatus!=NULL && strncasecmp(pmStatus->value,"Failed",6)==0)
1025        pjoRes=createStatus(pmsConf,SERVICE_FAILED);
1026      else
1027        if(pmStatus!=NULL  && strncasecmp(pmStatus->value,"Succeeded",9)==0)
1028          pjoRes=createStatus(pmsConf,SERVICE_SUCCEEDED);
1029        else
1030          if(pmStatus!=NULL  && strncasecmp(pmStatus->value,"Running",7)==0){
1031            map* tmpMap=getMapFromMaps(pmsConf,"lenv","Message");
1032            if(tmpMap!=NULL)
1033              setMapInMaps(pmsConf,"lenv","gs_message",tmpMap->value);
1034            pjoRes=createStatus(pmsConf,SERVICE_STARTED);
1035          }
1036          else
1037            pjoRes=createStatus(pmsConf,SERVICE_FAILED);
1038    }
1039    return pjoRes;
1040  }
1041 
1042  /**
1043   * Print the jobs list
1044   *
1045   * @param conf the maps containing the settings of the main.cfg file
1046   * @return the JSON object pointer to the jobs list
1047   */
1048  json_object* printJobList(maps* conf){
1049    json_object* res=json_object_new_array();
1050    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
1051    struct dirent *dp;
1052    DIR *dirp = opendir (tmpPath->value);
1053    if(dirp!=NULL){
1054      while ((dp = readdir (dirp)) != NULL){
1055        char* extn = strstr(dp->d_name, "_status.json");
1056        if(extn!=NULL){
1057          char* tmpStr=zStrdup(dp->d_name);
1058          tmpStr[strlen(dp->d_name)-12]=0;
1059          json_object* cjob=printJobStatus(conf,tmpStr);
1060          json_object_array_add(res,cjob);
1061        }
1062      }
1063      closedir (dirp);
1064    }
1065    return res;
1066  }
1067 
1068  /**
1069   * Print the result of an execution
1070   *
1071   * @param conf the maps containing the settings of the main.cfg file
1072   * @param s service pointer to metadata
1073   * @param result outputs of the service
1074   * @param res the status of execution SERVICE_FAILED/SERVICE_SUCCEEDED
1075   * @return the JSON object pointer to the result
1076   */
1077  json_object* printJResult(maps* conf,service* s,maps* result,int res){
1078    if(res==SERVICE_FAILED){
1079      char* pacTmp=produceErrorMessage(conf);
1080      map* pamTmp=createMap("message",pacTmp);
1081      free(pacTmp);
1082      map* pmTmp=getMapFromMaps(conf,"lenv","code");
1083      if(pmTmp!=NULL)
1084        addToMap(pamTmp,"code",pmTmp->value);
1085      printExceptionReportResponseJ(conf,pamTmp);
1086      freeMap(&pamTmp);
1087      free(pamTmp);
1088      return NULL;
1089    }
1090    if(getMapFromMaps(conf,"lenv","no-headers")==NULL)
1091      printHeaders(conf);
1092    map* pmMode=getMapFromMaps(conf,"request","response");
1093    if(pmMode!=NULL && strncasecmp(pmMode->value,"raw",3)==0){
1094      maps* resu=result;
1095      printRawdataOutput(conf,resu);
1096      map* pmError=getMapFromMaps(conf,"lenv","error");
1097      if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
1098        printExceptionReportResponseJ(conf,pmError);
1099      }
1100      return NULL;
1101    }else{
1102      json_object* eres1=json_object_new_object();
1103      map* pmIOAsArray=getMapFromMaps(conf,"openapi","io_as_array");
1104      json_object* eres;
1105      if(pmIOAsArray!=NULL && strncasecmp(pmIOAsArray->value,"true",4)==0)
1106        eres=json_object_new_array();
1107      else
1108        eres=json_object_new_object();
1109      maps* resu=result;
1110      int itn=0;
1111      while(resu!=NULL){
1112        json_object* res1=json_object_new_object();
1113        if(pmIOAsArray!=NULL && strncasecmp(pmIOAsArray->value,"true",4)==0)
1114          json_object_object_add(res1,"id",json_object_new_string(resu->name));
1115        map* tmpMap=getMap(resu->content,"mimeType");
1116        json_object* res3=json_object_new_object();
1117        if(tmpMap!=NULL)
1118          json_object_object_add(res3,"mediaType",json_object_new_string(tmpMap->value));
1119        else{
1120          json_object_object_add(res3,"mediaType",json_object_new_string("text/plain"));
1121          map* pmDataType=getMap(resu->content,"dataType");
1122          if(pmDataType!=NULL){
1123            json_object* pjoTmp3=json_object_new_object();
1124            json_object_object_add(pjoTmp3,"name",json_object_new_string(pmDataType->value));
1125            json_object_object_add(res1,"dataType",pjoTmp3);
1126          }
1127        }
1128        if((tmpMap=getMap(resu->content,"value"))!=NULL ||
1129           (getMap(resu->content,"generated_file"))!=NULL){
1130          //json_object* res2=json_object_new_object();
1131          map* tmpMap1=NULL;
1132          if((tmpMap1=getMap(resu->content,"transmissionMode"))!=NULL) {
1133            if(strcmp(tmpMap1->value,"value")==0) {
1134              map* tmpMap2=getMap(resu->content,"mimeType");
1135              if(tmpMap2!=NULL && strstr(tmpMap2->value,"json")!=NULL){
1136                json_object *jobj = NULL;
1137                int slen = 0;
1138                enum json_tokener_error jerr;
1139                struct json_tokener* tok=json_tokener_new();
1140                do {
1141                  slen = strlen(tmpMap->value);
1142                  jobj = json_tokener_parse_ex(tok, tmpMap->value, slen);
1143                } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
1144                if (jerr != json_tokener_success) {
1145                  fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
1146                  return eres1;
1147                }
1148                if (tok->char_offset < slen){
1149                  return eres1;         
1150                }
1151                json_object_object_add(res3,"encoding",json_object_new_string("utf-8"));
1152                json_object_object_add(res1,"value",jobj);
1153              }else{
1154                map* tmp1=getMapFromMaps(conf,"main","tmpPath");
1155                map *gfile=getMap(resu->content,"generated_file");
1156                if(gfile!=NULL){
1157                  gfile=getMap(resu->content,"expected_generated_file");
1158                  if(gfile==NULL){
1159                    gfile=getMap(resu->content,"generated_file");
1160                  }
1161                  FILE* pfData=fopen(gfile->value,"rb");
1162                  if(pfData!=NULL){
1163                    zStatStruct f_status;
1164                    int s=zStat(gfile->value, &f_status);
1165                    char* pcaTmp=(char*)malloc((f_status.st_size+1)*sizeof(char));
1166                    fread(pcaTmp,1,f_status.st_size,pfData);
1167                    pcaTmp[f_status.st_size]=0;     
1168                    fclose(pfData);
1169                    json_object_object_add(res1,"value",json_object_new_string(base64(pcaTmp,f_status.st_size)));
1170                    json_object_object_add(res3,"encoding",json_object_new_string("base64"));
1171                    free(pcaTmp);
1172                  }
1173                }else{
1174                  json_object_object_add(res3,"encoding",json_object_new_string("utf-8"));
1175                  json_object_object_add(res1,"value",json_object_new_string(tmpMap->value));
1176                }
1177              }
1178            }
1179            else{
1180              char *pcaFileUrl=produceFileUrl(s,conf,resu,NULL,itn);
1181              itn++;
1182              if(pcaFileUrl!=NULL){
1183                json_object_object_add(res1,"href",
1184                                       json_object_new_string(pcaFileUrl));
1185                free(pcaFileUrl);
1186              }
1187            }
1188          }
1189          //json_object_object_add(res1,"value",res2);
1190          json_object_object_add(res1,"format",res3);
1191          if(pmIOAsArray!=NULL && strncasecmp(pmIOAsArray->value,"true",4)==0){
1192            json_object_array_add(eres,res1);
1193          }else
1194            json_object_object_add(eres,resu->name,res1);
1195        }
1196        resu=resu->next;
1197      }
1198      json_object_object_add(eres1,"outputs",eres);
1199      const char* jsonStr =
1200        json_object_to_json_string_ext(eres1,JSON_C_TO_STRING_PLAIN);
1201      map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1202      map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1203      map *sessId = getMapFromMaps (conf, "lenv", "usid");
1204      char *pacTmp=(char*)malloc((strlen(tmpPath->value)+strlen(cIdentifier->value)+strlen(sessId->value)+8)*sizeof(char));
1205      sprintf(pacTmp,"%s/%s_%s.json",
1206              tmpPath->value,cIdentifier->value,sessId->value);
1207      zStatStruct zsFStatus;
1208      int iS=zStat(pacTmp, &zsFStatus);
1209      if(iS==0 && zsFStatus.st_size>0){
1210        map* tmpPath1 = getMapFromMaps (conf, "main", "tmpUrl");
1211        char* pacTmpUrl=(char*)malloc((strlen(tmpPath1->value)+strlen(cIdentifier->value)+strlen(sessId->value)+8)*sizeof(char));;
1212        sprintf(pacTmpUrl,"%s/%s_%s.json",tmpPath1->value,
1213                cIdentifier->value,sessId->value);
1214        if(getMapFromMaps(conf,"lenv","gs_location")==NULL)
1215          setMapInMaps(conf,"headers","Location",pacTmpUrl);
1216        free(pacTmpUrl);
1217      }
1218      free(pacTmp);
1219      if(res==3){
1220        map* mode=getMapFromMaps(conf,"request","mode");
1221        if(mode!=NULL && strncasecmp(mode->value,"async",5)==0)
1222          setMapInMaps(conf,"headers","Status","201 Created");
1223        else
1224          setMapInMaps(conf,"headers","Status","200 Ok");
1225      }
1226      else{
1227        setMapInMaps(conf,"headers","Status","500 Issue running your service");
1228      }
1229      return eres1;
1230    }
1231  }
1232
1233
1234  /**
1235   * Create the status links
1236   *
1237   * @param conf the maps containing the settings of the main.cfg file
1238   * @param result an integer (>0 for adding the /result link)
1239   * @param obj the JSON object pointer to add the links to
1240   * @return 0
1241   */
1242  int createStatusLinks(maps* conf,int result,json_object* obj){
1243    json_object* res=json_object_new_array();
1244    map *tmpPath = getMapFromMaps (conf, "openapi", "rootUrl");
1245    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1246    if(sessId==NULL){
1247      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1248    }
1249    char *Url0=(char*) malloc((strlen(tmpPath->value)+
1250                               strlen(sessId->value)+18)*sizeof(char));
1251    int needResult=-1;
1252    char *message, *status;
1253    sprintf(Url0,"%s/jobs/%s",
1254            tmpPath->value,
1255            sessId->value);
1256    if(getMapFromMaps(conf,"lenv","gs_location")==NULL)
1257      setMapInMaps(conf,"headers","Location",Url0);
1258    json_object* val=json_object_new_object();
1259    json_object_object_add(val,"title",
1260                           json_object_new_string(_("Status location")));
1261    json_object_object_add(val,"rel",
1262                           json_object_new_string(_("status")));
1263    json_object_object_add(val,"type",
1264                           json_object_new_string(_("application/json")));
1265    json_object_object_add(val,"href",json_object_new_string(Url0));
1266    json_object_array_add(res,val);
1267    if(result>0){
1268      free(Url0);
1269      Url0=(char*) malloc((strlen(tmpPath->value)+
1270                           strlen(sessId->value)+
1271                           25)*sizeof(char));
1272      sprintf(Url0,"%s/jobs/%s/results",
1273              tmpPath->value,
1274              sessId->value);
1275      json_object* val1=json_object_new_object();
1276      json_object_object_add(val1,"title",
1277                             json_object_new_string(_("Result location")));
1278      json_object_object_add(val1,"rel",
1279                             json_object_new_string(_("results")));
1280      json_object_object_add(val1,"type",
1281                             json_object_new_string(_("application/json")));
1282      json_object_object_add(val1,"href",json_object_new_string(Url0));
1283      json_object_array_add(res,val1);
1284    }
1285    json_object_object_add(obj,"links",res);
1286    free(Url0);
1287    return 0;
1288  }
1289
1290  /**
1291   * Get the status file path
1292   *
1293   * @param conf the maps containing the settings of the main.cfg file
1294   * @return a char* containing the full status file path
1295   */
1296  char* json_getStatusFilePath(maps* conf){
1297    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1298    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1299    if(sessId!=NULL){
1300      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1301      if(sessId==NULL)
1302        sessId = getMapFromMaps (conf, "lenv", "usid");
1303    }else
1304      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1305   
1306    char *tmp1=(char*) malloc((strlen(tmpPath->value)+
1307                               strlen(sessId->value)+14)*sizeof(char));
1308    sprintf(tmp1,"%s/%s_status.json",
1309            tmpPath->value,
1310            sessId->value);
1311    return tmp1;
1312  }
1313
1314  char* getResultPath(maps* conf,char* jobId){
1315    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1316    char *pacUrl=(char*) malloc((strlen(tmpPath->value)+
1317                                 strlen(jobId)+8)*sizeof(char));
1318    sprintf(pacUrl,"%s/%s.json",tmpPath->value,jobId);
1319    return pacUrl;
1320  }
1321
1322  json_object* parseJson(maps* conf,char* myString){
1323    json_object *pajObj = NULL;
1324    enum json_tokener_error jerr;
1325    struct json_tokener* tok=json_tokener_new();
1326    int slen = 0;
1327    do {
1328      slen = strlen(myString);
1329      pajObj = json_tokener_parse_ex(tok, myString, slen);
1330    } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
1331    if (jerr != json_tokener_success) {
1332      setMapInMaps(conf,"lenv","message",json_tokener_error_desc(jerr));
1333      fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
1334      return NULL;
1335    }
1336    if (tok->char_offset < slen){
1337      fprintf(stderr, "Error parsing json\n");
1338      return NULL;
1339    }
1340    return pajObj;
1341  }
1342 
1343  json_object* json_readFile(maps* conf,char* filePath){
1344    json_object *pajObj = NULL;
1345    zStatStruct zsFStatus;
1346    int iS=zStat(filePath, &zsFStatus);
1347    if(iS==0 && zsFStatus.st_size>0){
1348      FILE* cdat=fopen(filePath,"rb");
1349      if(cdat!=NULL){
1350        char* pacMyString=(char*)malloc((zsFStatus.st_size+1)*sizeof(char));
1351        fread(pacMyString,1,zsFStatus.st_size,cdat);
1352        pacMyString[zsFStatus.st_size]=0;
1353        fclose(cdat);
1354        pajObj=parseJson(conf,pacMyString);
1355        free(pacMyString);
1356      }
1357      else
1358        return NULL;
1359    }else
1360      return NULL;
1361    return pajObj;
1362  }
1363 
1364  json_object* createStatus(maps* conf,int status){
1365    int needResult=0;
1366    const char *rstatus;
1367    char *message;
1368    // Create statusInfo JSON object
1369    // cf. https://github.com/opengeospatial/wps-rest-binding/blob/master/core/
1370    //     openapi/schemas/statusInfo.yaml
1371    json_object* res=json_object_new_object();
1372    switch(status){
1373    case SERVICE_ACCEPTED:
1374      {
1375        message=_("ZOO-Kernel accepted to run your service!");
1376        rstatus="accepted";
1377        break;
1378      }
1379    case SERVICE_STARTED:
1380      {
1381        message=_("ZOO-Kernel is currently running your service!");
1382        map* pmStatus=getMapFromMaps(conf,"lenv","status");
1383        if(pmStatus!=NULL)
1384          setMapInMaps(conf,"lenv","PercentCompleted",pmStatus->value);
1385        pmStatus=getMapFromMaps(conf,"lenv","message");
1386        if(pmStatus!=NULL)
1387          setMapInMaps(conf,"lenv","gs_message",pmStatus->value);
1388        rstatus="running";
1389        break;
1390      }
1391    case SERVICE_PAUSED:
1392      {
1393        message=_("ZOO-Kernel pause your service!");
1394        rstatus="paused";
1395        break;
1396      }
1397    case SERVICE_SUCCEEDED:
1398      {
1399        message=_("ZOO-Kernel successfully run your service!");
1400        rstatus="successful";
1401        setMapInMaps(conf,"lenv","PercentCompleted","100");
1402        needResult=1;
1403        break;
1404      }
1405    case SERVICE_DISMISSED:
1406      {
1407        message=_("ZOO-Kernel successfully dismissed your service!");
1408        rstatus="dismissed";
1409        needResult=1;
1410        break;
1411      }
1412    default:
1413      {
1414        map* pmTmp=getMapFromMaps(conf,"lenv","force");
1415        if(pmTmp==NULL || strncasecmp(pmTmp->value,"false",5)==0){
1416          char* pacTmp=json_getStatusFilePath(conf);
1417          json_object* pjoStatus=json_readFile(conf,pacTmp);
1418          free(pacTmp);
1419          if(pjoStatus!=NULL){
1420            json_object* pjoMessage=NULL;
1421            if(json_object_object_get_ex(pjoStatus,"message",&pjoMessage)!=FALSE){
1422              message=(char*)json_object_get_string(pjoMessage);
1423            }
1424          }
1425          // TODO: Error
1426        }else{
1427          map* mMap=getMapFromMaps(conf,"lenv","gs_message");
1428          if(mMap!=NULL)
1429            setMapInMaps(conf,"lenv","message",mMap->value);
1430          message=produceErrorMessage(conf);
1431          needResult=-1;
1432        }
1433        rstatus="failed";
1434        break;
1435      }
1436    }
1437    setMapInMaps(conf,"lenv","message",message);
1438    setMapInMaps(conf,"lenv","status",rstatus);
1439
1440    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1441    if(sessId!=NULL){
1442      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1443      if(sessId==NULL)
1444        sessId = getMapFromMaps (conf, "lenv", "usid");
1445    }else
1446      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1447    if(sessId!=NULL)
1448      json_object_object_add(res,"jobID",json_object_new_string(sessId->value));
1449
1450    json_object_object_add(res,"status",json_object_new_string(rstatus));
1451    map* mMap=getMapFromMaps(conf,"lenv","gs_message");
1452    if(mMap==NULL)
1453      json_object_object_add(res,"message",json_object_new_string(message));
1454    else{
1455      json_object_object_add(res,"message",json_object_new_string(mMap->value));
1456      if((mMap=getMapFromMaps(conf,"lenv","PercentCompleted"))!=NULL)
1457        json_object_object_add(res,"progress",json_object_new_int(atoi(mMap->value)));
1458    }
1459    if(status!=SERVICE_DISMISSED)
1460      createStatusLinks(conf,needResult,res);
1461    else{
1462      json_object* res1=json_object_new_array();
1463      map *tmpPath = getMapFromMaps (conf, "openapi", "rootUrl");
1464      char *Url0=(char*) malloc((strlen(tmpPath->value)+17)*sizeof(char));
1465      sprintf(Url0,"%s/jobs",tmpPath->value);
1466      json_object* val=json_object_new_object();
1467      json_object_object_add(val,"title",
1468                             json_object_new_string(_("The job list for the current process")));
1469      json_object_object_add(val,"rel",
1470                             json_object_new_string(_("parent")));
1471      json_object_object_add(val,"type",
1472                             json_object_new_string(_("application/json")));
1473      json_object_object_add(val,"href",json_object_new_string(Url0));
1474      json_object_array_add(res1,val);
1475      free(Url0);
1476      json_object_object_add(res,"links",res1);
1477    }
1478    if(needResult<0)
1479      free(message);
1480    return res;
1481  }
1482 
1483  /**
1484   * Create the status file
1485   *
1486   * @param conf the maps containing the settings of the main.cfg file
1487   * @param status an integer (SERVICE_ACCEPTED,SERVICE_STARTED...)
1488   * @return an integer (0 in case of success, 1 in case of failure)
1489   */
1490  int createStatusFile(maps* conf,int status){
1491    json_object* res=createStatus(conf,status);
1492    char* tmp1=json_getStatusFilePath(conf);
1493    FILE* foutput1=fopen(tmp1,"w+");
1494    if(foutput1!=NULL){
1495      const char* jsonStr1=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
1496      fprintf(foutput1,"%s",jsonStr1);
1497      fclose(foutput1);
1498    }else{
1499      // Failure
1500      setMapInMaps(conf,"lenv","message",_("Unable to store the statusInfo!"));
1501      free(tmp1);
1502      return 1;
1503    }
1504    free(tmp1);
1505    return 0;
1506  }
1507
1508  /**
1509   * Create the status file
1510   *
1511   * @param conf the maps containing the settings of the main.cfg file
1512   * @return an integer (0 in case of success, 1 in case of failure)
1513   */
1514  int json_getStatusFile(maps* conf){
1515    char* tmp1=json_getStatusFilePath(conf);
1516    FILE* statusFile=fopen(tmp1,"rb");
1517
1518    map* tmpMap=getMapFromMaps(conf,"lenv","gs_usid");
1519    if(tmpMap!=NULL){
1520      char* tmpStr=_getStatus(conf,tmpMap->value);
1521      if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1522        char *tmpStr1=zStrdup(tmpStr);
1523        char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1524        free(tmpStr);
1525        tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1526        setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
1527        setMapInMaps(conf,"lenv","gs_message",tmpStr0);
1528        free(tmpStr0);
1529        free(tmpStr1);
1530        return 0;
1531      }else{
1532         
1533      }
1534    }
1535  }
1536
1537  /**
1538   * Produce the JSON object for api info object
1539   *
1540   * @param conf the maps containing the settings of the main.cfg file
1541   * @param res the JSON object for the api info
1542   */
1543  void produceApiInfo(maps* conf,json_object* res,json_object* res5){
1544    json_object *res1=json_object_new_object();
1545    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
1546    if(tmpMap!=NULL){
1547      json_object *res2=json_object_new_object();
1548      json_object_object_add(res2,"name",json_object_new_string(tmpMap->value));
1549      tmpMap=getMapFromMaps(conf,"provider","addressElectronicMailAddress");
1550      if(tmpMap!=NULL)
1551        json_object_object_add(res2,"email",json_object_new_string(tmpMap->value));
1552      tmpMap=getMapFromMaps(conf,"provider","providerSite");
1553      if(tmpMap!=NULL)
1554        json_object_object_add(res2,"url",json_object_new_string(tmpMap->value));
1555      json_object_object_add(res1,"contact",res2);
1556    }
1557    tmpMap=getMapFromMaps(conf,"identification","abstract");
1558    if(tmpMap!=NULL){
1559      json_object_object_add(res1,"description",json_object_new_string(tmpMap->value));
1560      json_object_object_add(res5,"description",json_object_new_string(tmpMap->value));
1561      tmpMap=getMapFromMaps(conf,"openapi","rootUrl");
1562      json_object_object_add(res5,"url",json_object_new_string(tmpMap->value));
1563    }
1564    tmpMap=getMapFromMaps(conf,"identification","title");
1565    if(tmpMap!=NULL)
1566      json_object_object_add(res1,"title",json_object_new_string(tmpMap->value));
1567    json_object_object_add(res1,"version",json_object_new_string(ZOO_VERSION));
1568    tmpMap=getMapFromMaps(conf,"identification","keywords");
1569    if(tmpMap!=NULL){
1570      char *saveptr;
1571      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
1572      json_object *res3=json_object_new_array();
1573      while (tmps != NULL){
1574        json_object_array_add(res3,json_object_new_string(tmps));
1575        tmps = strtok_r (NULL, ",", &saveptr);
1576      }
1577      json_object_object_add(res1,"x-keywords",res3);
1578    }
1579    maps* tmpMaps=getMaps(conf,"provider");
1580    if(tmpMaps!=NULL){
1581      json_object *res4=json_object_new_object();
1582      map* cItem=tmpMaps->content;
1583      while(cItem!=NULL){
1584        json_object_object_add(res4,cItem->name,json_object_new_string(cItem->value));
1585        cItem=cItem->next;
1586      }
1587      json_object_object_add(res1,"x-ows-servicecontact",res4);
1588    }
1589
1590    json_object *res4=json_object_new_object();
1591    tmpMap=getMapFromMaps(conf,"openapi","license_name");
1592    if(tmpMap!=NULL){
1593      json_object_object_add(res4,"name",json_object_new_string(tmpMap->value));
1594      tmpMap=getMapFromMaps(conf,"openapi","license_url");
1595      if(tmpMap!=NULL){
1596        json_object_object_add(res4,"url",json_object_new_string(tmpMap->value));     
1597      }
1598    }
1599    json_object_object_add(res1,"license",res4);
1600
1601    json_object_object_add(res,"info",res1);   
1602  }
1603
1604  // addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
1605  void addResponse(const map* useContent,json_object* res,const map* pmSchema,const map* pmType,const char* code,const char* msg){
1606    json_object *cc=json_object_new_object();
1607    if(pmSchema!=NULL)
1608      json_object_object_add(cc,"$ref",json_object_new_string(pmSchema->value));
1609    if(useContent!=NULL && strncasecmp(useContent->value,"true",4)!=0){
1610      json_object_object_add(res,code,cc);
1611    }else{
1612      json_object *cc0=json_object_new_object();
1613      if(pmSchema!=NULL)
1614        json_object_object_add(cc0,"schema",cc);
1615      json_object *cc1=json_object_new_object();
1616      if(pmType!=NULL)
1617        json_object_object_add(cc1,pmType->value,cc0);
1618      else
1619        json_object_object_add(cc1,"application/json",cc0);
1620      json_object *cc2=json_object_new_object();
1621      json_object_object_add(cc2,"content",cc1);
1622      json_object_object_add(cc2,"description",json_object_new_string(msg));
1623      json_object_object_add(res,code,cc2);
1624    }
1625  }
1626
1627  void addParameter(maps* conf,const char* oName,const char* fName,const char* in,json_object* res){
1628    maps* tmpMaps1=getMaps(conf,oName);
1629    json_object *res8=json_object_new_object();
1630    if(tmpMaps1!=NULL){
1631      map* tmpMap=getMap(tmpMaps1->content,"title");
1632      if(tmpMap!=NULL)
1633        json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
1634      tmpMap=getMap(tmpMaps1->content,"abstract");
1635      if(tmpMap!=NULL)
1636        json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
1637      tmpMap=getMap(tmpMaps1->content,"example");
1638      if(tmpMap!=NULL)
1639        json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
1640      tmpMap=getMap(tmpMaps1->content,"required");
1641      if(tmpMap!=NULL){
1642        if(strcmp(tmpMap->value,"true")==0)
1643          json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
1644        else
1645          json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
1646      }
1647      else
1648        json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
1649      json_object_object_add(res8,"in",json_object_new_string(in));
1650      json_object_object_add(res8,"name",json_object_new_string(fName));
1651      json_object *res6=json_object_new_object();
1652      tmpMap=getMap(tmpMaps1->content,"type");
1653      if(tmpMap!=NULL)
1654        json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
1655      else
1656        json_object_object_add(res6,"type",json_object_new_string("string"));
1657       
1658      json_object_object_add(res8,"schema",res6);
1659       
1660    }   
1661    json_object_object_add(res,fName,res8);   
1662  }
1663 
1664  /**
1665   * Produce the JSON object for api parameter
1666   *
1667   * @param conf the maps containing the settings of the main.cfg file
1668   * @param res the JSON object to populate with the parameters
1669   */
1670  void produceApiParameters(maps* conf,json_object* res){
1671    json_object *res9=json_object_new_object();
1672    maps* tmpMaps1=getMaps(conf,"{id}");
1673    map* tmpMap2=getMapFromMaps(conf,"openapi","parameters");
1674    char *saveptr12;
1675    char *tmps12 = strtok_r (tmpMap2->value, ",", &saveptr12);
1676    while(tmps12!=NULL){
1677      char* pacId=(char*) malloc((strlen(tmps12)+3)*sizeof(char));
1678      sprintf(pacId,"{%s}",tmps12);
1679      addParameter(conf,pacId,tmps12,"path",res9);
1680      free(pacId);
1681      tmps12 = strtok_r (NULL, ",", &saveptr12);
1682    }   
1683    tmpMap2=getMapFromMaps(conf,"openapi","header_parameters");
1684    if(tmpMap2!=NULL){
1685      char *saveptr13;
1686      char *tmps13 = strtok_r (tmpMap2->value, ",", &saveptr13);
1687      while(tmps13!=NULL){
1688        char* pacId=zStrdup(tmps13);
1689        addParameter(conf,pacId,pacId,"header",res9);
1690        free(pacId);
1691        tmps13 = strtok_r (NULL, ",", &saveptr13);
1692      }
1693    }
1694    json_object_object_add(res,"parameters",res9);
1695    maps* pmResponses=getMaps(conf,"responses");
1696    if(pmResponses!=NULL){
1697      json_object *cc=json_object_new_object();
1698      map* pmLen=getMap(pmResponses->content,"length");
1699      int iLen=atoi(pmLen->value);
1700      map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
1701      for(int i=0;i<iLen;i++){
1702        map* cMap=getMapArray(pmResponses->content,"code",i);
1703        map* vMap=getMapArray(pmResponses->content,"schema",i);
1704        map* tMap=getMapArray(pmResponses->content,"type",i);
1705        map* tMap0=getMapArray(pmResponses->content,"title",i);
1706        if(vMap!=NULL)
1707          addResponse(pmUseContent,cc,vMap,tMap,cMap->value,(tMap0==NULL)?"successful operation":tMap0->value);
1708      }
1709      json_object_object_add(res,"responses",cc);
1710    }
1711  }
1712
1713  void produceApiComponents(maps*conf,json_object* res){
1714    json_object* res1=json_object_new_object();
1715    produceApiParameters(conf,res1);
1716    json_object_object_add(res,"components",res1);
1717  }
1718 
1719  /**
1720   * Produce the JSON object for /api
1721   *
1722   * @param conf the maps containing the settings of the main.cfg file
1723   * @param res the JSON object to populate
1724   */
1725  void produceApi(maps* conf,json_object* res){
1726    // TODO: add 401 Gone for dismiss request
1727    json_object *res9=json_object_new_object();
1728    json_object *res10=json_object_new_object();
1729    maps* tmpMaps1=getMaps(conf,"{id}");
1730    produceApiComponents(conf,res);
1731    json_object *res4=json_object_new_object();
1732    setMapInMaps(conf,"headers","Content-Type","application/openapi+json; version=3.0;charset=UTF-8");
1733
1734    produceApiInfo(conf,res,res4);
1735    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
1736
1737    tmpMap=getMapFromMaps(conf,"openapi","version");
1738    if(tmpMap!=NULL)
1739      json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
1740    else
1741      json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
1742
1743    tmpMap=getMapFromMaps(conf,"openapi","paths");
1744    if(tmpMap!=NULL){
1745      json_object *res5=json_object_new_object();
1746      char *saveptr;
1747      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
1748      int cnt=0;
1749      maps* tmpMaps;
1750      json_object *paths=json_object_new_object();
1751      while (tmps != NULL){
1752        tmpMaps=getMaps(conf,tmps+1);
1753        json_object *method=json_object_new_object();
1754        if(tmpMaps!=NULL){
1755          if(getMap(tmpMaps->content,"length")==NULL)
1756            addToMap(tmpMaps->content,"length","1");
1757          map* len=getMap(tmpMaps->content,"length");
1758           
1759          for(int i=0;i<atoi(len->value);i++){
1760            json_object *methodc=json_object_new_object();
1761            map* cMap=getMapArray(tmpMaps->content,"method",i);
1762            map* vMap=getMapArray(tmpMaps->content,"title",i);
1763            if(vMap!=NULL)
1764              json_object_object_add(methodc,"summary",json_object_new_string(vMap->value));
1765            vMap=getMapArray(tmpMaps->content,"abstract",i);
1766            if(vMap!=NULL)
1767              json_object_object_add(methodc,"description",json_object_new_string(vMap->value));
1768            vMap=getMapArray(tmpMaps->content,"tags",i);
1769            if(vMap!=NULL){
1770              json_object *cc=json_object_new_array();
1771              json_object_array_add(cc,json_object_new_string(vMap->value));
1772              json_object_object_add(methodc,"tags",cc);
1773              json_object_object_add(methodc,"operationId",json_object_new_string(vMap->value));
1774
1775            }
1776            json_object *responses=json_object_new_object();
1777            json_object *cc3=json_object_new_object();
1778            map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
1779            vMap=getMapArray(tmpMaps->content,"schema",i);
1780            if(vMap!=NULL){
1781              map* tMap=getMapArray(tmpMaps->content,"type",i);
1782              addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
1783              vMap=getMapArray(tmpMaps->content,"eschema",i);
1784              if(vMap!=NULL && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
1785                addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
1786            }else{
1787              map* tMap=getMapFromMaps(conf,tmps,"type");
1788              map* pMap=createMap("ok","true");
1789              addResponse(pMap,cc3,vMap,tMap,"200","successful operation");
1790              if(cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
1791                addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
1792            }
1793            vMap=getMapArray(tmpMaps->content,"ecode",i);
1794            if(vMap!=NULL){
1795              char *saveptr0;
1796              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
1797              while(tmps1!=NULL){
1798                char* tmpStr=(char*)malloc((strlen(tmps1)+24)*sizeof(char));
1799                sprintf(tmpStr,"#/components/responses/%s",tmps1);
1800                vMap=createMap("ok",tmpStr);
1801                map* pMap=createMap("ok","false");
1802                //TODO: fix successful operation with correct value
1803                addResponse(pMap,cc3,vMap,NULL,tmps1,"successful operation");
1804                tmps1 = strtok_r (NULL, ",", &saveptr0);
1805              }
1806            }else{
1807              if(strstr(tmps,"{id}")!=NULL){
1808                vMap=getMapFromMaps(conf,"exception","schema");
1809                map* tMap=getMapFromMaps(conf,"exception","type");
1810                if(vMap!=NULL)
1811                  addResponse(pmUseContent,cc3,vMap,tMap,"404",
1812                              (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.");
1813              }
1814            }
1815            json_object_object_add(methodc,"responses",cc3);
1816            vMap=getMapArray(tmpMaps->content,"parameters",i);
1817            if(vMap!=NULL){
1818              char *saveptr0;
1819              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
1820              json_object *cc2=json_object_new_array();
1821              int cnt=0;
1822              while(tmps1!=NULL){
1823                char* tmpStr=(char*)malloc((strlen(tmps1)+2)*sizeof(char));
1824                sprintf(tmpStr,"#%s",tmps1);
1825                json_object *cc1=json_object_new_object();
1826                json_object_object_add(cc1,"$ref",json_object_new_string(tmpStr));
1827                json_object_array_add(cc2,cc1);
1828                free(tmpStr);
1829                cnt++;
1830                tmps1 = strtok_r (NULL, ",", &saveptr0);
1831              }
1832              json_object_object_add(methodc,"parameters",cc2);
1833            }
1834            if(i==1 && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0){
1835              maps* tmpMaps1=getMaps(conf,"requestBody");
1836              if(tmpMaps1!=NULL){
1837                vMap=getMap(tmpMaps1->content,"schema");
1838                if(vMap!=NULL){
1839                  json_object *cc=json_object_new_object();
1840                  json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
1841                  json_object *cc0=json_object_new_object();
1842                  json_object_object_add(cc0,"schema",cc);
1843                  json_object *cc1=json_object_new_object();
1844                  map* tmpMap3=getMap(tmpMaps->content,"type");
1845                  if(tmpMap3!=NULL)
1846                    json_object_object_add(cc1,tmpMap3->value,cc0);
1847                  else
1848                    json_object_object_add(cc1,"application/json",cc0);
1849                  json_object *cc2=json_object_new_object();
1850                  json_object_object_add(cc2,"content",cc1);
1851                  vMap=getMap(tmpMaps1->content,"abstract");
1852                  if(vMap!=NULL)
1853                    json_object_object_add(cc2,"description",json_object_new_string(vMap->value));
1854                  json_object_object_add(cc2,"required",json_object_new_boolean(true));
1855                  json_object_object_add(methodc,"requestBody",cc2);
1856
1857                }               
1858              }
1859              // TODO: callbacks
1860              tmpMaps1=getMaps(conf,"callbacks");
1861              if(tmpMaps1!=NULL){
1862                map* pmTmp2=getMap(tmpMaps1->content,"length");
1863                int iLen=atoi(pmTmp2->value);
1864                json_object *pajRes=json_object_new_object();
1865                for(int i=0;i<iLen;i++){
1866                  map* pmState=getMapArray(tmpMaps1->content,"state",i);
1867                  map* pmUri=getMapArray(tmpMaps1->content,"uri",i);
1868                  map* pmSchema=getMapArray(tmpMaps1->content,"schema",i);
1869                  map* pmType=getMapArray(tmpMaps1->content,"type",i);
1870                  map* pmTitle=getMapArray(tmpMaps1->content,"title",i);
1871                  json_object *pajSchema=json_object_new_object();
1872                  if(pmSchema!=NULL)
1873                    json_object_object_add(pajSchema,"$ref",json_object_new_string(pmSchema->value));
1874                  json_object *pajType=json_object_new_object();
1875                  json_object_object_add(pajType,"schema",pajSchema);
1876                  json_object *pajContent=json_object_new_object();
1877                  if(pmType!=NULL)
1878                    json_object_object_add(pajContent,pmType->value,pajType);
1879                  else           
1880                    json_object_object_add(pajContent,"application/json",pajType);
1881                  json_object *pajRBody=json_object_new_object();
1882                  json_object_object_add(pajRBody,"content",pajContent);
1883                 
1884                  json_object *pajDescription=json_object_new_object();
1885                  json_object *pajPost=json_object_new_object();
1886                  if(pmTitle!=NULL){
1887                    json_object_object_add(pajDescription,"description",json_object_new_string(pmTitle->value));
1888                    json_object_object_add(pajPost,"summary",json_object_new_string(pmTitle->value));
1889                  }
1890                  json_object *pajResponse=json_object_new_object();
1891                  json_object_object_add(pajResponse,"200",pajDescription);
1892
1893                  json_object_object_add(pajPost,"requestBody",pajRBody);
1894                  json_object_object_add(pajPost,"responses",pajResponse);
1895                  json_object_object_add(pajPost,"operationId",json_object_new_string(pmState->value));
1896
1897                  json_object *pajMethod=json_object_new_object();
1898                  json_object_object_add(pajMethod,"post",pajPost);
1899
1900                 
1901                  char* pacUri=(char*) malloc((strlen(pmUri->value)+29)*sizeof(char));
1902                  sprintf(pacUri,"{$request.body#/subscriber/%s}",pmUri->value);
1903
1904                  json_object *pajFinal=json_object_new_object();
1905                  json_object_object_add(pajFinal,pacUri,pajMethod);
1906                  json_object_object_add(pajRes,pmState->value,pajFinal);
1907
1908                }
1909                json_object_object_add(methodc,"callbacks",pajRes);
1910              }
1911            }
1912            map* mMap=getMapArray(tmpMaps->content,"method",i);
1913            if(mMap!=NULL)
1914              json_object_object_add(method,mMap->value,methodc);
1915            else
1916              json_object_object_add(method,"get",methodc);
1917
1918          }
1919
1920          tmpMap=getMapFromMaps(conf,"openapi","version");
1921          if(tmpMap!=NULL)
1922            json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
1923          else
1924            json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
1925          if(strstr(tmps,"/root")!=NULL)
1926            json_object_object_add(paths,"/",method);
1927          else
1928            json_object_object_add(paths,tmps,method);
1929        }
1930        tmps = strtok_r (NULL, ",", &saveptr);
1931        cnt++;
1932      }
1933      json_object_object_add(res,"paths",paths);
1934    }
1935     
1936    tmpMap=getMapFromMaps(conf,"openapi","links");
1937    if(tmpMap!=NULL){
1938       
1939    }
1940   
1941    json_object *res3=json_object_new_array();
1942    json_object_array_add(res3,res4);
1943    json_object_object_add(res,"servers",res3);
1944  }
1945 
1946#ifdef __cplusplus
1947}
1948#endif
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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