Ignore:
Timestamp:
Sep 5, 2019, 10:16:21 AM (5 years ago)
Author:
djay
Message:

Prototype implementation of the OGC API - Processing and other simplifications

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/zoo-project/zoo-kernel/service_json.c

    r917 r949  
    22 * Author : Gérald FENOY
    33 *
    4  *  Copyright 2017 GeoLabs SARL. All rights reserved.
     4 *  Copyright 2017-2019 GeoLabs SARL. All rights reserved.
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a copy
     
    2424
    2525#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>
    2634
    2735#ifdef __cplusplus
    2836extern "C" {
    2937#endif
    30 
     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   */
    3154  json_object* mapToJson(map* myMap){
    3255    json_object *res=json_object_new_object();
     
    6790  }
    6891
     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   */
    6997  json_object* mapsToJson(maps* myMap){
    7098    json_object *res=json_object_new_object();
     
    73101      json_object *obj=NULL;
    74102      if(cursor->content!=NULL){
    75         //json_object *content=NULL;
    76103        obj=mapToJson(cursor->content);
    77         //json_object_object_add(obj,"content",content);
    78104      }else
    79105        obj=json_object_new_object();
     
    89115  }
    90116
     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   */
    91122  json_object* elementsToJson(elements* myElements){
    92123    json_object *res=json_object_new_object();
     
    112143        }
    113144        json_object_object_add(cres,"supported",resi);
    114         fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
    115         fflush(stderr);
    116145      }
    117146     
    118       dumpElements(cur->child);
    119147      json_object_object_add(cres,"child",elementsToJson(cur->child));
    120       fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
    121       fflush(stderr);
    122148
    123149      json_object_object_add(res,cur->name,cres);
     
    127153  }
    128154 
     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   */
    129160  json_object* serviceToJson(service* myService){
    130161    json_object *res=json_object_new_object();
     
    137168    return res;
    138169  }
     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  }
    139209 
     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        json_object_object_add(prop1,"dataType",prop2);
     226      }
     227      tmpMap1=getMap(in->defaults->content,"value");
     228      if(tmpMap1!=NULL)
     229        json_object_object_add(prop1,"defaultValue",json_object_new_string(tmpMap1->value));
     230      json_object* prop3=json_object_new_object();
     231      tmpMap1=getMap(in->defaults->content,"rangeMin");
     232      if(tmpMap1!=NULL){
     233        json_object* prop5=json_object_new_array();
     234        printAllowedRangesJ(m,in->defaults,prop5);
     235        if(in->supported!=NULL){
     236          iotype* iot=in->supported;
     237          while(iot!=NULL){
     238            printAllowedRangesJ(m,iot,prop5);
     239            iot=iot->next;
     240          }
     241        }
     242        json_object_object_add(prop3,"allowedRanges",prop5);
     243      }
     244      else{
     245        tmpMap1=getMap(in->defaults->content,"range");
     246        if(tmpMap1!=NULL){
     247          // TODO: parse range = [rangeMin,rangeMax]
     248        }else{
     249          // AllowedValues
     250          tmpMap1=getMap(in->defaults->content,"AllowedValues");
     251          if(tmpMap1!=NULL){
     252            char* saveptr;
     253            json_object* prop5=json_object_new_array();
     254            char *tmps = strtok_r (tmpMap1->value, ",", &saveptr);
     255            while(tmps!=NULL){
     256              json_object_array_add(prop5,json_object_new_string(tmps));
     257              tmps = strtok_r (NULL, ",", &saveptr);
     258            }
     259            json_object_object_add(prop3,"allowedValues",prop5);
     260           
     261          }else{
     262            json_object_object_add(prop3,"anyValue",json_object_new_boolean(true));
     263          }
     264        }
     265      }
     266      json_object_object_add(prop1,"valueDefinition",prop3);
     267      json_object_array_add(prop0,prop1);
     268    }
     269    json_object_object_add(input,"literalDataDomains",prop0);
     270  }
     271
     272  /**
     273   * Add Format properties to a json_object
     274   * @param m the main configuration maps pointer
     275   * @param iot the current iotype pointer
     276   * @param res the json_object pointer to add the properties to
     277   * @param isDefault boolean specifying if the currrent iotype is default
     278   * @param maxSize a map pointer to the maximumMegabytes param defined in the zcfg file for this input/output
     279   */
     280  void printFormatJ(maps* m,iotype* iot,json_object* res,bool isDefault,map* maxSize){
     281    if(iot!=NULL){
     282      map* tmpMap1=getMap(iot->content,"mimeType");
     283      json_object* prop1=json_object_new_object();
     284      json_object_object_add(prop1,"default",json_object_new_boolean(isDefault));
     285      json_object_object_add(prop1,"mimeType",json_object_new_string(tmpMap1->value));
     286      tmpMap1=getMap(iot->content,"encoding");
     287      if(tmpMap1!=NULL)
     288        json_object_object_add(prop1,"encoding",json_object_new_string(tmpMap1->value));
     289      tmpMap1=getMap(iot->content,"schema");
     290      if(tmpMap1!=NULL)
     291        json_object_object_add(prop1,"schema",json_object_new_string(tmpMap1->value));
     292      if(maxSize!=NULL)
     293        json_object_object_add(prop1,"maximumMegabytes",json_object_new_int64(atoll(maxSize->value)));
     294      json_object_array_add(res,prop1);
     295    }
     296  }
     297
     298  /**
     299   * Add additionalParameters property to a json_object
     300   * @param conf the main configuration maps pointer
     301   * @param meta a map pointer to the current metadata informations
     302   * @param doc the json_object pointer to add the property to
     303   */
     304  void printJAdditionalParameters(maps* conf,map* meta,json_object* doc){
     305    map* cmeta=meta;
     306    json_object* carr=json_object_new_array();
     307    int hasElement=-1;
     308    json_object* jcaps=json_object_new_object();
     309    while(cmeta!=NULL){
     310      json_object* jcmeta=json_object_new_object();
     311      if(strcasecmp(cmeta->name,"role")!=0 &&
     312         strcasecmp(cmeta->name,"href")!=0 &&
     313         strcasecmp(cmeta->name,"title")!=0 &&
     314         strcasecmp(cmeta->name,"length")!=0 ){
     315        json_object_object_add(jcmeta,"name",json_object_new_string(cmeta->name));
     316        json_object_object_add(jcmeta,"value",json_object_new_string(cmeta->value));
     317        json_object_array_add(carr,jcmeta);
     318        hasElement++;
     319      }else{
     320        if(strcasecmp(cmeta->name,"length")!=0)
     321          json_object_object_add(jcaps,cmeta->name,json_object_new_string(cmeta->value));
     322      }
     323      cmeta=cmeta->next;
     324    }
     325    if(hasElement>=0){
     326      json_object_object_add(jcaps,"additionalParameter",carr);
     327      json_object_object_add(doc,"additionalParameters",jcaps);
     328    }
     329  }
     330
     331  /**
     332   * Add metadata property to a json_object
     333   * @param conf the main configuration maps pointer
     334   * @param meta a map pointer to the current metadata informations
     335   * @param doc the json_object pointer to add the property to
     336   */
     337  void printJMetadata(maps* conf,map* meta,json_object* doc){
     338    map* cmeta=meta;
     339    json_object* carr=json_object_new_array();
     340    int hasElement=-1;
     341    while(cmeta!=NULL){
     342      json_object* jcmeta=json_object_new_object();
     343      if(strcasecmp(cmeta->name,"role")==0 ||
     344         strcasecmp(cmeta->name,"href")==0 ||
     345         strcasecmp(cmeta->name,"title")==0 ){
     346        json_object_object_add(jcmeta,cmeta->name,json_object_new_string(cmeta->value));
     347        hasElement++;
     348      }
     349      json_object_array_add(carr,jcmeta);
     350      cmeta=cmeta->next;
     351    }
     352    if(hasElement>=0)
     353      json_object_object_add(doc,"metadata",carr);
     354  }
     355
     356  /**
     357   * Add metadata properties to a json_object
     358   * @param m the main configuration maps pointer
     359   * @param io a string
     360   * @param in an elements pointer to the current input/output
     361   * @param inputs the json_object pointer to add the property to
     362   * @param serv the service pointer to extract the metadata from
     363   */
     364  void printIOTypeJ(maps* m, const char *io, elements* in,json_object* inputs,service* serv){
     365    while(in!=NULL){
     366      json_object* input=json_object_new_object();
     367      json_object_object_add(input,"id",json_object_new_string(in->name));
     368      map* tmpMap=getMap(in->content,"title");
     369      if(tmpMap!=NULL)
     370        json_object_object_add(input,"title",json_object_new_string(tmpMap->value));
     371      tmpMap=getMap(in->content,"abstract");
     372      if(tmpMap!=NULL)
     373        json_object_object_add(input,"abstract",json_object_new_string(tmpMap->value));
     374      if(strcmp(io,"input")==0){
     375        tmpMap=getMap(in->content,"minOccurs");
     376        if(tmpMap!=NULL)
     377          json_object_object_add(input,"minOccurs",json_object_new_string(tmpMap->value));
     378        tmpMap=getMap(in->content,"maxOccurs");
     379        if(tmpMap!=NULL)
     380          json_object_object_add(input,"maxOccurs",json_object_new_string(tmpMap->value));
     381      }
     382      if(in->format!=NULL){
     383        json_object* input1=json_object_new_object();
     384        json_object* prop0=json_object_new_array();
     385        if(strcasecmp(in->format,"LiteralData")==0 ||
     386           strcasecmp(in->format,"LiteralOutput")==0){
     387          printLiteralDataJ(m,in,input1);
     388        }else{
     389          if(strcasecmp(in->format,"ComplexData")==0 ||
     390             strcasecmp(in->format,"ComplexOutput")==0){
     391            map* sizeMap=getMap(in->content,"maximumMegabytes");
     392            printFormatJ(m,in->defaults,prop0,true,sizeMap);
     393            iotype* sup=in->supported;
     394            while(sup!=NULL){
     395              printFormatJ(m,sup,prop0,false,sizeMap);
     396              sup=sup->next;
     397            }
     398            json_object_object_add(input1,"formats",prop0);
     399          }
     400          else{
     401            json_object* prop1=json_object_new_object();
     402            json_object_object_add(prop1,"default",json_object_new_boolean(true));
     403            map* tmpMap1=getMap(in->defaults->content,"crs");
     404            if(tmpMap1==NULL)
     405              return;
     406            json_object_object_add(prop1,"crs",json_object_new_string(tmpMap1->value));
     407            json_object_array_add(prop0,prop1);
     408            iotype* sup=in->supported;
     409            while(sup!=NULL){
     410              json_object* prop1=json_object_new_object();
     411              json_object_object_add(prop1,"default",json_object_new_boolean(false));
     412              tmpMap1=getMap(sup->content,"crs");
     413              json_object_object_add(prop1,"crs",json_object_new_string(tmpMap1->value));
     414              json_object_array_add(prop0,prop1);
     415              sup=sup->next;
     416            }         
     417            json_object_object_add(input1,"supportedCRS",prop0);
     418          }
     419        }
     420        json_object_object_add(input,io,input1);
     421      }
     422      printJMetadata(m,in->metadata,input);
     423      printJAdditionalParameters(m,in->additional_parameters,input);
     424      json_object_array_add(inputs,input);     
     425      in=in->next;
     426    }
     427   
     428  }
     429
     430  /**
     431   * Add all the capabilities properties to a json_object
     432   * @param ref the registry pointer
     433   * @param m the main configuration maps pointer
     434   * @param doc0 the void (json_object) pointer to add the property to
     435   * @param nc0 the void (json_object) pointer to add the property to
     436   * @param serv the service pointer to extract the metadata from
     437   */
     438  void printGetCapabilitiesForProcessJ(registry *reg, maps* m,void* doc0,void* nc0,service* serv){
     439    json_object* doc=(json_object*) doc0;
     440    json_object* nc=(json_object*) nc0;
     441    json_object *res=json_object_new_object();
     442    map* tmpMap0=getMapFromMaps(m,"lenv","level");
     443    char* rUrl=serv->name;
     444    if(tmpMap0!=NULL && atoi(tmpMap0->value)>0){
     445      int i=0;
     446      maps* tmpMaps=getMaps(m,"lenv");
     447      char* tmpName=NULL;
     448      for(i=0;i<atoi(tmpMap0->value);i++){
     449        char* key=(char*)malloc(15*sizeof(char));
     450        sprintf(key,"sprefix_%d",i);
     451        map* tmpMap1=getMap(tmpMaps->content,key);
     452        if(i+1==atoi(tmpMap0->value))
     453          if(tmpName==NULL){
     454            tmpName=(char*) malloc((strlen(serv->name)+strlen(tmpMap1->value)+1)*sizeof(char));
     455            sprintf(tmpName,"%s%s",tmpMap1->value,serv->name);
     456          }else{
     457            char* tmpStr=zStrdup(tmpName);
     458            tmpName=(char*) realloc(tmpName,(strlen(tmpStr)+strlen(tmpMap1->value)+strlen(serv->name)+1)*sizeof(char));
     459            sprintf(tmpName,"%s%s%s",tmpStr,tmpMap1->value,serv->name);
     460            free(tmpStr);
     461          }
     462        else
     463          if(tmpName==NULL){
     464            tmpName=(char*) malloc((strlen(tmpMap1->value)+1)*sizeof(char));
     465            sprintf(tmpName,"%s",tmpMap1->value);
     466          }else{
     467            char* tmpStr=zStrdup(tmpName);
     468            tmpName=(char*) realloc(tmpName,(strlen(tmpStr)+strlen(tmpMap1->value)+1)*sizeof(char));
     469            sprintf(tmpName,"%s%s",tmpStr,tmpMap1->value);
     470            free(tmpStr);
     471          }
     472      }
     473      json_object_object_add(res,"id",json_object_new_string(tmpName));
     474      if(tmpName!=NULL){
     475        rUrl=zStrdup(tmpName);
     476        free(tmpName);
     477      }
     478    }
     479    else
     480      json_object_object_add(res,"id",json_object_new_string(serv->name));
     481    if(serv->content!=NULL){
     482      map* tmpMap=getMap(serv->content,"title");
     483      if(tmpMap!=NULL){
     484        json_object_object_add(res,"title",json_object_new_string(tmpMap->value));
     485      }
     486      tmpMap=getMap(serv->content,"abstract");
     487      if(tmpMap!=NULL){
     488        json_object_object_add(res,"abstract",json_object_new_string(tmpMap->value));
     489      }
     490      tmpMap=getMap(serv->content,"processVersion");
     491      if(tmpMap!=NULL){
     492        if(strlen(tmpMap->value)<5){
     493          char *val=(char*)malloc((strlen(tmpMap->value)+5)*sizeof(char));
     494          sprintf(val,"%s.0.0",tmpMap->value);
     495          json_object_object_add(res,"version",json_object_new_string(val));
     496          free(val);
     497        }
     498        else
     499          json_object_object_add(res,"version",json_object_new_string(tmpMap->value));
     500      }
     501      int limit=4;
     502      int i=0;
     503      map* sType=getMap(serv->content,"serviceType");
     504      for(;i<limit;i+=2){
     505        json_object *res1=json_object_new_object();
     506        json_object *res2=json_object_new_array();
     507        char *saveptr;
     508        char* dupStr=strdup(jcapabilities[i+1]);
     509        char *tmps = strtok_r (dupStr, " ", &saveptr);
     510        while(tmps!=NULL){
     511          json_object_array_add(res2,json_object_new_string(tmps));
     512          tmps = strtok_r (NULL, " ", &saveptr);
     513        }
     514        free(dupStr);
     515        json_object_object_add(res,jcapabilities[i],res2);
     516      }
     517      json_object *res1=json_object_new_array();
     518      json_object *res2=json_object_new_object();
     519      json_object_object_add(res2,"rel",json_object_new_string("canonical"));
     520      json_object_object_add(res2,"type",json_object_new_string("application/json"));
     521      json_object_object_add(res2,"title",json_object_new_string("Process Description"));
     522      map* tmpUrl=getMapFromMaps(m,"main","serverAddress");
     523      char* tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(rUrl)+13)*sizeof(char));
     524      sprintf(tmpStr,"%s/processes/%s/",tmpUrl->value,rUrl);
     525      if(doc==NULL){
     526        json_object_object_add(res2,"title",json_object_new_string("Execute End Point"));
     527        char* tmpStr1=zStrdup(tmpStr);
     528        tmpStr=(char*) realloc(tmpStr,(strlen(tmpStr)+6)*sizeof(char));
     529        sprintf(tmpStr,"%sjobs/",tmpStr1);
     530        free(tmpStr1);
     531      }
     532      json_object_object_add(res2,"href",json_object_new_string(tmpStr));
     533      free(tmpStr);
     534      json_object_array_add(res1,res2);
     535      json_object_object_add(res,"links",res1);
     536    }
     537    if(doc==NULL){
     538      elements* in=serv->inputs;
     539      json_object* inputs=json_object_new_array();
     540      printIOTypeJ(m,"input",in,inputs,serv);
     541      json_object_object_add(res,"inputs",inputs);
     542
     543      in=serv->outputs;
     544      json_object* outputs=json_object_new_array();
     545      printIOTypeJ(m,"output",in,outputs,serv);
     546      json_object_object_add(res,"outputs",outputs);
     547
     548    }
     549    if(strcmp(rUrl,serv->name)!=0)
     550      free(rUrl);
     551    if(doc!=NULL)
     552      json_object_array_add(doc,res);
     553    else
     554      json_object_object_add(nc,"process",json_object_get(res));
     555
     556  }
     557
     558  /**
     559   * Print an OWS ExceptionReport Document and HTTP headers (when required)
     560   * depending on the code.
     561   * Set hasPrinted value to true in the [lenv] section.
     562   *
     563   * @param m the maps containing the settings of the main.cfg file
     564   * @param s the map containing the text,code,locator keys (or a map array of the same keys)
     565   */
     566  void printExceptionReportResponseJ(maps* m,map* s){
     567    if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
     568      return;
     569    int buffersize;
     570    json_object *res=json_object_new_object();
     571
     572    maps* tmpMap=getMaps(m,"main");
     573    const char *exceptionCode;
     574   
     575    map* tmp=getMap(s,"code");
     576    if(tmp!=NULL){
     577      if(strcmp(tmp->value,"OperationNotSupported")==0 ||
     578         strcmp(tmp->value,"NoApplicableCode")==0)
     579        exceptionCode="501 Not Implemented";
     580      else
     581        if(strcmp(tmp->value,"MissingParameterValue")==0 ||
     582           strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
     583           strcmp(tmp->value,"OptionNotSupported")==0 ||
     584           strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
     585           strcmp(tmp->value,"InvalidParameterValue")==0)
     586          exceptionCode="400 Bad request";
     587        else
     588          if(strcmp(tmp->value,"NotFound")==0)
     589            exceptionCode="404 Not Found";
     590          else
     591            exceptionCode="501 Internal Server Error";
     592      json_object_object_add(res,"code",json_object_new_string(tmp->value));
     593    }
     594    else
     595      exceptionCode="501 Internal Server Error";
     596    printHeaders(m);
     597
     598    tmp=getMapFromMaps(m,"lenv","status_code");
     599    if(tmp!=NULL)
     600      exceptionCode=tmp->value;
     601    if(m!=NULL){
     602      map *tmpSid=getMapFromMaps(m,"lenv","sid");
     603      if(tmpSid!=NULL){
     604        if( getpid()==atoi(tmpSid->value) ){
     605          printf("Status: %s\r\n\r\n",exceptionCode);
     606        }
     607      }
     608      else{
     609        printf("Status: %s\r\n\r\n",exceptionCode);
     610      }
     611    }else{
     612      printf("Status: %s\r\n\r\n",exceptionCode);
     613    }
     614    tmp=getMap(s,"text");
     615    if(tmp==NULL)
     616      tmp=getMap(s,"message");
     617    if(tmp==NULL)
     618      tmp=getMapFromMaps(m,"lenv","message");
     619    if(tmp!=NULL)
     620      json_object_object_add(res,"description",json_object_new_string(tmp->value));
     621    const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
     622    printf(jsonStr);
     623    if(m!=NULL)
     624      setMapInMaps(m,"lenv","hasPrinted","true");
     625  }
     626
     627  /**
     628   * Parse LiteralData value
     629   * @param conf the maps containing the settings of the main.cfg file
     630   * @param req json_object pointing to the input/output
     631   * @param element
     632   * @param output the maps to set current json structure
     633   */
     634  void parseJLiteral(maps* conf,json_object* req,elements* element,maps* output){
     635    json_object* json_cinput=NULL;
     636    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
     637      output->content=createMap("value",json_object_get_string(json_cinput));
     638    }
     639    const char* tmpStrs[2]={
     640      "dataType",
     641      "uom"
     642    };
     643    for(int i=0;i<2;i++)
     644      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
     645        json_object* json_cinput1;
     646        if(json_object_object_get_ex(json_cinput,"name",&json_cinput1)!=FALSE){
     647          if(output->content==NULL)
     648            output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
     649          else
     650            addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
     651        }
     652        if(json_object_object_get_ex(json_cinput,"reference",&json_cinput1)!=FALSE){
     653          if(output->content==NULL)
     654            output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
     655          else
     656            addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
     657        }
     658      }
     659    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
     660      if(output->content==NULL)
     661        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
     662      else
     663        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
     664    }
     665  }
     666
     667  /**
     668   * Parse ComplexData 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   * @param name the name of the request from http_requests
     674   */
     675  void parseJComplex(maps* conf,json_object* req,elements* element,maps* output,const char* name){
     676    json_object* json_cinput=NULL;
     677    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
     678      json_object* json_value=NULL;
     679      if(json_object_object_get_ex(json_cinput,"inlineValue",&json_value)!=FALSE)
     680        output->content=createMap("value",json_object_get_string(json_value));
     681      else{
     682        if(json_object_object_get_ex(json_cinput,"href",&json_value)!=FALSE){
     683          output->content=createMap("xlink:href",json_object_get_string(json_value));
     684          int len=0;
     685          int createdStr=0;
     686          char *tmpStr="url";
     687          char *tmpStr1="input";
     688          if(getMaps(conf,"http_requests")==NULL){
     689            maps* tmpMaps=createMaps("http_requests");
     690            tmpMaps->content=createMap("length","1");
     691            addMapsToMaps(&conf,tmpMaps);
     692            freeMaps(&tmpMaps);
     693            free(tmpMaps);
     694          }else{
     695            map* tmpMap=getMapFromMaps(conf,"http_requests","length");
     696            int len=atoi(tmpMap->value);
     697            createdStr=1;
     698            tmpStr=(char*) malloc((12)*sizeof(char));
     699            sprintf(tmpStr,"%d",len+1);
     700            setMapInMaps(conf,"http_requests","length",tmpStr);
     701            sprintf(tmpStr,"url_%d",len);
     702            tmpStr1=(char*) malloc((14)*sizeof(char));
     703            sprintf(tmpStr1,"input_%d",len);
     704          }
     705          setMapInMaps(conf,"http_requests",tmpStr,json_object_get_string(json_value));
     706          setMapInMaps(conf,"http_requests",tmpStr1,name);
     707          if(createdStr>0){
     708            free(tmpStr);
     709            free(tmpStr1);
     710          }
     711        }
     712      }
     713    }
     714    if(json_object_object_get_ex(req,"format",&json_cinput)!=FALSE){
     715      json_object_object_foreach(json_cinput, key, val) {
     716        if(output->content==NULL)
     717          output->content=createMap(key,json_object_get_string(val));
     718        else
     719          addToMap(output->content,key,json_object_get_string(val));
     720       
     721      }
     722    }
     723    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
     724      if(output->content==NULL)
     725        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
     726      else
     727        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
     728    }
     729  }
     730
     731  /**
     732   * Parse BoundingBox value
     733   * @param conf the maps containing the settings of the main.cfg file
     734   * @param req json_object pointing to the input/output
     735   * @param element
     736   * @param output the maps to set current json structure
     737   */
     738  void parseJBoundingBox(maps* conf,json_object* req,elements* element,maps* output){
     739    json_object* json_cinput=NULL;
     740    if(json_object_object_get_ex(req,"bbox",&json_cinput)!=FALSE){
     741      output->content=createMap("value",json_object_get_string(json_cinput));
     742    }
     743    if(json_object_object_get_ex(req,"crs",&json_cinput)!=FALSE){
     744      if(output->content==NULL)
     745        output->content=createMap("crs",json_object_get_string(json_cinput));
     746      else
     747        addToMap(output->content,"crs","http://www.opengis.net/def/crs/OGC/1.3/CRS84");
     748    }
     749    char* tmpStrs[2]={
     750      "lowerCorner",
     751      "upperCorner"
     752    };
     753    for(int i=0;i<2;i++)
     754      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
     755        if(output->content==NULL)
     756          output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput));
     757        else
     758          addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput));
     759      }
     760    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
     761      if(output->content==NULL)
     762        output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
     763      else
     764        addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
     765    }
     766  }
     767
     768  /**
     769   * Parse inputs / outputs
     770   * @param conf the maps containing the settings of the main.cfg file
     771   * @param req json_object pointing to the input/output
     772   * @param ioElements the elements extracted from the zcfg
     773   * @param ioMaps the produced maps containing inputs (or outputs)
     774   * @param ioType the char* set to inputs or outputs
     775   */
     776  void parseJIO(maps* conf, json_object* req, elements* ioElements, maps** ioMaps,const char* ioType){
     777    json_object* json_io=NULL;
     778    if(json_object_object_get_ex(req,ioType,&json_io)!=FALSE){     
     779      json_object* json_current_io=NULL;
     780      size_t len=json_object_array_length(json_io);
     781      for(int i=0;i<len;i++){
     782        maps *cMaps=NULL;
     783        json_current_io=json_object_array_get_idx(json_io,i);
     784        json_object* cname=NULL;
     785        if(json_object_object_get_ex(json_current_io,"id",&cname)!=FALSE){
     786          cMaps=createMaps(json_object_get_string(cname));
     787          elements* cio=getElements(ioElements,json_object_get_string(cname));
     788          json_object* json_input;
     789          json_object* json_cinput;
     790          if(json_object_object_get_ex(json_current_io,"input",&json_input)!=FALSE){
     791            if(json_object_object_get_ex(json_input,"dataType",&json_cinput)!=FALSE){
     792              parseJLiteral(conf,json_input,cio,cMaps);
     793            } else if(json_object_object_get_ex(json_input,"format",&json_cinput)!=FALSE){
     794              parseJComplex(conf,json_input,cio,cMaps,json_object_get_string(cname));
     795            } else if(json_object_object_get_ex(json_input,"bbox",&json_cinput)!=FALSE){
     796              parseJBoundingBox(conf,json_input,cio,cMaps);
     797            }// else error!
     798            else{
     799              if(json_object_object_get_ex(json_input,"value",&json_cinput)!=FALSE){
     800                map* error=createMap("code","BadRequest");
     801                char tmpS[1024];
     802                sprintf(tmpS,_("Missing input for %s"),ioElements->name);
     803                addToMap(error,"message",tmpS);
     804                setMapInMaps(conf,"lenv","status_code","400 Bad Request");
     805                printExceptionReportResponseJ(conf,error);
     806                return;
     807              }else{
     808                if(json_object_get_type(json_cinput)==json_type_string){
     809                  parseJLiteral(conf,json_input,cio,cMaps);
     810                }else if(json_object_get_type(json_cinput)==json_type_object){
     811                  json_object* json_ccinput=NULL;
     812                  if(json_object_object_get_ex(json_cinput,"bbox",&json_ccinput)!=FALSE){
     813                    parseJComplex(conf,json_input,cio,cMaps,json_object_get_string(cname));
     814                  }
     815                  else{
     816                    parseJBoundingBox(conf,json_input,cio,cMaps);
     817                  }
     818                }else{
     819                  if(strcmp(ioType,"input")==0){
     820                    map* error=createMap("code","BadRequest");
     821                    char tmpS1[1024];
     822                    sprintf(tmpS1,_("Issue with input %s"),ioElements->name);
     823                    addToMap(error,"message",tmpS1);
     824                    setMapInMaps(conf,"lenv","status_code","400 Bad Request");
     825                    printExceptionReportResponseJ(conf,error);
     826                    return;
     827                  }
     828                }
     829              }
     830            }
     831          }else{
     832            if(strcmp(ioType,"input")==0){
     833              map* error=createMap("code","BadRequest");
     834              char tmpS1[1024];
     835              sprintf(tmpS1,_("Missing input for %s"),ioElements->name);
     836              addToMap(error,"message",tmpS1);
     837              setMapInMaps(conf,"lenv","status_code","400 Bad Request");
     838              printExceptionReportResponseJ(conf,error);
     839              return;
     840            }else{
     841              // Outputs
     842              if(json_object_object_get_ex(json_current_io,"transmissionMode",&json_cinput)!=FALSE){
     843                if(cMaps->content==NULL)
     844                  cMaps->content=createMap("transmissionMode",json_object_get_string(json_cinput));
     845                else
     846                  addToMap(cMaps->content,"transmissionMode",json_object_get_string(json_cinput));
     847              }
     848              if(json_object_object_get_ex(json_current_io,"format",&json_cinput)!=FALSE){
     849                json_object_object_foreach(json_cinput, key, val) {
     850                  if(cMaps->content==NULL)
     851                    cMaps->content=createMap(key,json_object_get_string(val));
     852                  else
     853                    addToMap(cMaps->content,key,json_object_get_string(val));
     854                }
     855              }       
     856            }
     857          }
     858        }
     859        addToMap(cMaps->content,"inRequest","true");
     860        if (ioMaps == NULL)
     861          *ioMaps = dupMaps(&cMaps);
     862        else
     863          addMapsToMaps (ioMaps, cMaps);
     864      }
     865    }
     866  }
     867   
     868     
     869 
     870  /**
     871   * Parse Json Request
     872   * @param conf the maps containing the settings of the main.cfg file
     873   * @param s the current service metadata
     874   * @param req the JSON object of the request body
     875   * @param inputs the produced maps
     876   * @param outputs the produced maps
     877   */
     878  void parseJRequest(maps* conf, service* s,json_object* req,maps** inputs,maps** outputs){
     879    elements* io=s->inputs;
     880
     881    json_object* json_io=NULL;
     882    int parsed=0;
     883    char* tmpS="input";
     884    maps* in=*inputs;
     885    parseJIO(conf,req,s->inputs,inputs,"inputs");
     886
     887    if(parsed==0){
     888      json_io=NULL;
     889      if(json_object_object_get_ex(req,"outputs",&json_io)!=FALSE){
     890        parseJIO(conf,req,s->outputs,outputs,"outputs");
     891      }
     892    }     
     893  }
     894
     895  /**
     896   * Print the jobs list
     897   *
     898   * @param conf the maps containing the settings of the main.cfg file
     899   * @return the JSON object pointer to the jobs list
     900   */
     901  json_object* printJobList(maps* conf){
     902    json_object* res=json_object_new_array();
     903    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
     904    map* oIdentifier=getMapFromMaps(conf,"lenv","oIdentifier");
     905    char* cpath=(char*)malloc((strlen(tmpPath->value)+strlen(oIdentifier->value)+14)*sizeof(char));
     906    sprintf(cpath,"%s/statusInfos/%s",tmpPath->value,oIdentifier->value);
     907    struct dirent *dp;
     908    DIR *dirp = opendir (cpath);
     909    if(dirp!=NULL){
     910      while ((dp = readdir (dirp)) != NULL){
     911        char* extn = strstr(dp->d_name, ".json");
     912        if(extn!=NULL){
     913          json_object* cjob=json_object_new_object();
     914          char* tmpStr=zStrdup(dp->d_name);
     915          tmpStr[strlen(dp->d_name)-5]=0;
     916          json_object_object_add(cjob,"id",json_object_new_string(tmpStr));
     917          char *tmps1=(char*)malloc((strlen(cpath)+strlen(dp->d_name)+2)*sizeof(char));
     918          sprintf (tmps1, "%s/%s", cpath, dp->d_name);
     919          FILE* cdat=fopen(tmps1,"rb");
     920          if(cdat!=NULL){
     921            zStatStruct f_status;
     922            int s=zStat(tmps1, &f_status);
     923            char* mystring=(char*)malloc((f_status.st_size+1)*sizeof(char));
     924            fread(mystring,1,f_status.st_size,cdat);
     925            mystring[f_status.st_size]=0;           
     926            json_object *jobj = NULL;
     927            int slen = 0;
     928            enum json_tokener_error jerr;
     929            struct json_tokener* tok=json_tokener_new();
     930            do {
     931              slen = strlen(mystring);
     932              jobj = json_tokener_parse_ex(tok, mystring, slen);
     933            } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
     934            if (jerr != json_tokener_success) {
     935              fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
     936              return res;
     937            }
     938            if (tok->char_offset < slen){
     939              return res;
     940            }
     941            json_object_object_add(cjob,"infos",jobj);
     942            free(mystring);
     943            fclose(cdat);
     944          }
     945          free(tmpStr);
     946          json_object_array_add(res,cjob);
     947        }
     948      }
     949      closedir (dirp);
     950    }
     951    return res;
     952  }
     953
     954  /**
     955   * Print the result of an execution
     956   *
     957   * @param conf the maps containing the settings of the main.cfg file
     958   * @param s service pointer to metadata
     959   * @param result outputs of the service
     960   * @param res the status of executino SERVICE_FAILED/SERVICE_SUCCEEDED
     961   * @return the JSON object pointer to the result
     962   */
     963  json_object* printJResult(maps* conf,service* s,maps* result,int res){
     964    printHeaders(conf);
     965    json_object* eres1=json_object_new_object();
     966    json_object* eres=json_object_new_array();
     967    maps* resu=result;
     968    int itn=0;
     969    while(resu!=NULL){
     970      json_object* res1=json_object_new_object();
     971      json_object_object_add(res1,"id",json_object_new_string(resu->name));
     972      map* tmpMap=NULL;
     973      if((tmpMap=getMap(resu->content,"value"))!=NULL ||
     974         (getMap(resu->content,"generated_file"))!=NULL){
     975        json_object* res2=json_object_new_object();
     976        map* tmpMap1=NULL;
     977        if((tmpMap1=getMap(resu->content,"transmissionMode"))!=NULL) {
     978          if(strcmp(tmpMap1->value,"value")==0) {
     979            map* tmpMap2=getMap(resu->content,"mimeType");
     980            if(tmpMap2!=NULL && strstr(tmpMap2->value,"json")!=NULL){
     981              json_object *jobj = NULL;
     982              int slen = 0;
     983              enum json_tokener_error jerr;
     984              struct json_tokener* tok=json_tokener_new();
     985              do {
     986                slen = strlen(tmpMap->value);
     987                jobj = json_tokener_parse_ex(tok, tmpMap->value, slen);
     988              } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
     989              if (jerr != json_tokener_success) {
     990                fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
     991                return eres1;
     992              }
     993              if (tok->char_offset < slen){
     994                return eres1;           
     995              }
     996              json_object_object_add(res2,"inlineValue",jobj);
     997            }else
     998              json_object_object_add(res2,"inlineValue",json_object_new_string(tmpMap->value));
     999          }
     1000          else{
     1001            // Create file for reference data if not existing
     1002            map *gfile=getMap(resu->content,"generated_file");
     1003            char *file_name=NULL;
     1004            char *file_path=NULL;
     1005            char *file_url=NULL;
     1006            map *tmp1=getMapFromMaps(conf,"main","tmpPath");
     1007            if(gfile!=NULL){
     1008              gfile=getMap(resu->content,"expected_generated_file");
     1009              if(gfile==NULL){
     1010                gfile=getMap(resu->content,"generated_file");
     1011              }
     1012              if(strstr(gfile->value,tmp1->value)!=NULL)
     1013                file_name=zStrdup(strstr(gfile->value,tmp1->value)+strlen(tmp1->value));
     1014            }/*else*/
     1015            {
     1016              // Create file for reference data
     1017              map *tmpUrl=getMapFromMaps(conf,"main","tmpUrl");
     1018              map *usid=getMapFromMaps(conf,"lenv","usid");
     1019              map *ext=getMap(resu->content,"extension");
     1020              if(gfile==NULL){
     1021                char file_ext[32];         
     1022                if( ext != NULL && ext->value != NULL) {
     1023                  strncpy(file_ext, ext->value, 32);
     1024                }
     1025                else {
     1026                  // Obtain default file extension (see mimetypes.h).         
     1027                  // If the MIME type is not recognized, txt is used as the default extension
     1028                  map* mtype=getMap(resu->content,"mimeType");
     1029                  getFileExtension(mtype != NULL ? mtype->value : NULL, file_ext, 32);
     1030                }
     1031                if(file_name!=NULL)
     1032                  free(file_name);
     1033             
     1034                file_name=(char*)malloc((strlen(s->name)+strlen(usid->value)+strlen(file_ext)+strlen(resu->name)+45)*sizeof(char));
     1035                sprintf(file_name,"ZOO_DATA_%s_%s_%s_%d.%s",s->name,resu->name,usid->value,itn,file_ext);
     1036
     1037                file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
     1038                sprintf(file_path,"%s/%s",tmp1->value,file_name);
     1039              }else{
     1040                file_path=(char*)malloc((strlen(gfile->value)+1)*sizeof(char));
     1041                sprintf(file_path,"%s",gfile->value);
     1042              }
     1043               
     1044             
     1045              itn++;
     1046             
     1047              file_url=(char*)malloc((strlen(tmpUrl->value)+
     1048                                      strlen(file_name)+2)*sizeof(char));
     1049              sprintf(file_url,"%s/%s",tmpUrl->value,file_name);
     1050
     1051              if(gfile==NULL){
     1052                FILE *ofile=fopen(file_path,"wb");
     1053                if(ofile==NULL){
     1054                  char tmpMsg[1024];
     1055                  sprintf(tmpMsg,
     1056                          _("Unable to create the file \"%s\" for storing the %s final result."),
     1057                          file_name,resu->name);
     1058                  map* error=createMap("code","InternalError");
     1059                  addToMap(error,"message",tmpMsg);
     1060                  printExceptionReportResponseJ(conf,error);
     1061                  free(file_name);
     1062                  free(file_path);
     1063                  return NULL;
     1064                }
     1065
     1066                map* toto=getMap(resu->content,"value");
     1067                if(toto==NULL){
     1068                  char tmpMsg[1024];
     1069                  sprintf(tmpMsg,
     1070                          _("No value found for the requested output %s."),
     1071                          resu->name);
     1072                  map* error=createMap("code","InternalError");
     1073                  addToMap(error,"message",tmpMsg);
     1074                  printExceptionReportResponseJ(conf,error);
     1075                  fclose(ofile);
     1076                  free(file_name);
     1077                  free(file_path);
     1078                  return NULL;
     1079                }
     1080                map* size=getMap(resu->content,"size");
     1081                if(size!=NULL && toto!=NULL)
     1082                  fwrite(toto->value,1,(atoi(size->value))*sizeof(char),ofile);
     1083                else
     1084                  if(toto!=NULL && toto->value!=NULL)
     1085                    fwrite(toto->value,1,
     1086                           strlen(toto->value)*sizeof(char),ofile);
     1087                fclose(ofile);
     1088              }
     1089              json_object_object_add(res2,"href",
     1090                                     json_object_new_string(file_url));
     1091              free(file_url);
     1092              free(file_name);
     1093              free(file_path);
     1094             
     1095            }
     1096           
     1097          }
     1098        }
     1099        json_object_object_add(res1,"value",res2);     
     1100        json_object_array_add(eres,res1);
     1101      }
     1102      resu=resu->next;
     1103    }
     1104    json_object_object_add(eres1,"outputs",eres);
     1105    const char* jsonStr =
     1106      json_object_to_json_string_ext(eres1,JSON_C_TO_STRING_PLAIN);
     1107    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
     1108    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
     1109    map *sessId = getMapFromMaps (conf, "lenv", "usid");
     1110    char tmp[1024];
     1111    sprintf(tmp,"%s/%s_%s.json",
     1112            tmpPath->value,cIdentifier->value,sessId->value);
     1113    FILE* foutput=fopen(tmp,"w+");
     1114    if(foutput!=NULL){
     1115      fclose(foutput);
     1116      char tmpUrl[1024];
     1117      map* tmpPath1 = getMapFromMaps (conf, "main", "tmpUrl");
     1118      sprintf(tmpUrl,"%s/%s_%s.json",tmpPath1->value,
     1119              cIdentifier->value,sessId->value);
     1120      setMapInMaps(conf,"headers","Location",tmpUrl);
     1121    }
     1122    if(res==3){
     1123      setMapInMaps(conf,"headers","Status","201 Created");
     1124    }
     1125    else{
     1126      setMapInMaps(conf,"headers","Status","500 Issue running your service");
     1127    }
     1128
     1129    return eres1;
     1130  }
     1131
     1132
     1133  /**
     1134   * Create the status links
     1135   *
     1136   * @param conf the maps containing the settings of the main.cfg file
     1137   * @param result an integer (>0 for adding the /result link)
     1138   * @param obj the JSON object pointer to add the links to
     1139   * @return 0
     1140   */
     1141  int createStatusLinks(maps* conf,int result,json_object* obj){
     1142    json_object* res=json_object_new_array();
     1143    map *tmpPath = getMapFromMaps (conf, "main", "serverAddress");
     1144    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
     1145    map *sessId = getMapFromMaps (conf, "lenv", "usid");
     1146    char *Url0=(char*) malloc((strlen(tmpPath->value)+
     1147                               strlen(cIdentifier->value)+
     1148                               strlen(sessId->value)+18)*sizeof(char));
     1149    int needResult=-1;
     1150    char *message, *status;
     1151    sprintf(Url0,"%s/processes/%s/jobs/%s",
     1152            tmpPath->value,
     1153            cIdentifier->value,
     1154            sessId->value);
     1155    setMapInMaps(conf,"headers","Location",Url0);
     1156    json_object* val=json_object_new_object();
     1157    json_object_object_add(val,"Title",
     1158                           json_object_new_string(_("Status location")));
     1159    json_object_object_add(val,"href",json_object_new_string(Url0));
     1160    json_object_array_add(res,val);
     1161    if(result>0){
     1162      free(Url0);
     1163      Url0=(char*) malloc((strlen(tmpPath->value)+
     1164                           strlen(cIdentifier->value)+strlen(sessId->value)+
     1165                           25)*sizeof(char));
     1166      sprintf(Url0,"%s/processes/%s/jobs/%s/result",
     1167              tmpPath->value,
     1168              cIdentifier->value,
     1169              sessId->value);
     1170      json_object* val1=json_object_new_object();
     1171      json_object_object_add(val1,"Title",
     1172                             json_object_new_string(_("Result location")));
     1173      json_object_object_add(val1,"href",json_object_new_string(Url0));
     1174      json_object_array_add(res,val1);
     1175    }
     1176    json_object_object_add(obj,"links",res);
     1177    free(Url0);
     1178    return 0;
     1179  }
     1180
     1181  /**
     1182   * Get the status file path
     1183   *
     1184   * @param conf the maps containing the settings of the main.cfg file
     1185   * @return a char* containing the full status file path
     1186   */
     1187  char* json_getStatusFilePath(maps* conf){
     1188    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
     1189    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
     1190    map *sessId = getMapFromMaps (conf, "lenv", "usid");
     1191    if(sessId!=NULL){
     1192      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
     1193      if(sessId==NULL)
     1194        sessId = getMapFromMaps (conf, "lenv", "usid");
     1195    }else
     1196      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
     1197    char *tmp1=(char*) malloc((strlen(tmpPath->value)+
     1198                               strlen(cIdentifier->value)+14)*sizeof(char));
     1199    sprintf(tmp1,"%s/statusInfos/%s",
     1200            tmpPath->value,
     1201            cIdentifier->value);
     1202    if(mkdir(tmp1,0777) != 0 && errno != EEXIST){
     1203      fprintf(stderr,"Issue creating directory %s\n",tmp1);
     1204      return NULL;
     1205    }
     1206    free(tmp1);
     1207    tmp1=(char*) malloc((strlen(tmpPath->value)+
     1208                         strlen(cIdentifier->value)+
     1209                         strlen(sessId->value)+20)*sizeof(char));
     1210    int needResult=0;
     1211    char *message, *rstatus;
     1212    sprintf(tmp1,"%s/statusInfos/%s/%s.json",
     1213            tmpPath->value,
     1214            cIdentifier->value,
     1215            sessId->value);
     1216   
     1217    return tmp1;
     1218  }
     1219 
     1220  /**
     1221   * Create the status file
     1222   *
     1223   * @param conf the maps containing the settings of the main.cfg file
     1224   * @param status an integer (SERVICE_ACCEPTED,SERVICE_STARTED...)
     1225   * @return an integer (0 in case of success, 1 in case of failure)
     1226   */
     1227  int createStatusFile(maps* conf,int status){
     1228    int needResult=0;
     1229    const char *message, *rstatus;
     1230    char* tmp1=json_getStatusFilePath(conf);
     1231    // Create statusInfo JSON object
     1232    // cf. https://github.com/opengeospatial/wps-rest-binding/blob/master/core/
     1233    //     openapi/schemas/statusInfo.yaml
     1234    json_object* res=json_object_new_object();
     1235    json_object_object_add(res,"status",json_object_new_string("successful"));
     1236    switch(status){
     1237    case SERVICE_ACCEPTED:
     1238      {
     1239        message=_("ZOO-Kernel accepted to run your service!");
     1240        rstatus="accepted";
     1241        break;
     1242      }
     1243    case SERVICE_STARTED:
     1244      {
     1245        message=_("ZOO-Kernel is currently running your service!");
     1246        rstatus="running";
     1247        break;
     1248      }
     1249    case SERVICE_PAUSED:
     1250      {
     1251        message=_("ZOO-Kernel pause your service!");
     1252        rstatus="paused";
     1253        break;
     1254      }
     1255    case SERVICE_SUCCEEDED:
     1256      {
     1257        message=_("ZOO-Kernel successfully run your service!");
     1258        rstatus="successful";
     1259        needResult=1;
     1260        break;
     1261      }
     1262    default:
     1263      {
     1264        message=_("ZOO-Kernel failed to run your service!");
     1265        rstatus="failed";
     1266        break;
     1267      }
     1268    }
     1269    setMapInMaps(conf,"lenv","message",message);
     1270    setMapInMaps(conf,"lenv","status",rstatus);
     1271       
     1272    map* mess=getMapFromMaps(conf,"lenv","message");
     1273    if(mess!=NULL)
     1274      json_object_object_add(res,"message",json_object_new_string(mess->value));
     1275
     1276    createStatusLinks(conf,needResult,res);
     1277   
     1278    FILE* foutput1=fopen(tmp1,"w+");
     1279    if(foutput1!=NULL){
     1280      const char* jsonStr1=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
     1281      fprintf(foutput1,"%s",jsonStr1);
     1282      fclose(foutput1);
     1283    }else{
     1284      // Failure
     1285      setMapInMaps(conf,"lenv","message",_("Unable to store the statusInfo!"));
     1286      free(tmp1);
     1287      return 1;
     1288    }
     1289    free(tmp1);
     1290    return 0;
     1291  }
     1292
     1293  /**
     1294   * Create the status file
     1295   *
     1296   * @param conf the maps containing the settings of the main.cfg file
     1297   * @return an integer (0 in case of success, 1 in case of failure)
     1298   */
     1299  int json_getStatusFile(maps* conf){
     1300    char* tmp1=json_getStatusFilePath(conf);
     1301    FILE* statusFile=fopen(tmp1,"rb");
     1302
     1303    map* tmpMap=getMapFromMaps(conf,"lenv","gs_usid");
     1304    if(tmpMap!=NULL){
     1305        char* tmpStr=_getStatus(conf,tmpMap->value);
     1306        if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
     1307          char *tmpStr1=zStrdup(tmpStr);
     1308          char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
     1309          free(tmpStr);
     1310          tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
     1311          setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
     1312          setMapInMaps(conf,"lenv","gs_message",tmpStr0);
     1313          free(tmpStr0);
     1314          free(tmpStr1);
     1315        }
     1316      }
     1317  }
     1318
     1319  /**
     1320   * Produce the JSON object for api info object
     1321   *
     1322   * @param conf the maps containing the settings of the main.cfg file
     1323   * @param res the JSON object for the api info
     1324   */
     1325  void produceApiInfo(maps* conf,json_object* res,json_object* res5){
     1326    json_object *res1=json_object_new_object();
     1327    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
     1328    if(tmpMap!=NULL){
     1329      json_object *res2=json_object_new_object();
     1330      json_object_object_add(res2,"name",json_object_new_string(tmpMap->value));
     1331      tmpMap=getMapFromMaps(conf,"provider","addressElectronicMailAddress");
     1332      if(tmpMap!=NULL)
     1333        json_object_object_add(res2,"email",json_object_new_string(tmpMap->value));
     1334      tmpMap=getMapFromMaps(conf,"provider","providerSite");
     1335      if(tmpMap!=NULL)
     1336        json_object_object_add(res2,"url",json_object_new_string(tmpMap->value));
     1337      json_object_object_add(res1,"contact",res2);
     1338    }
     1339    tmpMap=getMapFromMaps(conf,"identification","abstract");
     1340    if(tmpMap!=NULL){
     1341      json_object_object_add(res1,"description",json_object_new_string(tmpMap->value));
     1342      json_object_object_add(res5,"description",json_object_new_string(tmpMap->value));
     1343      tmpMap=getMapFromMaps(conf,"main","serverAddress");
     1344      json_object_object_add(res5,"url",json_object_new_string(tmpMap->value));
     1345    }
     1346    tmpMap=getMapFromMaps(conf,"identification","title");
     1347    if(tmpMap!=NULL)
     1348      json_object_object_add(res1,"title",json_object_new_string(tmpMap->value));
     1349    json_object_object_add(res1,"version",json_object_new_string(ZOO_VERSION));
     1350    tmpMap=getMapFromMaps(conf,"identification","keywords");
     1351    if(tmpMap!=NULL){
     1352      char *saveptr;
     1353      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
     1354      json_object *res3=json_object_new_array();
     1355      while (tmps != NULL){
     1356        json_object_array_add(res3,json_object_new_string(tmps));
     1357        tmps = strtok_r (NULL, ",", &saveptr);
     1358      }
     1359      json_object_object_add(res1,"x-keywords",res3);
     1360    }
     1361    maps* tmpMaps=getMaps(conf,"provider");
     1362    if(tmpMaps!=NULL){
     1363      json_object *res4=json_object_new_object();
     1364      map* cItem=tmpMaps->content;
     1365      while(cItem!=NULL){
     1366        json_object_object_add(res4,cItem->name,json_object_new_string(cItem->value));
     1367        cItem=cItem->next;
     1368      }
     1369      json_object_object_add(res1,"x-ows-servicecontact",res4);
     1370    }
     1371
     1372    json_object *res4=json_object_new_object();
     1373    tmpMap=getMapFromMaps(conf,"main","license_name");
     1374    if(tmpMap!=NULL){
     1375      json_object_object_add(res4,"name",json_object_new_string(tmpMap->value));
     1376      tmpMap=getMapFromMaps(conf,"main","license_url");
     1377      if(tmpMap!=NULL){
     1378        json_object_object_add(res4,"url",json_object_new_string(tmpMap->value));     
     1379      }
     1380    }
     1381    json_object_object_add(res1,"license",res4);
     1382
     1383    json_object_object_add(res,"info",res1);   
     1384  }
     1385
     1386  /**
     1387   * Produce the JSON object for api parameter
     1388   *
     1389   * @param conf the maps containing the settings of the main.cfg file
     1390   * @param res the JSON object to populate with the parameters
     1391   */
     1392  void produceApiParameters(maps* conf,json_object* res){
     1393    json_object *res9=json_object_new_object();
     1394    maps* tmpMaps1=getMaps(conf,"{id}");
     1395    map* tmpMap2=getMapFromMaps(conf,"openapi","parameters");
     1396    char *saveptr12;
     1397    char *tmps12 = strtok_r (tmpMap2->value, ",", &saveptr12);
     1398    while(tmps12!=NULL){
     1399      char* tmpId=(char*) malloc((strlen(tmps12)+3)*sizeof(char));
     1400      sprintf(tmpId,"{%s}",tmps12);
     1401      tmpMaps1=getMaps(conf,tmpId);
     1402      json_object *res8=json_object_new_object();
     1403      if(tmpMaps1!=NULL){
     1404        map* tmpMap=getMap(tmpMaps1->content,"title");
     1405        if(tmpMap!=NULL)
     1406          json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
     1407        tmpMap=getMap(tmpMaps1->content,"abstract");
     1408        if(tmpMap!=NULL)
     1409          json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
     1410        tmpMap=getMap(tmpMaps1->content,"example");
     1411        if(tmpMap!=NULL)
     1412          json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
     1413        tmpMap=getMap(tmpMaps1->content,"required");
     1414        if(tmpMap!=NULL){
     1415          if(strcmp(tmpMap->value,"true")==0)
     1416            json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
     1417          else
     1418            json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
     1419        }
     1420        else
     1421          json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
     1422        json_object_object_add(res8,"in",json_object_new_string("path"));
     1423        json_object_object_add(res8,"name",json_object_new_string(tmps12));
     1424        json_object *res6=json_object_new_object();
     1425        json_object *res7=json_object_new_object();
     1426        tmpMap=getMap(tmpMaps1->content,"type");
     1427        if(tmpMap!=NULL)
     1428          json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
     1429        else
     1430          json_object_object_add(res6,"type",json_object_new_string("string"));
     1431       
     1432        json_object_object_add(res8,"schema",res6);
     1433       
     1434      }
     1435       
     1436      json_object_object_add(res9,tmps12,res8);
     1437      tmps12 = strtok_r (NULL, ",", &saveptr12);
     1438    }   
     1439    tmpMap2=getMapFromMaps(conf,"openapi","header_parameters");
     1440    char *saveptr13;
     1441    char *tmps13 = strtok_r (tmpMap2->value, ",", &saveptr13);
     1442    while(tmps13!=NULL){
     1443      char* tmpId=zStrdup(tmps13);
     1444      maps *tmpMaps2=getMaps(conf,tmpId);
     1445      json_object *res8=json_object_new_object();
     1446      if(tmpMaps2!=NULL){
     1447        map* tmpMap=getMap(tmpMaps2->content,"title");
     1448        if(tmpMap!=NULL)
     1449          json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
     1450        tmpMap=getMap(tmpMaps2->content,"abstract");
     1451        if(tmpMap!=NULL)
     1452          json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
     1453        tmpMap=getMap(tmpMaps2->content,"example");
     1454        if(tmpMap!=NULL)
     1455          json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
     1456        tmpMap=getMap(tmpMaps2->content,"required");
     1457        if(tmpMap!=NULL){
     1458          if(strcmp(tmpMap->value,"true")==0)
     1459            json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
     1460          else
     1461            json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
     1462        }
     1463        else
     1464          json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
     1465        json_object_object_add(res8,"in",json_object_new_string("header"));
     1466        tmpMap=getMap(tmpMaps2->content,"name");
     1467        if(tmpMap!=NULL)
     1468          json_object_object_add(res8,"name",json_object_new_string(tmpMap->value));
     1469        json_object *res6=json_object_new_object();
     1470        json_object *res7=json_object_new_object();
     1471        tmpMap=getMap(tmpMaps2->content,"type");
     1472        if(tmpMap!=NULL)
     1473          json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
     1474        else
     1475          json_object_object_add(res6,"type",json_object_new_string("string"));
     1476
     1477        {
     1478          tmpMap=getMap(tmpMaps2->content,"enum");
     1479          if(tmpMap!=NULL){
     1480            char *saveptr11;
     1481            char *tmps11 = strtok_r (tmpMap->value, ",", &saveptr11);
     1482            json_object *res71=json_object_new_array();
     1483            while(tmps11!=NULL){               
     1484              json_object_array_add(res71,json_object_new_string(tmps11));
     1485              tmps11 = strtok_r (NULL, ",", &saveptr11);
     1486            }
     1487            json_object_object_add(res6,"enum",res71);                           
     1488          }
     1489        }
     1490       
     1491        json_object_object_add(res8,"schema",res6);
     1492       
     1493      }
     1494       
     1495      json_object_object_add(res9,tmpId,res8);
     1496      tmps13 = strtok_r (NULL, ",", &saveptr13);
     1497    }
     1498    json_object_object_add(res,"parameters",res9);   
     1499  }
     1500
     1501  void produceApiComponents(maps*conf,json_object* res){
     1502    json_object* res1=json_object_new_object();
     1503    produceApiParameters(conf,res1);
     1504    json_object_object_add(res,"components",res1);
     1505  }
     1506
     1507  /**
     1508   * Produce the JSON object for /api
     1509   *
     1510   * @param conf the maps containing the settings of the main.cfg file
     1511   * @param res the JSON object to populate
     1512   */
     1513  void produceApi(maps* conf,json_object* res){
     1514    json_object *res9=json_object_new_object();
     1515    json_object *res10=json_object_new_object();
     1516    maps* tmpMaps1=getMaps(conf,"{id}");
     1517
     1518    produceApiComponents(conf,res);
     1519    json_object *res4=json_object_new_object();
     1520    setMapInMaps(conf,"headers","Content-Type","application/openapi+json; version=3.0;charset=UTF-8");
     1521
     1522    produceApiInfo(conf,res,res4);
     1523    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
     1524
     1525    tmpMap=getMapFromMaps(conf,"openapi","version");
     1526    if(tmpMap!=NULL)
     1527      json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
     1528    else
     1529      json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
     1530
     1531    tmpMap=getMapFromMaps(conf,"openapi","paths");
     1532    if(tmpMap!=NULL){
     1533      json_object *res5=json_object_new_object();
     1534      char *saveptr;
     1535      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
     1536      int cnt=0;
     1537      maps* tmpMaps;
     1538      json_object *paths=json_object_new_object();
     1539      while (tmps != NULL){
     1540        tmpMaps=getMaps(conf,tmps+1);
     1541        json_object *method=json_object_new_object();
     1542        if(tmpMaps!=NULL){
     1543          if(getMap(tmpMaps->content,"length")==NULL)
     1544            addToMap(tmpMaps->content,"length","1");
     1545          map* len=getMap(tmpMaps->content,"length");
     1546           
     1547          for(int i=0;i<atoi(len->value);i++){
     1548            json_object *methodc=json_object_new_object();
     1549            map* cMap=getMapArray(tmpMaps->content,"method",i);
     1550            map* vMap=getMapArray(tmpMaps->content,"title",i);
     1551            if(vMap!=NULL)
     1552              json_object_object_add(methodc,"summary",json_object_new_string(vMap->value));
     1553            vMap=getMapArray(tmpMaps->content,"abstract",i);
     1554            if(vMap!=NULL)
     1555              json_object_object_add(methodc,"description",json_object_new_string(vMap->value));
     1556            vMap=getMapArray(tmpMaps->content,"tags",i);
     1557            if(vMap!=NULL){
     1558              json_object *cc=json_object_new_array();
     1559              json_object_array_add(cc,json_object_new_string(vMap->value));
     1560              json_object_object_add(methodc,"tags",cc);
     1561            }
     1562            json_object *responses=json_object_new_object();
     1563            json_object *cc3=json_object_new_object();
     1564            vMap=getMapArray(tmpMaps->content,"schema",i);
     1565            if(vMap!=NULL){
     1566              json_object *cc=json_object_new_object();
     1567              json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
     1568              json_object *cc0=json_object_new_object();
     1569              json_object_object_add(cc0,"schema",cc);
     1570              json_object *cc1=json_object_new_object();
     1571              map* tmpMap3=getMapFromMaps(conf,tmps,"type");
     1572              if(tmpMap3!=NULL)
     1573                json_object_object_add(cc1,tmpMap3->value,cc0);
     1574              else
     1575                json_object_object_add(cc1,"application/json",cc0);
     1576              json_object *cc2=json_object_new_object();
     1577              json_object_object_add(cc2,"content",cc1);
     1578              json_object_object_add(cc2,"description",json_object_new_string("successful operation"));
     1579              if(i==1)
     1580                json_object_object_add(cc3,"201",cc2);
     1581              else
     1582                json_object_object_add(cc3,"200",cc2);
     1583            }else{
     1584              json_object *cc1=json_object_new_object();
     1585              map* tmpMap3=getMapFromMaps(conf,tmps,"type");
     1586              if(tmpMap3!=NULL)
     1587                json_object_object_add(cc1,tmpMap3->value,json_object_new_object());
     1588              else
     1589                json_object_object_add(cc1,"application/json",json_object_new_object());
     1590              json_object *cc2=json_object_new_object();
     1591              json_object_object_add(cc2,"content",cc1);
     1592              json_object_object_add(cc2,"description",json_object_new_string("successful operation"));
     1593              if(i==1)
     1594                json_object_object_add(cc3,"201",cc2);
     1595              else
     1596                json_object_object_add(cc3,"200",cc2);
     1597            }
     1598            if(strstr(tmps,"{id}")!=NULL){
     1599              vMap=getMapFromMaps(conf,"exception","schema");
     1600              json_object *cc=json_object_new_object();
     1601              json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
     1602              json_object *cc01=json_object_new_array();
     1603              json_object_array_add(cc01,cc);
     1604
     1605              json_object *cc0=json_object_new_object();
     1606              json_object_object_add(cc0,"schema",cc);
     1607              json_object *cc1=json_object_new_object();
     1608              map* tmpMap3=getMapFromMaps(conf,"exception","type");
     1609              if(tmpMap3!=NULL)
     1610                json_object_object_add(cc1,tmpMap3->value,cc0);
     1611              else
     1612                json_object_object_add(cc1,"application/json",cc0);
     1613
     1614              json_object *cc2=json_object_new_object();
     1615              json_object_object_add(cc2,"content",cc1);
     1616              if(strstr(tmps,"{jobID}")==NULL)
     1617                json_object_object_add(cc2,"description",json_object_new_string("The process with id {id} does not exist."));
     1618              else
     1619                json_object_object_add(cc2,"description",json_object_new_string("The process with id {id} or job with id {jobID} does not exist."));
     1620              json_object_object_add(cc3,"404",cc2);
     1621              json_object_object_add(cc3,"default",cc2);
     1622            }
     1623            json_object_object_add(methodc,"responses",cc3);
     1624            vMap=getMapArray(tmpMaps->content,"parameters",i);
     1625            if(vMap!=NULL){
     1626              char *saveptr0;
     1627              char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
     1628              json_object *cc2=json_object_new_array();
     1629              int cnt=0;
     1630              while(tmps1!=NULL){
     1631                char* tmpStr=(char*)malloc((strlen(tmps1)+2)*sizeof(char));
     1632                sprintf(tmpStr,"#%s",tmps1);
     1633                json_object *cc1=json_object_new_object();
     1634                json_object_object_add(cc1,"$ref",json_object_new_string(tmpStr));
     1635                json_object_array_add(cc2,cc1);
     1636                free(tmpStr);
     1637                cnt++;
     1638                tmps1 = strtok_r (NULL, ",", &saveptr0);
     1639              }
     1640              json_object_object_add(methodc,"parameters",cc2);
     1641            }
     1642            if(i==1){
     1643              maps* tmpMaps1=getMaps(conf,"requestBody");
     1644              if(tmpMaps1!=NULL){
     1645                vMap=getMap(tmpMaps1->content,"schema");
     1646                if(vMap!=NULL){
     1647                  json_object *cc=json_object_new_object();
     1648                  json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
     1649                  json_object *cc0=json_object_new_object();
     1650                  json_object_object_add(cc0,"schema",cc);
     1651                  json_object *cc1=json_object_new_object();
     1652                  map* tmpMap3=getMap(tmpMaps->content,"type");
     1653                  if(tmpMap3!=NULL)
     1654                    json_object_object_add(cc1,tmpMap3->value,cc0);
     1655                  else
     1656                    json_object_object_add(cc1,"application/json",cc0);
     1657                  json_object *cc2=json_object_new_object();
     1658                  json_object_object_add(cc2,"content",cc1);
     1659                  vMap=getMap(tmpMaps1->content,"abstract");
     1660                  if(vMap!=NULL)
     1661                    json_object_object_add(cc2,"description",json_object_new_string(vMap->value));
     1662                  json_object_object_add(cc2,"required",json_object_new_boolean(true));
     1663                  json_object_object_add(methodc,"requestBody",cc2);
     1664
     1665                }
     1666              }
     1667            }
     1668            map* mMap=getMapArray(tmpMaps->content,"method",i);
     1669            if(mMap!=NULL)
     1670              json_object_object_add(method,mMap->value,methodc);
     1671            else
     1672              json_object_object_add(method,"get",methodc);
     1673
     1674          }
     1675
     1676          tmpMap=getMapFromMaps(conf,"openapi","version");
     1677          if(tmpMap!=NULL)
     1678            json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
     1679          else
     1680            json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
     1681          if(strstr(tmps,"/root")!=NULL)
     1682            json_object_object_add(paths,"/",method);
     1683          else
     1684            json_object_object_add(paths,tmps,method);
     1685        }
     1686        tmps = strtok_r (NULL, ",", &saveptr);
     1687        cnt++;
     1688      }
     1689      json_object_object_add(res,"paths",paths);
     1690    }
     1691     
     1692    tmpMap=getMapFromMaps(conf,"openapi","links");
     1693    if(tmpMap!=NULL){
     1694       
     1695    }
     1696   
     1697    json_object *res3=json_object_new_array();
     1698    json_object_array_add(res3,res4);
     1699    json_object_object_add(res,"servers",res3);
     1700  }
    1401701 
    1411702#ifdef __cplusplus
Note: See TracChangeset for help on using the changeset viewer.

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