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

Last change on this file since 962 was 962, checked in by djay, 14 months ago

Update OGC API - Processes documentation and implementation, providing a browsable User Interface to Processes.

  • Property svn:keywords set to Id
File size: 71.8 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(pacTmp);
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      return NULL;
1378    }
1379    return pajObj;
1380  }
1381 
1382  json_object* json_readFile(maps* conf,char* filePath){
1383    json_object *pajObj = NULL;
1384    zStatStruct zsFStatus;
1385    int iS=zStat(filePath, &zsFStatus);
1386    if(iS==0 && zsFStatus.st_size>0){
1387      FILE* cdat=fopen(filePath,"rb");
1388      if(cdat!=NULL){
1389        char* pacMyString=(char*)malloc((zsFStatus.st_size+1)*sizeof(char));
1390        fread(pacMyString,1,zsFStatus.st_size,cdat);
1391        pacMyString[zsFStatus.st_size]=0;
1392        fclose(cdat);
1393        pajObj=parseJson(conf,pacMyString);
1394        free(pacMyString);
1395      }
1396      else
1397        return NULL;
1398    }else
1399      return NULL;
1400    return pajObj;
1401  }
1402 
1403  json_object* createStatus(maps* conf,int status){
1404    int needResult=0;
1405    const char *rstatus;
1406    char *message;
1407    // Create statusInfo JSON object
1408    // cf. https://github.com/opengeospatial/wps-rest-binding/blob/master/core/
1409    //     openapi/schemas/statusInfo.yaml
1410    json_object* res=json_object_new_object();
1411    switch(status){
1412    case SERVICE_ACCEPTED:
1413      {
1414        message=_("ZOO-Kernel accepted to run your service!");
1415        rstatus="accepted";
1416        break;
1417      }
1418    case SERVICE_STARTED:
1419      {
1420        message=_("ZOO-Kernel is currently running your service!");
1421        map* pmStatus=getMapFromMaps(conf,"lenv","status");
1422        if(pmStatus!=NULL)
1423          setMapInMaps(conf,"lenv","PercentCompleted",pmStatus->value);
1424        pmStatus=getMapFromMaps(conf,"lenv","message");
1425        if(pmStatus!=NULL)
1426          setMapInMaps(conf,"lenv","gs_message",pmStatus->value);
1427        rstatus="running";
1428        break;
1429      }
1430    case SERVICE_PAUSED:
1431      {
1432        message=_("ZOO-Kernel pause your service!");
1433        rstatus="paused";
1434        break;
1435      }
1436    case SERVICE_SUCCEEDED:
1437      {
1438        message=_("ZOO-Kernel successfully run your service!");
1439        rstatus="successful";
1440        setMapInMaps(conf,"lenv","PercentCompleted","100");
1441        needResult=1;
1442        break;
1443      }
1444    case SERVICE_DISMISSED:
1445      {
1446        message=_("ZOO-Kernel successfully dismissed your service!");
1447        rstatus="dismissed";
1448        needResult=1;
1449        break;
1450      }
1451    default:
1452      {
1453        map* pmTmp=getMapFromMaps(conf,"lenv","force");
1454        if(pmTmp==NULL || strncasecmp(pmTmp->value,"false",5)==0){
1455          char* pacTmp=json_getStatusFilePath(conf);
1456          json_object* pjoStatus=json_readFile(conf,pacTmp);
1457          free(pacTmp);
1458          if(pjoStatus!=NULL){
1459            json_object* pjoMessage=NULL;
1460            if(json_object_object_get_ex(pjoStatus,"message",&pjoMessage)!=FALSE){
1461              message=(char*)json_object_get_string(pjoMessage);
1462            }
1463          }
1464          // TODO: Error
1465        }else{
1466          map* mMap=getMapFromMaps(conf,"lenv","gs_message");
1467          if(mMap!=NULL)
1468            setMapInMaps(conf,"lenv","message",mMap->value);
1469          message=produceErrorMessage(conf);
1470          needResult=-1;
1471        }
1472        rstatus="failed";
1473        break;
1474      }
1475    }
1476    setMapInMaps(conf,"lenv","message",message);
1477    setMapInMaps(conf,"lenv","status",rstatus);
1478
1479    map *sessId = getMapFromMaps (conf, "lenv", "usid");
1480    if(sessId!=NULL){
1481      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1482      if(sessId==NULL)
1483        sessId = getMapFromMaps (conf, "lenv", "usid");
1484    }else
1485      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
1486    if(sessId!=NULL)
1487      json_object_object_add(res,"jobID",json_object_new_string(sessId->value));
1488    json_object_object_add(res,"status",json_object_new_string(rstatus));
1489    map* mMap=getMapFromMaps(conf,"lenv","gs_message");
1490    if(mMap==NULL)
1491      json_object_object_add(res,"message",json_object_new_string(message));
1492    else{
1493      json_object_object_add(res,"message",json_object_new_string(mMap->value));
1494      if((mMap=getMapFromMaps(conf,"lenv","PercentCompleted"))!=NULL)
1495        json_object_object_add(res,"progress",json_object_new_int(atoi(mMap->value)));
1496    }
1497    if(status!=SERVICE_DISMISSED)
1498      createStatusLinks(conf,needResult,res);
1499    else{
1500      json_object* res1=json_object_new_array();
1501      map *tmpPath = getMapFromMaps (conf, "openapi", "rootUrl");
1502      map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
1503      char *Url0=(char*) malloc((strlen(tmpPath->value)+
1504                                 strlen(cIdentifier->value)+
1505                                 17)*sizeof(char));
1506      sprintf(Url0,"%s/processes/%s/jobs",           
1507              tmpPath->value,
1508              cIdentifier->value);
1509      json_object* val=json_object_new_object();
1510      json_object_object_add(val,"title",
1511                             json_object_new_string(_("The job list for the current process")));
1512      json_object_object_add(val,"rel",
1513                             json_object_new_string(_("parent")));
1514      json_object_object_add(val,"type",
1515                             json_object_new_string(_("application/json")));
1516      json_object_object_add(val,"href",json_object_new_string(Url0));
1517      json_object_array_add(res1,val);
1518      free(Url0);
1519      json_object_object_add(res,"links",res1);
1520    }
1521    if(needResult<0)
1522      free(message);
1523    return res;
1524  }
1525 
1526  /**
1527   * Create the status file
1528   *
1529   * @param conf the maps containing the settings of the main.cfg file
1530   * @param status an integer (SERVICE_ACCEPTED,SERVICE_STARTED...)
1531   * @return an integer (0 in case of success, 1 in case of failure)
1532   */
1533  int createStatusFile(maps* conf,int status){
1534    json_object* res=createStatus(conf,status);
1535    char* tmp1=json_getStatusFilePath(conf);
1536    FILE* foutput1=fopen(tmp1,"w+");
1537    if(foutput1!=NULL){
1538      const char* jsonStr1=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
1539      fprintf(foutput1,"%s",jsonStr1);
1540      fclose(foutput1);
1541    }else{
1542      // Failure
1543      setMapInMaps(conf,"lenv","message",_("Unable to store the statusInfo!"));
1544      free(tmp1);
1545      return 1;
1546    }
1547    free(tmp1);
1548    return 0;
1549  }
1550
1551  /**
1552   * Create the status file
1553   *
1554   * @param conf the maps containing the settings of the main.cfg file
1555   * @return an integer (0 in case of success, 1 in case of failure)
1556   */
1557  int json_getStatusFile(maps* conf){
1558    char* tmp1=json_getStatusFilePath(conf);
1559    FILE* statusFile=fopen(tmp1,"rb");
1560
1561    map* tmpMap=getMapFromMaps(conf,"lenv","gs_usid");
1562    if(tmpMap!=NULL){
1563      char* tmpStr=_getStatus(conf,tmpMap->value);
1564      if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
1565        char *tmpStr1=zStrdup(tmpStr);
1566        char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
1567        free(tmpStr);
1568        tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
1569        setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
1570        setMapInMaps(conf,"lenv","gs_message",tmpStr0);
1571        free(tmpStr0);
1572        free(tmpStr1);
1573        return 0;
1574      }else{
1575         
1576      }
1577    }
1578  }
1579
1580  /**
1581   * Produce the JSON object for api info object
1582   *
1583   * @param conf the maps containing the settings of the main.cfg file
1584   * @param res the JSON object for the api info
1585   */
1586  void produceApiInfo(maps* conf,json_object* res,json_object* res5){
1587    json_object *res1=json_object_new_object();
1588    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
1589    if(tmpMap!=NULL){
1590      json_object *res2=json_object_new_object();
1591      json_object_object_add(res2,"name",json_object_new_string(tmpMap->value));
1592      tmpMap=getMapFromMaps(conf,"provider","addressElectronicMailAddress");
1593      if(tmpMap!=NULL)
1594        json_object_object_add(res2,"email",json_object_new_string(tmpMap->value));
1595      tmpMap=getMapFromMaps(conf,"provider","providerSite");
1596      if(tmpMap!=NULL)
1597        json_object_object_add(res2,"url",json_object_new_string(tmpMap->value));
1598      json_object_object_add(res1,"contact",res2);
1599    }
1600    tmpMap=getMapFromMaps(conf,"identification","abstract");
1601    if(tmpMap!=NULL){
1602      json_object_object_add(res1,"description",json_object_new_string(tmpMap->value));
1603      json_object_object_add(res5,"description",json_object_new_string(tmpMap->value));
1604      tmpMap=getMapFromMaps(conf,"openapi","rootUrl");
1605      json_object_object_add(res5,"url",json_object_new_string(tmpMap->value));
1606    }
1607    tmpMap=getMapFromMaps(conf,"identification","title");
1608    if(tmpMap!=NULL)
1609      json_object_object_add(res1,"title",json_object_new_string(tmpMap->value));
1610    json_object_object_add(res1,"version",json_object_new_string(ZOO_VERSION));
1611    tmpMap=getMapFromMaps(conf,"identification","keywords");
1612    if(tmpMap!=NULL){
1613      char *saveptr;
1614      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
1615      json_object *res3=json_object_new_array();
1616      while (tmps != NULL){
1617        json_object_array_add(res3,json_object_new_string(tmps));
1618        tmps = strtok_r (NULL, ",", &saveptr);
1619      }
1620      json_object_object_add(res1,"x-keywords",res3);
1621    }
1622    maps* tmpMaps=getMaps(conf,"provider");
1623    if(tmpMaps!=NULL){
1624      json_object *res4=json_object_new_object();
1625      map* cItem=tmpMaps->content;
1626      while(cItem!=NULL){
1627        json_object_object_add(res4,cItem->name,json_object_new_string(cItem->value));
1628        cItem=cItem->next;
1629      }
1630      json_object_object_add(res1,"x-ows-servicecontact",res4);
1631    }
1632
1633    json_object *res4=json_object_new_object();
1634    tmpMap=getMapFromMaps(conf,"openapi","license_name");
1635    if(tmpMap!=NULL){
1636      json_object_object_add(res4,"name",json_object_new_string(tmpMap->value));
1637      tmpMap=getMapFromMaps(conf,"openapi","license_url");
1638      if(tmpMap!=NULL){
1639        json_object_object_add(res4,"url",json_object_new_string(tmpMap->value));     
1640      }
1641    }
1642    json_object_object_add(res1,"license",res4);
1643
1644    json_object_object_add(res,"info",res1);   
1645  }
1646
1647  // addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
1648  void addResponse(const map* useContent,json_object* res,const map* pmSchema,const map* pmType,const char* code,const char* msg){
1649    json_object *cc=json_object_new_object();
1650    if(pmSchema!=NULL)
1651      json_object_object_add(cc,"$ref",json_object_new_string(pmSchema->value));
1652    if(useContent!=NULL && strncasecmp(useContent->value,"true",4)!=0){
1653        json_object_object_add(res,code,cc);
1654    }else{
1655        json_object *cc0=json_object_new_object();
1656        if(pmSchema!=NULL)
1657          json_object_object_add(cc0,"schema",cc);
1658        json_object *cc1=json_object_new_object();
1659        if(pmType!=NULL)
1660          json_object_object_add(cc1,pmType->value,cc0);
1661        else
1662          json_object_object_add(cc1,"application/json",cc0);
1663        json_object *cc2=json_object_new_object();
1664        json_object_object_add(cc2,"content",cc1);
1665        json_object_object_add(cc2,"description",json_object_new_string(msg));
1666        json_object_object_add(res,code,cc2);
1667    }
1668  }
1669
1670  void addParameter(maps* conf,const char* oName,const char* fName,const char* in,json_object* res){
1671    maps* tmpMaps1=getMaps(conf,oName);
1672    json_object *res8=json_object_new_object();
1673    if(tmpMaps1!=NULL){
1674      map* tmpMap=getMap(tmpMaps1->content,"title");
1675      if(tmpMap!=NULL)
1676        json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
1677      tmpMap=getMap(tmpMaps1->content,"abstract");
1678      if(tmpMap!=NULL)
1679        json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
1680      tmpMap=getMap(tmpMaps1->content,"example");
1681      if(tmpMap!=NULL)
1682        json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
1683      tmpMap=getMap(tmpMaps1->content,"required");
1684      if(tmpMap!=NULL){
1685        if(strcmp(tmpMap->value,"true")==0)
1686          json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
1687        else
1688          json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
1689      }
1690      else
1691        json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
1692      json_object_object_add(res8,"in",json_object_new_string(in));
1693      json_object_object_add(res8,"name",json_object_new_string(fName));
1694      json_object *res6=json_object_new_object();
1695      tmpMap=getMap(tmpMaps1->content,"type");
1696      if(tmpMap!=NULL)
1697        json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
1698      else
1699        json_object_object_add(res6,"type",json_object_new_string("string"));
1700       
1701      json_object_object_add(res8,"schema",res6);
1702       
1703    }   
1704    json_object_object_add(res,fName,res8);   
1705  }
1706 
1707  /**
1708   * Produce the JSON object for api parameter
1709   *
1710   * @param conf the maps containing the settings of the main.cfg file
1711   * @param res the JSON object to populate with the parameters
1712   */
1713  void produceApiParameters(maps* conf,json_object* res){
1714    json_object *res9=json_object_new_object();
1715    maps* tmpMaps1=getMaps(conf,"{id}");
1716    map* tmpMap2=getMapFromMaps(conf,"openapi","parameters");
1717    char *saveptr12;
1718    char *tmps12 = strtok_r (tmpMap2->value, ",", &saveptr12);
1719    while(tmps12!=NULL){
1720      char* pacId=(char*) malloc((strlen(tmps12)+3)*sizeof(char));
1721      sprintf(pacId,"{%s}",tmps12);
1722      addParameter(conf,pacId,tmps12,"path",res9);
1723      free(pacId);
1724      tmps12 = strtok_r (NULL, ",", &saveptr12);
1725    }   
1726    tmpMap2=getMapFromMaps(conf,"openapi","header_parameters");
1727    if(tmpMap2!=NULL){
1728      char *saveptr13;
1729      char *tmps13 = strtok_r (tmpMap2->value, ",", &saveptr13);
1730      while(tmps13!=NULL){
1731        char* pacId=zStrdup(tmps13);
1732        addParameter(conf,pacId,pacId,"header",res9);
1733        free(pacId);
1734        tmps13 = strtok_r (NULL, ",", &saveptr13);
1735      }
1736    }
1737    json_object_object_add(res,"parameters",res9);
1738    maps* pmResponses=getMaps(conf,"responses");
1739    if(pmResponses!=NULL){
1740      json_object *cc=json_object_new_object();
1741      map* pmLen=getMap(pmResponses->content,"length");
1742      int iLen=atoi(pmLen->value);
1743      map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
1744      for(int i=0;i<iLen;i++){
1745        map* cMap=getMapArray(pmResponses->content,"code",i);
1746        map* vMap=getMapArray(pmResponses->content,"schema",i);
1747        map* tMap=getMapArray(pmResponses->content,"type",i);
1748        map* tMap0=getMapArray(pmResponses->content,"title",i);
1749        if(vMap!=NULL)
1750          addResponse(pmUseContent,cc,vMap,tMap,cMap->value,(tMap0==NULL)?"successful operation":tMap0->value);
1751      }
1752      json_object_object_add(res,"responses",cc);
1753    }
1754  }
1755
1756  void produceApiComponents(maps*conf,json_object* res){
1757    json_object* res1=json_object_new_object();
1758    produceApiParameters(conf,res1);
1759    json_object_object_add(res,"components",res1);
1760  }
1761 
1762  /**
1763   * Produce the JSON object for /api
1764   *
1765   * @param conf the maps containing the settings of the main.cfg file
1766   * @param res the JSON object to populate
1767   */
1768  void produceApi(maps* conf,json_object* res){
1769    // TODO: add 401 Gone for dismiss request
1770    json_object *res9=json_object_new_object();
1771    json_object *res10=json_object_new_object();
1772    maps* tmpMaps1=getMaps(conf,"{id}");
1773    produceApiComponents(conf,res);
1774    json_object *res4=json_object_new_object();
1775    setMapInMaps(conf,"headers","Content-Type","application/openapi+json; version=3.0;charset=UTF-8");
1776
1777    produceApiInfo(conf,res,res4);
1778    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
1779
1780    tmpMap=getMapFromMaps(conf,"openapi","version");
1781    if(tmpMap!=NULL)
1782      json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
1783    else
1784      json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
1785
1786    tmpMap=getMapFromMaps(conf,"openapi","paths");
1787    if(tmpMap!=NULL){
1788      json_object *res5=json_object_new_object();
1789      char *saveptr;
1790      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
1791      int cnt=0;
1792      maps* tmpMaps;
1793      json_object *paths=json_object_new_object();
1794      while (tmps != NULL){
1795        tmpMaps=getMaps(conf,tmps+1);
1796        json_object *method=json_object_new_object();
1797        if(tmpMaps!=NULL){
1798          if(getMap(tmpMaps->content,"length")==NULL)
1799            addToMap(tmpMaps->content,"length","1");
1800          map* len=getMap(tmpMaps->content,"length");
1801           
1802          for(int i=0;i<atoi(len->value);i++){
1803            json_object *methodc=json_object_new_object();
1804            map* cMap=getMapArray(tmpMaps->content,"method",i);
1805            map* vMap=getMapArray(tmpMaps->content,"title",i);
1806            if(vMap!=NULL)
1807              json_object_object_add(methodc,"summary",json_object_new_string(vMap->value));
1808            vMap=getMapArray(tmpMaps->content,"abstract",i);
1809            if(vMap!=NULL)
1810              json_object_object_add(methodc,"description",json_object_new_string(vMap->value));
1811            vMap=getMapArray(tmpMaps->content,"tags",i);
1812            if(vMap!=NULL){
1813              json_object *cc=json_object_new_array();
1814              json_object_array_add(cc,json_object_new_string(vMap->value));
1815              json_object_object_add(methodc,"tags",cc);
1816            }
1817            json_object *responses=json_object_new_object();
1818            json_object *cc3=json_object_new_object();
1819            map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
1820            vMap=getMapArray(tmpMaps->content,"schema",i);
1821            if(vMap!=NULL){
1822              map* tMap=getMapArray(tmpMaps->content,"type",i);
1823              addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
1824              vMap=getMapArray(tmpMaps->content,"eschema",i);
1825              if(vMap!=NULL && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
1826                addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
1827            }else{
1828              map* tMap=getMapFromMaps(conf,tmps,"type");
1829              map* pMap=createMap("ok","true");
1830              addResponse(pMap,cc3,vMap,tMap,"200","successful operation");
1831              if(cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
1832                addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
1833            }
1834            vMap=getMapArray(tmpMaps->content,"ecode",i);
1835            if(vMap!=NULL){
1836              char *saveptr0;
1837              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
1838              while(tmps1!=NULL){
1839                char* tmpStr=(char*)malloc((strlen(tmps1)+24)*sizeof(char));
1840                sprintf(tmpStr,"#/components/responses/%s",tmps1);
1841                vMap=createMap("ok",tmpStr);
1842                map* pMap=createMap("ok","false");
1843                //TODO: fix successful operation with correct value
1844                addResponse(pMap,cc3,vMap,NULL,tmps1,"successful operation");
1845                tmps1 = strtok_r (NULL, ",", &saveptr0);
1846              }
1847            }else{
1848              if(strstr(tmps,"{id}")!=NULL){
1849                vMap=getMapFromMaps(conf,"exception","schema");
1850                map* tMap=getMapFromMaps(conf,"exception","type");
1851                if(vMap!=NULL)
1852                  addResponse(pmUseContent,cc3,vMap,tMap,"404",
1853                              (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.");
1854              }
1855            }
1856            json_object_object_add(methodc,"responses",cc3);
1857            vMap=getMapArray(tmpMaps->content,"parameters",i);
1858            if(vMap!=NULL){
1859              char *saveptr0;
1860              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
1861              json_object *cc2=json_object_new_array();
1862              int cnt=0;
1863              while(tmps1!=NULL){
1864                char* tmpStr=(char*)malloc((strlen(tmps1)+2)*sizeof(char));
1865                sprintf(tmpStr,"#%s",tmps1);
1866                json_object *cc1=json_object_new_object();
1867                json_object_object_add(cc1,"$ref",json_object_new_string(tmpStr));
1868                json_object_array_add(cc2,cc1);
1869                free(tmpStr);
1870                cnt++;
1871                tmps1 = strtok_r (NULL, ",", &saveptr0);
1872              }
1873              json_object_object_add(methodc,"parameters",cc2);
1874            }
1875            if(i==1 && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0){
1876              maps* tmpMaps1=getMaps(conf,"requestBody");
1877              if(tmpMaps1!=NULL){
1878                vMap=getMap(tmpMaps1->content,"schema");
1879                if(vMap!=NULL){
1880                  json_object *cc=json_object_new_object();
1881                  json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
1882                  json_object *cc0=json_object_new_object();
1883                  json_object_object_add(cc0,"schema",cc);
1884                  json_object *cc1=json_object_new_object();
1885                  map* tmpMap3=getMap(tmpMaps->content,"type");
1886                  if(tmpMap3!=NULL)
1887                    json_object_object_add(cc1,tmpMap3->value,cc0);
1888                  else
1889                    json_object_object_add(cc1,"application/json",cc0);
1890                  json_object *cc2=json_object_new_object();
1891                  json_object_object_add(cc2,"content",cc1);
1892                  vMap=getMap(tmpMaps1->content,"abstract");
1893                  if(vMap!=NULL)
1894                    json_object_object_add(cc2,"description",json_object_new_string(vMap->value));
1895                  json_object_object_add(cc2,"required",json_object_new_boolean(true));
1896                  json_object_object_add(methodc,"requestBody",cc2);
1897
1898                }               
1899              }
1900              // TODO: callbacks
1901              tmpMaps1=getMaps(conf,"callbacks");
1902              if(tmpMaps1!=NULL){
1903                map* pmTmp2=getMap(tmpMaps1->content,"length");
1904                int iLen=atoi(pmTmp2->value);
1905                json_object *pajRes=json_object_new_object();
1906                for(int i=0;i<iLen;i++){
1907                  map* pmState=getMapArray(tmpMaps1->content,"state",i);
1908                  map* pmUri=getMapArray(tmpMaps1->content,"uri",i);
1909                  map* pmSchema=getMapArray(tmpMaps1->content,"schema",i);
1910                  map* pmType=getMapArray(tmpMaps1->content,"type",i);
1911                  map* pmTitle=getMapArray(tmpMaps1->content,"title",i);
1912                  json_object *pajSchema=json_object_new_object();
1913                  if(pmSchema!=NULL)
1914                    json_object_object_add(pajSchema,"$ref",json_object_new_string(pmSchema->value));
1915                  json_object *pajType=json_object_new_object();
1916                  json_object_object_add(pajType,"schema",pajSchema);
1917                  json_object *pajContent=json_object_new_object();
1918                  if(pmType!=NULL)
1919                    json_object_object_add(pajContent,pmType->value,pajType);
1920                  else           
1921                    json_object_object_add(pajContent,"application/json",pajType);
1922                  json_object *pajRBody=json_object_new_object();
1923                  json_object_object_add(pajRBody,"content",pajContent);
1924                 
1925                  json_object *pajDescription=json_object_new_object();
1926                  if(pmTitle!=NULL)
1927                    json_object_object_add(pajDescription,"description",json_object_new_string(pmTitle->value));
1928                  json_object *pajResponse=json_object_new_object();
1929                  json_object_object_add(pajResponse,"200",pajDescription);
1930
1931                  json_object *pajPost=json_object_new_object();
1932                  json_object_object_add(pajPost,"requestBody",pajRBody);
1933                  json_object_object_add(pajPost,"responses",pajResponse);
1934
1935                  json_object *pajMethod=json_object_new_object();
1936                  json_object_object_add(pajMethod,"post",pajPost);
1937
1938                 
1939                  char* pacUri=(char*) malloc((strlen(pmUri->value)+29)*sizeof(char));
1940                  sprintf(pacUri,"{$request.body#/subscriber/%s}",pmUri->value);
1941
1942                  json_object *pajFinal=json_object_new_object();
1943                  json_object_object_add(pajFinal,pacUri,pajMethod);
1944
1945                  json_object_object_add(pajRes,pmState->value,pajFinal);
1946
1947                }
1948                json_object_object_add(methodc,"callbacks",pajRes);
1949              }
1950            }
1951            map* mMap=getMapArray(tmpMaps->content,"method",i);
1952            if(mMap!=NULL)
1953              json_object_object_add(method,mMap->value,methodc);
1954            else
1955              json_object_object_add(method,"get",methodc);
1956
1957          }
1958
1959          tmpMap=getMapFromMaps(conf,"openapi","version");
1960          if(tmpMap!=NULL)
1961            json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
1962          else
1963            json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
1964          if(strstr(tmps,"/root")!=NULL)
1965            json_object_object_add(paths,"/",method);
1966          else
1967            json_object_object_add(paths,tmps,method);
1968        }
1969        tmps = strtok_r (NULL, ",", &saveptr);
1970        cnt++;
1971      }
1972      json_object_object_add(res,"paths",paths);
1973    }
1974     
1975    tmpMap=getMapFromMaps(conf,"openapi","links");
1976    if(tmpMap!=NULL){
1977       
1978    }
1979   
1980    json_object *res3=json_object_new_array();
1981    json_object_array_add(res3,res4);
1982    json_object_object_add(res,"servers",res3);
1983  }
1984 
1985#ifdef __cplusplus
1986}
1987#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