source: trunk/zoo-kernel/service_internal.c @ 248

Last change on this file since 248 was 216, checked in by djay, 14 years ago

Add WIN32 platform support. Fix for values containing @ passed as KVP.

File size: 62.2 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2011 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal.h"
26
27#ifdef WIN32
28char *
29strtok_r (char *s1, const char *s2, char **lasts)
30{
31  char *ret;
32  if (s1 == NULL)
33    s1 = *lasts;
34  while (*s1 && strchr(s2, *s1))
35    ++s1;
36  if (*s1 == '\0')
37    return NULL;
38  ret = s1;
39  while (*s1 && !strchr(s2, *s1))
40    ++s1;
41  if (*s1)
42    *s1++ = '\0';
43  *lasts = s1;
44  return ret;
45}
46#endif
47
48void addLangAttr(xmlNodePtr n,maps *m){
49  map *tmpLmap=getMapFromMaps(m,"main","language");
50  if(tmpLmap!=NULL)
51    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST tmpLmap->value);
52  else
53    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST "en-US");
54}
55
56/* Converts a hex character to its integer value */
57char from_hex(char ch) {
58  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
59}
60
61/* Converts an integer value to its hex character*/
62char to_hex(char code) {
63  static char hex[] = "0123456789abcdef";
64  return hex[code & 15];
65}
66
67#ifdef WIN32
68
69#include <windows.h>
70#include <stdio.h>
71#include <conio.h>
72#include <tchar.h>
73
74#define SHMEMSIZE 4096
75
76static LPVOID lpvMemG = NULL;      // pointer to shared memory
77static HANDLE hMapObjectG = NULL;  // handle to file mapping
78
79void updateStatus(maps *conf){
80        fprintf(stderr,"OK Final 1 \n");
81        fflush(stderr);
82        LPWSTR lpszTmp;
83        BOOL fInit;
84        char *s=NULL;
85        map *tmpMap=getMapFromMaps(conf,"lenv","sid");
86        fprintf(stderr,"OK Final 11 \n");
87        fflush(stderr);
88        if(hMapObjectG==NULL)
89        hMapObjectG = CreateFileMapping( 
90                INVALID_HANDLE_VALUE,   // use paging file
91                NULL,                   // default security attributes
92                PAGE_READWRITE,         // read/write access
93                0,                      // size: high 32-bits
94                SHMEMSIZE,              // size: low 32-bits
95                TEXT(tmpMap->value));   // name of map object
96        if (hMapObjectG == NULL){
97                fprintf(stderr,"Unable to create share memory segment %s !! \n",tmpMap->value);
98                return ;
99        }
100        fprintf(stderr,"OK Final 2 \n");
101        fflush(stderr);
102        fInit = (GetLastError() != ERROR_ALREADY_EXISTS); 
103        if(lpvMemG==NULL)
104        lpvMemG = MapViewOfFile( 
105                hMapObjectG,     // object to map view of
106                FILE_MAP_WRITE, // read/write access
107                0,              // high offset:  map from
108                0,              // low offset:   beginning
109                0);             // default: map entire file
110        if (lpvMemG == NULL){
111                fprintf(stderr,"Unable to create or access the shared memory segment %s !! \n",tmpMap->value);
112                return ;
113        } 
114        fprintf(stderr,"OK Final 3 \n");
115        fflush(stderr);
116        if (fInit)
117                memset(lpvMemG, '\0', SHMEMSIZE);
118        fprintf(stderr,"OK Final 4 \n");
119        fflush(stderr);
120        tmpMap=getMapFromMaps(conf,"lenv","status");
121        lpszTmp = (LPWSTR) lpvMemG;
122        for(s=tmpMap->value;*s!=NULL;s++)
123                *lpszTmp++ = *s;
124        *lpszTmp = '\0'; 
125}
126
127char* getStatus(int pid){
128  LPWSTR lpszBuf=NULL;
129  LPWSTR lpszTmp=NULL;
130  LPVOID lpvMem = NULL;
131  HANDLE hMapObject = NULL;
132  BOOL fIgnore,fInit;
133  char tmp[100];
134  sprintf(tmp,"%i",pid);
135  if(hMapObject==NULL)
136    hMapObject = CreateFileMapping( 
137                                   INVALID_HANDLE_VALUE,   // use paging file
138                                   NULL,                   // default security attributes
139                                   PAGE_READWRITE,         // read/write access
140                                   0,                      // size: high 32-bits
141                                   4096,                   // size: low 32-bits
142                                   TEXT(tmp));   // name of map object
143  if (hMapObject == NULL) 
144    return FALSE;
145  if((GetLastError() != ERROR_ALREADY_EXISTS)){
146    fIgnore = UnmapViewOfFile(lpvMem); 
147    fIgnore = CloseHandle(hMapObject);
148    return "-1";
149  }
150  fInit=TRUE;
151  if(lpvMem==NULL)
152    lpvMem = MapViewOfFile( 
153                           hMapObject,     // object to map view of
154                           FILE_MAP_READ,  // read/write access
155                           0,              // high offset:  map from
156                           0,              // low offset:   beginning
157                           0);             // default: map entire file
158  if (lpvMem == NULL) 
159    return "-1"; 
160  lpszTmp = (LPWSTR) lpvMem;
161  while (*lpszTmp!=NULL)
162    *lpszBuf++ = *lpszTmp++;
163  *lpszBuf = '\0';
164  fIgnore = UnmapViewOfFile(lpvMem); 
165  fIgnore = CloseHandle(hMapObject);
166  return (char*)lpszBuf;
167}
168
169void unhandleStatus(maps *conf){
170  BOOL fIgnore;
171  fIgnore = UnmapViewOfFile(lpvMemG); 
172  fIgnore = CloseHandle(hMapObjectG);
173}
174#else
175void unhandleStatus(maps *conf){
176  int shmid,i;
177  key_t key;
178  void *shm;
179  struct shmid_ds shmids;
180  char *s,*s1;
181  map *tmpMap=getMapFromMaps(conf,"lenv","sid");
182  if(tmpMap!=NULL){
183    key=atoi(tmpMap->value);
184    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
185#ifdef DEBUG
186      fprintf(stderr,"shmget failed to update value\n");
187#endif
188    }else{
189      if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
190#ifdef DEBUG
191        fprintf(stderr,"shmat failed to update value\n");
192#endif
193      }else{
194        shmdt(shm);
195        shmctl(shmid,IPC_RMID,&shmids);
196      }
197    }
198  }
199}
200
201void updateStatus(maps *conf){
202  int shmid,i;
203  key_t key;
204  char *shm,*s,*s1;
205  map *tmpMap=NULL;
206  tmpMap=getMapFromMaps(conf,"lenv","sid");
207  if(tmpMap!=NULL){
208    key=atoi(tmpMap->value);
209    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
210#ifdef DEBUG
211      fprintf(stderr,"shmget failed to update value\n");
212#endif
213    }else{
214      if ((shm = (char*) shmat(shmid, NULL, 0)) == (char *) -1) {
215#ifdef DEBUG
216        fprintf(stderr,"shmat failed to update value\n");
217#endif
218      }
219      else{
220        tmpMap=getMapFromMaps(conf,"lenv","status");
221        s1=shm;
222        for(s=tmpMap->value;s!=NULL;s++)
223          *s1++=*s;
224        shmdt((void *)shm);
225      }
226    }
227  }
228}
229
230char* getStatus(int pid){
231  int shmid,i;
232  key_t key;
233  void *shm;
234  char *s;
235  key=pid;
236  if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
237#ifdef DEBUG
238    fprintf(stderr,"shmget failed in getStatus\n");
239#endif
240  }else{
241    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
242#ifdef DEBUG
243      fprintf(stderr,"shmat failed in getStatus\n");
244#endif
245    }else{
246      return (char*)shm;
247    }
248  }
249  return "-1";
250}
251
252#endif
253
254#ifdef USE_JS
255
256JSBool
257JSUpdateStatus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
258{
259  JS_MaybeGC(cx);
260  char *sid;
261  int istatus=0;
262  char *status=NULL;
263  maps *conf;
264  int i=0;
265  if(argc>2){
266#ifdef JS_DEBUG
267    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
268#endif
269    return JS_FALSE;
270  }
271  conf=mapsFromJSObject(cx,argv[0]);
272  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
273    char tmpStatus[4];
274    sprintf(tmpStatus,"%i",istatus);
275    tmpStatus[3]=0;
276    status=strdup(tmpStatus);
277  }
278  if(getMapFromMaps(conf,"lenv","status")!=NULL){
279    if(status!=NULL)
280      setMapInMaps(conf,"lenv","status",status);
281    else
282      setMapInMaps(conf,"lenv","status","15");
283    updateStatus(conf);
284  }
285  freeMaps(&conf);
286  free(conf);
287  JS_MaybeGC(cx);
288  return JS_TRUE;
289}
290
291#endif
292
293
294
295/* Returns a url-encoded version of str */
296/* IMPORTANT: be sure to free() the returned string after use */
297char *url_encode(char *str) {
298  char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
299  while (*pstr) {
300    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
301      *pbuf++ = *pstr;
302    else if (*pstr == ' ') 
303      *pbuf++ = '+';
304    else 
305      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
306    pstr++;
307  }
308  *pbuf = '\0';
309  return buf;
310}
311
312/* Returns a url-decoded version of str */
313/* IMPORTANT: be sure to free() the returned string after use */
314char *url_decode(char *str) {
315  char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
316  while (*pstr) {
317    if (*pstr == '%') {
318      if (pstr[1] && pstr[2]) {
319        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
320        pstr += 2;
321      }
322    } else if (*pstr == '+') { 
323      *pbuf++ = ' ';
324    } else {
325      *pbuf++ = *pstr;
326    }
327    pstr++;
328  }
329  *pbuf = '\0';
330  return buf;
331}
332
333char *zCapitalize1(char *tmp){
334        char *res=strdup(tmp);
335        if(res[0]>=97 && res[0]<=122)
336                res[0]-=32;
337        return res;
338}
339
340char *zCapitalize(char *tmp){
341  int i=0;
342  char *res=strdup(tmp);
343  for(i=0;i<strlen(res);i++)
344    if(res[i]>=97 && res[i]<=122)
345      res[i]-=32;
346  return res;
347}
348
349
350int zooXmlSearchForNs(const char* name){
351  int i;
352  int res=-1;
353  for(i=0;i<nbNs;i++)
354    if(strncasecmp(name,nsName[i],strlen(nsName[i]))==0){
355      res=i;
356      break;
357    }
358  return res;
359}
360
361int zooXmlAddNs(xmlNodePtr nr,const char* url,const char* name){
362#ifdef DEBUG
363  fprintf(stderr,"zooXmlAddNs %d \n",nbNs);
364#endif
365  int currId=-1;
366  if(nbNs==0){
367    nbNs++;
368    currId=0;
369    nsName[currId]=strdup(name);
370    usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
371  }else{
372    currId=zooXmlSearchForNs(name);
373    if(currId<0){
374      nbNs++;
375      currId=nbNs-1;
376      nsName[currId]=strdup(name);
377      usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
378    }
379  }
380  return currId;
381}
382
383void zooXmlCleanupNs(){
384  int j;
385#ifdef DEBUG
386  fprintf(stderr,"zooXmlCleanup %d\n",nbNs);
387#endif
388  for(j=nbNs-1;j>=0;j--){
389#ifdef DEBUG
390    fprintf(stderr,"zooXmlCleanup %d\n",j);
391#endif
392    if(j==0)
393      xmlFreeNs(usedNs[j]);
394    free(nsName[j]);
395    nbNs--;
396  }
397  nbNs=0;
398}
399
400xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr doc,const char* service,maps* m){
401
402  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
403  xmlNodePtr n,nc,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
404  xmlChar *xmlbuff;
405  int buffersize;
406  /**
407   * Create the document and its temporary root.
408   */
409  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
410  ns=usedNs[wpsId];
411  maps* toto1=getMaps(m,"main");
412
413  n = xmlNewNode(ns, BAD_CAST "Capabilities");
414  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
415  ns_ows=usedNs[owsId];
416  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
417  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
418  ns_xsi=usedNs[xsiId];
419  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
420  ns_xlink=usedNs[xlinkId];
421  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsGetCapabilities_response.xsd"); 
422  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
423  addLangAttr(n,m);
424 
425  if(toto1!=NULL){
426    map* tmp=getMap(toto1->content,"version");
427    if(tmp!=NULL){
428      xmlNewProp(n,BAD_CAST "version",BAD_CAST tmp->value);
429    }
430    else
431      xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
432  }
433  else
434    xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
435
436  char tmp[256];
437 
438  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceIdentification");
439  maps* tmp4=getMaps(m,"identification");
440  if(tmp4!=NULL){
441    map* tmp2=tmp4->content;
442    char *orderedFields[5];
443    orderedFields[0]="Title";
444    orderedFields[1]="Abstract";
445    orderedFields[2]="Keywords";
446    orderedFields[3]="Fees";
447    orderedFields[4]="AccessConstraints";
448    int oI=0;
449    for(oI=0;oI<5;oI++)
450      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
451        if(strcasecmp(tmp2->name,"abstract")==0 ||
452           strcasecmp(tmp2->name,"title")==0 ||
453           strcasecmp(tmp2->name,"accessConstraints")==0 ||
454           strcasecmp(tmp2->name,"fees")==0){
455          tmp2->name[0]=toupper(tmp2->name[0]);
456          nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
457          xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
458          xmlAddChild(nc,nc1);
459        }
460        else
461          if(strcmp(tmp2->name,"keywords")==0){
462            nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
463            char *toto=tmp2->value;
464            char buff[256];
465            int i=0;
466            int j=0;
467            while(toto[i]){
468              if(toto[i]!=',' && toto[i]!=0){
469                buff[j]=toto[i];
470                buff[j+1]=0;
471                j++;
472              }
473              else{
474                nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
475                xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
476                xmlAddChild(nc1,nc2);
477                j=0;
478              }
479              i++;
480            }
481            if(strlen(buff)>0){
482              nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
483              xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
484              xmlAddChild(nc1,nc2);
485            }
486            xmlAddChild(nc,nc1);
487            nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceType");
488            xmlAddChild(nc2,xmlNewText(BAD_CAST "WPS"));
489            xmlAddChild(nc,nc2);
490            nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceTypeVersion");
491            xmlAddChild(nc2,xmlNewText(BAD_CAST "1.0.0"));
492            xmlAddChild(nc,nc2);         
493          }
494        tmp2=tmp2->next;
495      }
496  }
497  else{
498    fprintf(stderr,"TMP4 NOT FOUND !!");
499    return NULL;
500  }
501  xmlAddChild(n,nc);
502
503  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceProvider");
504  nc3 = xmlNewNode(ns_ows, BAD_CAST "ServiceContact");
505  nc4 = xmlNewNode(ns_ows, BAD_CAST "ContactInfo");
506  nc5 = xmlNewNode(ns_ows, BAD_CAST "Phone");
507  nc6 = xmlNewNode(ns_ows, BAD_CAST "Address");
508  tmp4=getMaps(m,"provider");
509  if(tmp4!=NULL){
510    map* tmp2=tmp4->content;
511    char *tmpAddress[6];
512    tmpAddress[0]="addressDeliveryPoint";
513    tmpAddress[1]="addressCity";
514    tmpAddress[2]="addressAdministrativeArea";
515    tmpAddress[3]="addressPostalCode";
516    tmpAddress[4]="addressCountry";
517    tmpAddress[5]="addressElectronicMailAddress";
518    char *tmpPhone[2];
519    tmpPhone[0]="phoneVoice";
520    tmpPhone[1]="phoneFacsimile";
521    char *orderedFields[12];
522    orderedFields[0]="providerName";
523    orderedFields[1]="providerSite";
524    orderedFields[2]="individualName";
525    orderedFields[3]="positionName";
526    orderedFields[4]=tmpPhone[0];
527    orderedFields[5]=tmpPhone[1];
528    orderedFields[6]=tmpAddress[0];
529    orderedFields[7]=tmpAddress[1];
530    orderedFields[8]=tmpAddress[2];
531    orderedFields[9]=tmpAddress[3];
532    orderedFields[10]=tmpAddress[4];
533    orderedFields[11]=tmpAddress[5];
534    int oI=0;
535    for(oI=0;oI<12;oI++)
536      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
537        if(strcmp(tmp2->name,"keywords")!=0 &&
538           strcmp(tmp2->name,"serverAddress")!=0 &&
539           strcmp(tmp2->name,"lang")!=0){
540          tmp2->name[0]=toupper(tmp2->name[0]);
541          if(strcmp(tmp2->name,"ProviderName")==0){
542            nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
543            xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
544            xmlAddChild(nc,nc1);
545          }
546          else{
547            if(strcmp(tmp2->name,"ProviderSite")==0){
548              nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
549              xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST tmp2->value);
550              xmlAddChild(nc,nc1);
551            } 
552            else 
553              if(strcmp(tmp2->name,"IndividualName")==0 || 
554                 strcmp(tmp2->name,"PositionName")==0){
555                nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
556                xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
557                xmlAddChild(nc3,nc1);
558              } 
559              else 
560                if(strncmp(tmp2->name,"Phone",5)==0){
561                  int j;
562                  for(j=0;j<2;j++)
563                    if(strcasecmp(tmp2->name,tmpPhone[j])==0){
564                      char *toto=NULL;
565                      char *toto1=tmp2->name;
566                      toto=strstr(toto1,"Phone");
567                      nc1 = xmlNewNode(ns_ows, BAD_CAST toto1+5);
568                      xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
569                      xmlAddChild(nc5,nc1);
570                    }
571                }
572                else 
573                  if(strncmp(tmp2->name,"Address",7)==0){
574                    int j;
575                    for(j=0;j<6;j++)
576                      if(strcasecmp(tmp2->name,tmpAddress[j])==0){
577                        char *toto=NULL;
578                        char *toto1=tmp2->name;
579                        toto=strstr(toto1,"Address");
580                        nc1 = xmlNewNode(ns_ows, BAD_CAST toto1+7);
581                        xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
582                        xmlAddChild(nc6,nc1);
583                      }
584                  }
585          }
586        }
587        else
588          if(strcmp(tmp2->name,"keywords")==0){
589            nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
590            char *toto=tmp2->value;
591            char buff[256];
592            int i=0;
593            int j=0;
594            while(toto[i]){
595              if(toto[i]!=',' && toto[i]!=0){
596                buff[j]=toto[i];
597                buff[j+1]=0;
598                j++;
599              }
600              else{
601                nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
602                xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
603                xmlAddChild(nc1,nc2);
604                j=0;
605              }
606              i++;
607            }
608            if(strlen(buff)>0){
609              nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
610              xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
611              xmlAddChild(nc1,nc2);
612            }
613            xmlAddChild(nc,nc1);
614          }
615        tmp2=tmp2->next;
616      }
617  }
618  else{
619    fprintf(stderr,"TMP4 NOT FOUND !!");
620  }
621  xmlAddChild(nc4,nc5);
622  xmlAddChild(nc4,nc6);
623  xmlAddChild(nc3,nc4);
624  xmlAddChild(nc,nc3);
625  xmlAddChild(n,nc);
626
627
628  nc = xmlNewNode(ns_ows, BAD_CAST "OperationsMetadata");
629  char *tmp2[3];
630  tmp2[0]=strdup("GetCapabilities");
631  tmp2[1]=strdup("DescribeProcess");
632  tmp2[2]=strdup("Execute");
633  int j=0;
634
635  if(toto1!=NULL){
636    map* tmp=getMap(toto1->content,"serverAddress");
637    if(tmp!=NULL){
638      SERVICE_URL = strdup(tmp->value);
639    }
640    else
641      SERVICE_URL = strdup("not_found");
642  }
643  else
644    SERVICE_URL = strdup("not_found");
645
646  for(j=0;j<3;j++){
647    nc1 = xmlNewNode(ns_ows, BAD_CAST "Operation");
648    xmlNewProp(nc1,BAD_CAST "name",BAD_CAST tmp2[j]);
649    nc2 = xmlNewNode(ns_ows, BAD_CAST "DCP");
650    nc3 = xmlNewNode(ns_ows, BAD_CAST "HTTP");
651    nc4 = xmlNewNode(ns_ows, BAD_CAST "Get");
652    sprintf(tmp,"%s/%s",SERVICE_URL,service);
653    xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
654    xmlAddChild(nc3,nc4);
655    if(j>0){
656      nc4 = xmlNewNode(ns_ows, BAD_CAST "Post");
657      xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
658      xmlAddChild(nc3,nc4);
659    }
660    xmlAddChild(nc2,nc3);
661    xmlAddChild(nc1,nc2);   
662    xmlAddChild(nc,nc1);   
663  }
664  for(j=2;j>=0;j--)
665    free(tmp2[j]);
666  xmlAddChild(n,nc);
667
668  nc = xmlNewNode(ns, BAD_CAST "ProcessOfferings");
669  xmlAddChild(n,nc);
670
671  nc1 = xmlNewNode(ns, BAD_CAST "Languages");
672  nc2 = xmlNewNode(ns, BAD_CAST "Default");
673  nc3 = xmlNewNode(ns, BAD_CAST "Supported");
674 
675  toto1=getMaps(m,"main");
676  if(toto1!=NULL){
677    map* tmp1=getMap(toto1->content,"lang");
678    char *toto=tmp1->value;
679    char buff[256];
680    int i=0;
681    int j=0;
682    int dcount=0;
683    while(toto[i]){
684      if(toto[i]!=',' && toto[i]!=0){
685        buff[j]=toto[i];
686        buff[j+1]=0;
687        j++;
688      }
689      else{
690        nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
691        xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
692        if(dcount==0){
693          xmlAddChild(nc2,nc4);
694          xmlAddChild(nc1,nc2);
695          dcount++;
696        }
697        nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
698        xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
699        xmlAddChild(nc3,nc4);
700        j=0;
701        buff[j]=0;
702      }
703      i++;
704    }
705    if(strlen(buff)>0){
706      nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
707      xmlAddChild(nc4,xmlNewText(BAD_CAST buff));             
708      xmlAddChild(nc3,nc4);
709    }
710  }
711  xmlAddChild(nc1,nc3);
712  xmlAddChild(n,nc1);
713 
714  xmlDocSetRootElement(doc, n);
715  //xmlFreeNs(ns);
716  free(SERVICE_URL);
717  return nc;
718}
719
720void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
721  xmlNsPtr ns,ns_ows,ns_xlink;
722  xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
723  /**
724   * Initialize or get existing namspaces
725   */
726  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
727  ns=usedNs[wpsId];
728  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
729  ns_ows=usedNs[owsId];
730  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
731  ns_xlink=usedNs[xlinkId];
732
733  int cursor=0;
734  map* tmp1;
735  if(serv->content!=NULL){
736    nc1 = xmlNewNode(ns, BAD_CAST "Process");
737    tmp1=getMap(serv->content,"processVersion");
738    if(tmp1!=NULL)
739      xmlNewNsProp(nc1,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);
740    printDescription(nc1,ns_ows,serv->name,serv->content);
741    tmp1=serv->metadata;
742    while(tmp1!=NULL){
743      nc2 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
744      xmlNewNsProp(nc2,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
745      xmlAddChild(nc1,nc2);
746      tmp1=tmp1->next;
747    }
748    xmlAddChild(nc,nc1);
749  }
750}
751
752xmlNodePtr printDescribeProcessHeader(xmlDocPtr doc,const char* service,maps* m){
753
754  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
755  xmlNodePtr n,nr;
756  xmlChar *xmlbuff;
757  int buffersize;
758
759  int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
760  ns=usedNs[wpsId];
761  n = xmlNewNode(ns, BAD_CAST "ProcessDescriptions");
762  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
763  ns_ows=usedNs[owsId];
764  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
765  zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
766  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
767  ns_xsi=usedNs[xsiId];
768 
769  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd");
770  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
771  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
772  addLangAttr(n,m);
773
774  xmlDocSetRootElement(doc, n);
775
776  return n;
777}
778
779void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv,int sc){
780  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
781  xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
782
783  char tmp[256];
784  n=nc;
785 
786  int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
787  ns=usedNs[wpsId];
788  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
789  ns_ows=usedNs[owsId];
790  int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
791  ns_xlink=usedNs[xlinkId];
792
793  nc = xmlNewNode(NULL, BAD_CAST "ProcessDescription");
794  char *tmp4[3];
795  tmp4[0]="processVersion";
796  tmp4[1]="storeSupported";
797  tmp4[2]="statusSupported";
798  int j=0;
799  map* tmp1=NULL;
800  for(j=0;j<3;j++){
801    tmp1=getMap(serv->content,tmp4[j]);
802    if(tmp1!=NULL){
803      if(j==0)
804        xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);     
805      else
806        xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value);     
807    }
808    else{
809      if(j>0)
810        xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "false");     
811    }
812  }
813 
814  printDescription(nc,ns_ows,serv->name,serv->content);
815
816  tmp1=serv->metadata;
817  while(tmp1!=NULL){
818    nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
819    xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
820    xmlAddChild(nc,nc1);
821    tmp1=tmp1->next;
822  }
823
824  tmp1=getMap(serv->content,"Profile");
825  if(tmp1!=NULL){
826    nc1 = xmlNewNode(ns, BAD_CAST "Profile");
827    xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
828    xmlAddChild(nc,nc1);
829  }
830
831  nc1 = xmlNewNode(NULL, BAD_CAST "DataInputs");
832  elements* e=serv->inputs;
833  printFullDescription(e,"Input",ns_ows,nc1);
834  xmlAddChild(nc,nc1);
835
836  nc1 = xmlNewNode(NULL, BAD_CAST "ProcessOutputs");
837  e=serv->outputs;
838  printFullDescription(e,"Output",ns_ows,nc1);
839  xmlAddChild(nc,nc1);
840
841  xmlAddChild(n,nc);
842
843}
844
845void printFullDescription(elements *elem,const char* type,xmlNsPtr ns_ows,xmlNodePtr nc1){
846  char *orderedFields[7];
847  orderedFields[0]="mimeType";
848  orderedFields[1]="encoding";
849  orderedFields[2]="schema";
850  orderedFields[3]="dataType";
851  orderedFields[4]="uom";
852  orderedFields[5]="CRS";
853  orderedFields[6]="value";
854
855  xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7;
856  elements* e=elem;
857  map* tmp1=NULL;
858  while(e!=NULL){
859    int default1=0;
860    int isAnyValue=1;
861    nc2 = xmlNewNode(NULL, BAD_CAST type);
862    tmp1=getMap(e->content,"minOccurs");
863    if(tmp1){
864      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
865    }
866    tmp1=getMap(e->content,"maxOccurs");
867    if(tmp1){
868      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
869    }
870
871    printDescription(nc2,ns_ows,e->name,e->content);
872
873    if(strncmp(type,"Output",6)==0){
874      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
875        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralOutput");
876      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
877        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexOutput");
878      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
879        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
880      else
881        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
882    }else{
883      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0){
884        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralData");
885      }
886      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
887        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexData");
888      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
889        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxData");
890      else
891        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
892    }
893    iotype* _tmp=e->defaults;
894    int datatype=0;
895    bool hasDefault=false;
896    bool hasUOM=false;
897    if(_tmp!=NULL){
898      if(strcmp(e->format,"LiteralOutput")==0 ||
899         strcmp(e->format,"LiteralData")==0){
900        datatype=1;
901        nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
902        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
903      }
904      else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
905              strcmp(e->format,"BoundingBoxData")==0){
906        datatype=2;
907        //nc4 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
908        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
909      }
910      else{
911        nc4 = xmlNewNode(NULL, BAD_CAST "Default");
912        nc5 = xmlNewNode(NULL, BAD_CAST "Format");
913      }
914     
915      tmp1=_tmp->content;
916      int avcnt=0;
917      int dcnt=0;
918      int oI=0;
919      for(oI=0;oI<7;oI++)
920        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
921          //while(tmp1!=NULL){
922#ifdef DEBUG
923          printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
924#endif
925          if(strncasecmp(tmp1->name,"DataType",8)==0){
926            nc6 = xmlNewNode(ns_ows, BAD_CAST "DataType");
927            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
928            char tmp[1024];
929            sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
930            xmlNewNsProp(nc6,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
931            xmlAddChild(nc3,nc6);
932            tmp1=tmp1->next;
933            datatype=1;
934            continue;
935          }
936          if(strcmp(tmp1->name,"asReference")!=0 &&
937             strncasecmp(tmp1->name,"DataType",8)!=0 &&
938             strcasecmp(tmp1->name,"extension")!=0 &&
939             strcasecmp(tmp1->name,"value")!=0 &&
940             strncasecmp(tmp1->name,"AllowedValues",13)!=0){
941            if(datatype!=1){
942              char *tmp2=zCapitalize1(tmp1->name);
943              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
944              free(tmp2);
945            }
946            else{
947              char *tmp2=zCapitalize(tmp1->name);
948              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
949              free(tmp2);
950            }
951            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
952            xmlAddChild(nc5,nc6);
953            hasUOM=true;
954          }else 
955            if(strncmp(type,"Input",5)==0){
956              if(strcmp(tmp1->name,"value")==0){
957                nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
958                xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
959                default1=1;
960              }
961              if(strncasecmp(tmp1->name,"AllowedValues",13)==0){
962                nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
963                fprintf(stderr,"ALLOWED VALUE %s\n",tmp1->value);
964                char *token,*saveptr1;
965                token=strtok_r(tmp1->value,",",&saveptr1);
966                while(token!=NULL){
967                  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
968                  char *tmps=strdup(token);
969                  tmps[strlen(tmps)]=0;
970                  xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
971                  fprintf(stderr,"strgin : %s\n",tmps);
972                  xmlAddChild(nc6,nc7);
973                  token=strtok_r(NULL,",",&saveptr1);
974                }
975                xmlAddChild(nc3,nc6);
976                isAnyValue=-1;
977              }
978              hasDefault=true;
979            }
980          tmp1=tmp1->next;
981          if(datatype!=2){
982            if(hasUOM==true){
983              xmlAddChild(nc4,nc5);
984              xmlAddChild(nc3,nc4);
985            }
986          }else{
987            xmlAddChild(nc3,nc5);
988          }
989         
990          if(strncmp(type,"Input",5)==0){
991            if(datatype==1 && isAnyValue==1 && avcnt==0){
992              xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
993              hasDefault=true;
994              avcnt++;
995            }
996            if(datatype==1 && default1>0){
997              xmlAddChild(nc3,nc7);
998            }
999          }
1000        }
1001    }
1002    _tmp=e->supported;
1003    int hasSupported=-1;
1004    while(_tmp!=NULL){
1005      if(hasSupported<0){
1006        if(datatype==0){
1007          nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
1008          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1009        }
1010        else
1011          nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
1012        hasSupported=0;
1013      }else
1014        if(datatype==0)
1015          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1016      tmp1=_tmp->content;
1017      int oI=0;
1018      for(oI=0;oI<6;oI++)
1019        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
1020#ifdef DEBUG
1021          printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
1022#endif
1023          if(strcmp(tmp1->name,"asReference")!=0 && 
1024             strcmp(tmp1->name,"DataType")!=0 &&
1025             strcasecmp(tmp1->name,"extension")!=0){
1026            if(datatype!=1){
1027              char *tmp2=zCapitalize1(tmp1->name);
1028              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1029              free(tmp2);
1030            }
1031            else{
1032              char *tmp2=zCapitalize(tmp1->name);
1033              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
1034              free(tmp2);
1035            }
1036            if(datatype==2){
1037              char *tmpv,*tmps;
1038              tmps=strtok_r(tmp1->value,",",&tmpv);
1039              while(tmps){
1040                xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
1041                xmlAddChild(nc5,nc6);
1042                tmps=strtok_r(NULL,",",&tmpv);
1043                if(tmps){
1044                  char *tmp2=zCapitalize1(tmp1->name);
1045                  nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1046                  free(tmp2);
1047                }
1048              }
1049            }
1050            else{
1051              xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
1052              xmlAddChild(nc5,nc6);
1053            }
1054          }
1055          tmp1=tmp1->next;
1056        }
1057      if(hasSupported<=0){
1058        if(datatype!=2){
1059          xmlAddChild(nc4,nc5);
1060          xmlAddChild(nc3,nc4);
1061        }else
1062          xmlAddChild(nc3,nc5);
1063        hasSupported=1;
1064      }
1065      else
1066        if(datatype!=2){
1067          xmlAddChild(nc4,nc5);
1068        }
1069        else
1070          xmlAddChild(nc3,nc5);
1071      _tmp=_tmp->next;
1072    }
1073    xmlAddChild(nc2,nc3);
1074   
1075    if(datatype!=2 && hasUOM==true){
1076      xmlAddChild(nc3,nc4);
1077      xmlAddChild(nc2,nc3);
1078    }else if(datatype!=2){
1079      if(hasDefault!=true && strncmp(type,"Input",5)==0)
1080        xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1081      xmlFreeNodeList(nc5);
1082      xmlFreeNodeList(nc4);
1083    }
1084   
1085    xmlAddChild(nc1,nc2);
1086   
1087    e=e->next;
1088  }
1089}
1090
1091void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
1092  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
1093  xmlNodePtr nr,n,nc,nc1,nc2,nc3,pseudor;
1094  xmlDocPtr doc;
1095  xmlChar *xmlbuff;
1096  int buffersize;
1097  time_t time1; 
1098  time(&time1);
1099  /**
1100   * Create the document and its temporary root.
1101   */
1102  doc = xmlNewDoc(BAD_CAST "1.0");
1103  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
1104  ns=usedNs[wpsId];
1105 
1106  n = xmlNewNode(ns, BAD_CAST "ExecuteResponse");
1107  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
1108  ns_ows=usedNs[owsId];
1109  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1110  ns_xlink=usedNs[xlinkId];
1111  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1112  ns_xsi=usedNs[xsiId];
1113  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
1114
1115  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_response.xsd");
1116 
1117  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
1118  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
1119  addLangAttr(n,m);
1120
1121  char tmp[256];
1122  char url[1024];
1123  char stored_path[1024];
1124  memset(tmp,0,256);
1125  memset(url,0,1024);
1126  memset(stored_path,0,1024);
1127  maps* tmp_maps=getMaps(m,"main");
1128  if(tmp_maps!=NULL){
1129    map* tmpm1=getMap(tmp_maps->content,"serverAddress");
1130    /**
1131     * Check if the ZOO Service GetStatus is available in the local directory.
1132     * If yes, then it uses a reference to an URL which the client can access
1133     * to get information on the status of a running Service (using the
1134     * percentCompleted attribute).
1135     * Else fallback to the initial method using the xml file to write in ...
1136     */
1137    char ntmp[1024];
1138#ifndef WIN32
1139    getcwd(ntmp,1024);
1140#else
1141    _getcwd(ntmp,1024);
1142#endif
1143    struct stat myFileInfo;
1144    int statRes;
1145    char file_path[1024];
1146    sprintf(file_path,"%s/GetStatus.zcfg",ntmp);
1147    statRes=stat(file_path,&myFileInfo);
1148    if(statRes==0){
1149      char currentSid[128];
1150      map* tmpm=getMap(tmp_maps->content,"rewriteUrl");
1151      map *tmp_lenv=NULL;
1152      tmp_lenv=getMapFromMaps(m,"lenv","sid");
1153      if(tmp_lenv==NULL)
1154        sprintf(currentSid,"%i",pid);
1155      else
1156        sprintf(currentSid,"%s",tmp_lenv->value);
1157      if(tmpm==NULL || strcasecmp(tmpm->value,"false")==0){
1158        sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1159      }else{
1160        if(strlen(tmpm->value)>0)
1161          if(strcasecmp(tmpm->value,"true")!=0)
1162            sprintf(url,"%s/%s/GetStatus/%s",tmpm1->value,tmpm->value,currentSid);
1163          else
1164            sprintf(url,"%s/GetStatus/%s",tmpm1->value,currentSid);
1165        else
1166          sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1167      }
1168    }else{
1169      map* tmpm2=getMap(tmp_maps->content,"tmpUrl");
1170      if(tmpm1!=NULL && tmpm2!=NULL){
1171        sprintf(url,"%s/%s/%s_%i.xml",tmpm1->value,tmpm2->value,service,pid);
1172      }
1173    }
1174    if(tmpm1!=NULL)
1175      sprintf(tmp,"%s/",tmpm1->value);
1176    tmpm1=getMapFromMaps(m,"main","TmpPath");
1177    sprintf(stored_path,"%s/%s_%i.xml",tmpm1->value,service,pid);
1178  }
1179
1180 
1181
1182  xmlNewProp(n,BAD_CAST "serviceInstance",BAD_CAST tmp);
1183  map* test=getMap(request,"storeExecuteResponse");
1184  bool hasStoredExecuteResponse=false;
1185  if(test!=NULL && strcasecmp(test->value,"true")==0){
1186    xmlNewProp(n,BAD_CAST "statusLocation",BAD_CAST url);
1187    hasStoredExecuteResponse=true;
1188  }
1189
1190  nc = xmlNewNode(ns, BAD_CAST "Process");
1191  map* tmp2=getMap(serv->content,"processVersion");
1192
1193  if(tmp2!=NULL)
1194    xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp2->value);
1195 
1196  printDescription(nc,ns_ows,serv->name,serv->content);
1197  fflush(stderr);
1198
1199  xmlAddChild(n,nc);
1200
1201  nc = xmlNewNode(ns, BAD_CAST "Status");
1202  const struct tm *tm;
1203  size_t len;
1204  time_t now;
1205  char *tmp1;
1206  map *tmpStatus;
1207 
1208  now = time ( NULL );
1209  tm = localtime ( &now );
1210
1211  tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
1212
1213  len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
1214
1215  xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
1216
1217  char sMsg[2048];
1218  switch(status){
1219  case SERVICE_SUCCEEDED:
1220    nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
1221    sprintf(sMsg,_("Service \"%s\" run successfully."),serv->name);
1222    nc3=xmlNewText(BAD_CAST sMsg);
1223    xmlAddChild(nc1,nc3);
1224    break;
1225  case SERVICE_STARTED:
1226    nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
1227    tmpStatus=getMapFromMaps(m,"lenv","status");
1228    xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
1229    sprintf(sMsg,_("ZOO Service \"%s\" is currently running. Please, reload this document to get the up-to-date status of the Service."),serv->name);
1230    nc3=xmlNewText(BAD_CAST sMsg);
1231    xmlAddChild(nc1,nc3);
1232    break;
1233  case SERVICE_ACCEPTED:
1234    nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
1235    sprintf(sMsg,_("Service \"%s\" was accepted by the ZOO Kernel and it run as a background task. Please consult the statusLocation attribtue providen in this document to get the up-to-date document."),serv->name);
1236    nc3=xmlNewText(BAD_CAST sMsg);
1237    xmlAddChild(nc1,nc3);
1238    break;
1239  case SERVICE_FAILED:
1240    nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
1241    map *errorMap;
1242    map *te;
1243    te=getMapFromMaps(m,"lenv","code");
1244    if(te!=NULL)
1245      errorMap=createMap("code",te->value);
1246    else
1247      errorMap=createMap("code","NoApplicableCode");
1248    te=getMapFromMaps(m,"lenv","message");
1249    if(te!=NULL)
1250      addToMap(errorMap,"text",_ss(te->value));
1251    else
1252      addToMap(errorMap,"text",_("No more information available"));
1253    nc3=createExceptionReportNode(m,errorMap,0);
1254    freeMap(&errorMap);
1255    free(errorMap);
1256    xmlAddChild(nc1,nc3);
1257    break;
1258  default :
1259    printf(_("error code not know : %i\n"),status);
1260    //exit(1);
1261    break;
1262  }
1263  xmlAddChild(nc,nc1);
1264  xmlAddChild(n,nc);
1265  free(tmp1);
1266
1267#ifdef DEBUG
1268  fprintf(stderr,"printProcessResponse 1 161\n");
1269#endif
1270
1271  map* lineage=getMap(request,"lineage");
1272  if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
1273    nc = xmlNewNode(ns, BAD_CAST "DataInputs");
1274    int i;
1275    maps* mcursor=inputs;
1276    elements* scursor=NULL;
1277    while(mcursor!=NULL /*&& scursor!=NULL*/){
1278      scursor=getElements(serv->inputs,mcursor->name);
1279      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input");
1280      mcursor=mcursor->next;
1281    }
1282    xmlAddChild(n,nc);
1283   
1284#ifdef DEBUG
1285    fprintf(stderr,"printProcessResponse 1 177\n");
1286#endif
1287
1288    nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
1289    mcursor=outputs;
1290    scursor=NULL;
1291    while(mcursor!=NULL){
1292      scursor=getElements(serv->outputs,mcursor->name);
1293      printOutputDefinitions1(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
1294      mcursor=mcursor->next;
1295    }
1296    xmlAddChild(n,nc);
1297  }
1298#ifdef DEBUG
1299  fprintf(stderr,"printProcessResponse 1 190\n");
1300#endif
1301
1302  /**
1303   * Display the process output only when requested !
1304   */
1305  if(status==SERVICE_SUCCEEDED){
1306    nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
1307    maps* mcursor=outputs;
1308    elements* scursor=serv->outputs;
1309    while(mcursor!=NULL){
1310      scursor=getElements(serv->outputs,mcursor->name);
1311      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1312      mcursor=mcursor->next;
1313    }
1314    xmlAddChild(n,nc);
1315  }
1316#ifdef DEBUG
1317  fprintf(stderr,"printProcessResponse 1 202\n");
1318#endif
1319  xmlDocSetRootElement(doc, n);
1320  if(hasStoredExecuteResponse==true){
1321    /* We need to write the ExecuteResponse Document somewhere */
1322    FILE* output=fopen(stored_path,"w");
1323    xmlChar *xmlbuff;
1324    int buffersize;
1325    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
1326    fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
1327    xmlFree(xmlbuff);
1328    fclose(output);
1329  }
1330  printDocument(m,doc,pid);
1331
1332  xmlCleanupParser();
1333  zooXmlCleanupNs();
1334}
1335
1336
1337void printDocument(maps* m, xmlDocPtr doc,int pid){
1338  char *encoding=getEncoding(m);
1339  if(pid==getpid()){
1340    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1341  }
1342  fflush(stdout);
1343  xmlChar *xmlbuff;
1344  int buffersize;
1345  /*
1346   * Dump the document to a buffer and print it on stdout
1347   * for demonstration purposes.
1348   */
1349  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1350  printf("%s",xmlbuff);
1351  fflush(stdout);
1352  /*
1353   * Free associated memory.
1354   */
1355  xmlFree(xmlbuff);
1356  xmlFreeDoc(doc);
1357  xmlCleanupParser();
1358  zooXmlCleanupNs();
1359}
1360
1361void printOutputDefinitions1(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
1362  xmlNodePtr nc1;
1363  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1364  map *tmp=NULL; 
1365  if(e!=NULL && e->defaults!=NULL)
1366    tmp=e->defaults->content;
1367  else{
1368    /*
1369    dumpElements(e);
1370    */
1371    return;
1372  }
1373  while(tmp!=NULL){
1374    if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
1375       || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
1376       || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
1377       || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
1378    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1379    tmp=tmp->next;
1380  }
1381  tmp=getMap(e->defaults->content,"asReference");
1382  if(tmp==NULL)
1383    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1384
1385  tmp=e->content;
1386
1387  printDescription(nc1,ns_ows,m->name,e->content);
1388
1389  xmlAddChild(nc,nc1);
1390
1391}
1392
1393void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,map* m,const char* type){
1394  xmlNodePtr nc1,nc2,nc3;
1395  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1396  map *tmp=NULL; 
1397  if(e!=NULL && e->defaults!=NULL)
1398    tmp=e->defaults->content;
1399  else{
1400    /*
1401    dumpElements(e);
1402    */
1403    return;
1404  }
1405  while(tmp!=NULL){
1406    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1407    tmp=tmp->next;
1408  }
1409  tmp=getMap(e->defaults->content,"asReference");
1410  if(tmp==NULL)
1411    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1412
1413  tmp=e->content;
1414
1415  printDescription(nc1,ns_ows,m->name,e->content);
1416
1417  xmlAddChild(nc,nc1);
1418
1419}
1420
1421void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type){
1422  xmlNodePtr nc1,nc2,nc3;
1423  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1424  map *tmp=NULL;
1425  if(e!=NULL)
1426    tmp=e->content;
1427  else
1428    tmp=m->content;
1429#ifdef DEBUG
1430  dumpMap(tmp);
1431  dumpElements(e);
1432#endif
1433  nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
1434  if(e!=NULL)
1435    nc3=xmlNewText(BAD_CAST e->name);
1436  else
1437    nc3=xmlNewText(BAD_CAST m->name);
1438  xmlAddChild(nc2,nc3);
1439  xmlAddChild(nc1,nc2);
1440  xmlAddChild(nc,nc1);
1441  // Extract Title required to be first element in the ZCFG file !
1442  bool isTitle=true;
1443  if(e!=NULL)
1444    tmp=getMap(e->content,"Title");
1445  else
1446    tmp=getMap(m->content,"Title");
1447 
1448  if(tmp!=NULL){
1449    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1450    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1451    xmlAddChild(nc2,nc3); 
1452    xmlAddChild(nc1,nc2);
1453  }
1454
1455  if(e!=NULL)
1456    tmp=getMap(e->content,"Abstract");
1457  else
1458    tmp=getMap(m->content,"Abstract");
1459  if(tmp!=NULL){
1460    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1461    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1462    xmlAddChild(nc2,nc3); 
1463    xmlAddChild(nc1,nc2);
1464    xmlAddChild(nc,nc1);
1465  }
1466
1467  /**
1468   * IO type Reference or full Data ?
1469   */
1470#ifdef DEBUG
1471  fprintf(stderr,"FORMAT %s %s\n",e->format,e->format);
1472#endif
1473  map *tmpMap=getMap(m->content,"Reference");
1474  if(tmpMap==NULL){
1475    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
1476    if(e!=NULL){
1477      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
1478        nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
1479      else
1480        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
1481          nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
1482        else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
1483          nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
1484        else
1485          nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
1486    }
1487    else{
1488      map* tmpV=getMapFromMaps(m,"format","value");
1489      if(tmpV!=NULL)
1490        nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
1491      else
1492        nc3=xmlNewNode(ns_wps, BAD_CAST "LitteralData");
1493    } 
1494    tmp=m->content;
1495    while(tmp!=NULL){
1496      if(strcasecmp(tmp->name,"mimeType")==0 ||
1497         strcasecmp(tmp->name,"encoding")==0 ||
1498         strcasecmp(tmp->name,"schema")==0 ||
1499         strcasecmp(tmp->name,"datatype")==0 ||
1500         strcasecmp(tmp->name,"uom")==0)
1501        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1502      tmp=tmp->next;
1503      xmlAddChild(nc2,nc3);
1504    }
1505    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
1506      map* bb=getMap(m->content,"value");
1507      if(bb!=NULL){
1508        map* tmpRes=parseBoundingBox(bb->value);
1509        printBoundingBox(ns_ows,nc3,tmpRes);
1510        freeMap(&tmpRes);
1511        free(tmpRes);
1512      }
1513    }else{
1514      if(e!=NULL)
1515        tmp=getMap(e->defaults->content,"mimeType");
1516      else
1517        tmp=NULL;
1518      map* tmp1=getMap(m->content,"encoding");
1519      map* tmp2=getMap(m->content,"mimeType");
1520      map* toto=getMap(m->content,"value");
1521      if((tmp1!=NULL && strncmp(tmp1->value,"base64",6)==0)
1522         || (tmp2!=NULL && (strncmp(tmp2->value,"image/",6)==0 ||
1523                            (strncmp(tmp2->value,"application/",12)==0) &&
1524                            strncmp(tmp2->value,"application/json",16)!=0))) {
1525        map* rs=getMap(m->content,"size");
1526        bool isSized=true;
1527        if(rs==NULL){
1528          char tmp1[1024];
1529          sprintf(tmp1,"%d",strlen(toto->value));
1530          rs=createMap("z",tmp1);
1531          isSized=false;
1532        }
1533
1534        xmlAddChild(nc3,xmlNewText(BAD_CAST base64(toto->value, atoi(rs->value))));
1535        if(!isSized){
1536          freeMap(&rs);
1537          free(rs);
1538        }
1539      }
1540      else if(tmp!=NULL){
1541        if(strncmp(tmp->value,"text/js",4)==0 ||
1542           strncmp(tmp->value,"application/js",14)==0)
1543          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST toto->value,strlen(toto->value)));
1544        else
1545          xmlAddChild(nc3,xmlNewText(BAD_CAST toto->value));
1546        xmlAddChild(nc2,nc3);
1547      }
1548      else
1549        xmlAddChild(nc3,xmlNewText(BAD_CAST toto->value));
1550    }
1551  }
1552  else{
1553    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
1554    if(strcasecmp(type,"Output")==0)
1555      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
1556    else
1557      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
1558    tmp=m->content;
1559    while(tmp!=NULL){
1560      if(strcasecmp(tmp->name,"mimeType")==0 ||
1561         strcasecmp(tmp->name,"encoding")==0 ||
1562         strcasecmp(tmp->name,"schema")==0 ||
1563         strcasecmp(tmp->name,"datatype")==0 ||
1564         strcasecmp(tmp->name,"uom")==0)
1565        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1566      tmp=tmp->next;
1567      xmlAddChild(nc2,nc3);
1568    }
1569  }
1570
1571  xmlAddChild(nc1,nc2);
1572  xmlAddChild(nc,nc1);
1573
1574}
1575
1576void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
1577  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
1578  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
1579  xmlAddChild(root,nc2);
1580  map* tmp=amap;
1581  char *tmp2[2];
1582  tmp2[0]="Title";
1583  tmp2[1]="Abstract";
1584  int j=0;
1585  for(j=0;j<2;j++){
1586    map* tmp1=getMap(tmp,tmp2[j]);
1587    if(tmp1!=NULL){
1588      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
1589      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
1590      xmlAddChild(root,nc2);
1591    }
1592  }
1593}
1594
1595char* getEncoding(maps* m){
1596  if(m!=NULL){
1597    map* tmp=getMap(m->content,"encoding");
1598    if(tmp!=NULL){
1599      return tmp->value;
1600    }
1601    else
1602      return "UTF-8";
1603  }
1604  else
1605    return "UTF-8"; 
1606}
1607
1608char* getVersion(maps* m){
1609  if(m!=NULL){
1610    map* tmp=getMap(m->content,"version");
1611    if(tmp!=NULL){
1612      return tmp->value;
1613    }
1614    else
1615      return "1.0.0";
1616  }
1617  else
1618    return "1.0.0";
1619}
1620
1621void printExceptionReportResponse(maps* m,map* s){
1622  int buffersize;
1623  xmlDocPtr doc;
1624  xmlChar *xmlbuff;
1625  xmlNodePtr n;
1626
1627  doc = xmlNewDoc(BAD_CAST "1.0");
1628  maps* tmpMap=getMaps(m,"main");
1629  char *encoding=getEncoding(tmpMap);
1630  if(m!=NULL){
1631    map *tmpSid=getMapFromMaps(m,"lenv","sid");
1632    if(tmpSid!=NULL){
1633      if( getpid()==atoi(tmpSid->value) )
1634        printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1635    }
1636    else
1637      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1638  }else
1639    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1640  n=createExceptionReportNode(m,s,1);
1641  xmlDocSetRootElement(doc, n);
1642  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1643  printf("%s",xmlbuff);
1644  fflush(stdout);
1645  xmlFreeDoc(doc);
1646  xmlFree(xmlbuff);
1647  xmlCleanupParser();
1648  zooXmlCleanupNs();
1649}
1650
1651xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
1652 
1653  int buffersize;
1654  xmlChar *xmlbuff;
1655  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
1656  xmlNodePtr n,nc,nc1,nc2;
1657
1658  maps* tmpMap=getMaps(m,"main");
1659
1660  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
1661  ns=usedNs[nsid];
1662  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
1663
1664  if(use_ns==1){
1665    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
1666    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1667    ns_xsi=usedNs[xsiId];
1668    int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1669    ns_xlink=usedNs[xlinkId];
1670    xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd");
1671  }
1672  addLangAttr(n,m);
1673  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
1674 
1675  nc = xmlNewNode(ns, BAD_CAST "Exception");
1676
1677  map* tmp=getMap(s,"code");
1678  if(tmp!=NULL)
1679    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
1680  else
1681    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
1682
1683  tmp=getMap(s,"text");
1684  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
1685  nc2=NULL;
1686  if(tmp!=NULL){
1687    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
1688  }
1689  else{
1690    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
1691  }
1692  xmlAddChild(nc,nc1);
1693  xmlAddChild(n,nc);
1694  return n;
1695}
1696
1697
1698void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
1699                    map* request_inputs1,int cpid,maps* m,int res){
1700#ifdef DEBUG
1701  dumpMaps(request_inputs);
1702  dumpMaps(request_outputs);
1703  fprintf(stderr,"printProcessResponse\n");
1704#endif
1705  map* toto=getMap(request_inputs1,"RawDataOutput");
1706  int asRaw=0;
1707  if(toto!=NULL)
1708    asRaw=1;
1709 
1710  map *_tmp=getMapFromMaps(m,"lenv","cookie");
1711  if(_tmp!=NULL){
1712    printf("Set-Cookie: %s\r\n",_tmp->value);
1713    maps *tmpSess=getMaps(m,"senv");
1714    if(tmpSess!=NULL){
1715      char session_file_path[1024];
1716      map *tmpPath=getMapFromMaps(m,"main","sessPath");
1717      if(tmpPath==NULL)
1718        tmpPath=getMapFromMaps(m,"main","tmpPath");
1719      char *tmp1=strtok(_tmp->value,";");
1720      if(tmp1!=NULL)
1721        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(tmp1,"=")+1);
1722      else
1723        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(_tmp->value,"=")+1);
1724      FILE* file=fopen(session_file_path,"w");
1725      dumpMapsToFile(tmpSess,file);
1726      fclose(file);
1727    }
1728  }
1729  if(asRaw==0){
1730#ifdef DEBUG
1731    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
1732    dumpMaps(request_outputs);
1733#endif
1734    maps* tmpI=request_outputs;
1735    while(tmpI!=NULL){
1736      toto=getMap(tmpI->content,"asReference");
1737      if(toto!=NULL && strcasecmp(toto->value,"true")==0){
1738        elements* in=getElements(s->outputs,tmpI->name);
1739        char *format=NULL;
1740        if(in!=NULL){
1741          format=strdup(in->format);
1742        }else
1743          format=strdup("LiteralData");
1744        if(strcasecmp(format,"BoundingBoxData")==0){
1745          addToMap(tmpI->content,"extension","xml");
1746          addToMap(tmpI->content,"mimeType","text/xml");
1747          addToMap(tmpI->content,"encoding","UTF-8");
1748          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
1749        }
1750        map *ext=getMap(tmpI->content,"extension");
1751        map *tmp1=getMapFromMaps(m,"main","tmpPath");
1752        char *file_name;
1753        bool hasExt=true;
1754        if(ext==NULL){
1755          // We can fallback to a default list of supported formats using
1756          // mimeType information if present here. Maybe we can add more formats
1757          // here.
1758          // If mimeType was not found, we then set txt as the default extension.
1759          map* mtype=getMap(tmpI->content,"mimeType");
1760          if(mtype!=NULL){
1761            if(strcasecmp(mtype->value,"text/xml")==0)
1762              ext=createMap("extension","xml");
1763            else if(strcasecmp(mtype->value,"application/json")==0)
1764              ext=createMap("extension","js");
1765            else
1766              ext=createMap("extension","txt");
1767          }
1768          else
1769            ext=createMap("extension","txt");
1770          hasExt=false;
1771        }
1772        file_name=(char*)malloc((strlen(tmp1->value)+strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+13)*sizeof(char));
1773        sprintf(file_name,"%s/%s_%s_%i.%s",tmp1->value,s->name,tmpI->name,cpid+100000,ext->value);
1774        FILE *ofile=fopen(file_name,"w");
1775        if(ofile==NULL)
1776          fprintf(stderr,"Unable to create file on disk implying segfault ! \n");
1777        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
1778        map *tmp3=getMapFromMaps(m,"main","serverAddress");
1779        char *file_url;
1780        file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+13)*sizeof(char));
1781        sprintf(file_url,"%s/%s/%s_%s_%i.%s",tmp3->value,tmp2->value,s->name,tmpI->name,cpid+100000,ext->value);
1782        addToMap(tmpI->content,"Reference",file_url);
1783        if(hasExt!=true){
1784          freeMap(&ext);
1785          free(ext);
1786        }
1787        toto=getMap(tmpI->content,"value");
1788        if(strcasecmp(format,"BoundingBoxData")!=0){
1789          map* size=getMap(tmpI->content,"size");
1790          if(size!=NULL && toto!=NULL)
1791            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
1792          else
1793            if(toto!=NULL && toto->value!=NULL)
1794              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
1795        }else{
1796          printBoundingBoxDocument(m,tmpI,ofile);
1797        }
1798        free(format);
1799        fclose(ofile);
1800        free(file_name);
1801        free(file_url); 
1802      }
1803      tmpI=tmpI->next;
1804    }
1805    map *r_inputs=getMap(s->content,"serviceProvider");
1806#ifdef DEBUG
1807    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
1808    dumpMaps(m);
1809#endif
1810    printProcessResponse(m,request_inputs1,cpid,
1811                         s,r_inputs->value,res,
1812                         request_inputs,
1813                         request_outputs);
1814  }
1815  else
1816    if(res!=SERVICE_FAILED){
1817      /**
1818       * We get the requested output or fallback to the first one if the
1819       * requested one is not present in the resulting outputs maps.
1820       */
1821      maps* tmpI=NULL;
1822      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
1823      if(tmpIV!=NULL){
1824        tmpI=getMaps(request_outputs,tmpIV->value);
1825      }
1826      if(tmpI==NULL)
1827        tmpI=request_outputs;
1828      elements* e=getElements(s->outputs,tmpI->name);
1829      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
1830        printBoundingBoxDocument(m,tmpI,NULL);
1831      }else{
1832        toto=getMap(tmpI->content,"value");
1833        if(toto==NULL){
1834          char tmpMsg[1024];
1835          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
1836          map * errormap = createMap("text",tmpMsg);
1837          addToMap(errormap,"code", "InvalidParameterValue");
1838          printExceptionReportResponse(m,errormap);
1839          freeMap(&errormap);
1840          free(errormap);
1841          return;
1842        }
1843        char mime[1024];
1844        map* mi=getMap(tmpI->content,"mimeType");
1845#ifdef DEBUG
1846        fprintf(stderr,"SERVICE OUTPUTS\n");
1847        dumpMaps(request_outputs);
1848        fprintf(stderr,"SERVICE OUTPUTS\n");
1849#endif
1850        map* en=getMap(tmpI->content,"encoding");
1851        if(mi!=NULL && en!=NULL)
1852          sprintf(mime,
1853                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
1854                  mi->value,en->value);
1855        else
1856          if(mi!=NULL)
1857            sprintf(mime,
1858                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
1859                    mi->value);
1860          else
1861            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
1862        printf("%s",mime);
1863        if(mi!=NULL && strncmp(mi->value,"image",5)==0){
1864          map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
1865          fwrite(toto->value,atoi(rs->value),1,stdout);
1866        }
1867        else
1868          printf("%s",toto->value);
1869#ifdef DEBUG
1870        dumpMap(toto);
1871#endif
1872      }
1873    }else{
1874      char tmp[1024];
1875      map * errormap;
1876      map *lenv;
1877      lenv=getMapFromMaps(m,"lenv","message");
1878      if(lenv!=NULL)
1879        sprintf(tmp,_("Unable to run the Service. The message returned back by the Service was the following : %s"),lenv->value);
1880      else
1881        sprintf(tmp,_("Unable to run the Service. No more information was returned back by the Service."));
1882      errormap = createMap("text",tmp);     
1883      addToMap(errormap,"code", "InternalError");
1884      printExceptionReportResponse(m,errormap);
1885      freeMap(&errormap);
1886      free(errormap);
1887    }
1888}
1889
1890char *base64(const char *input, int length)
1891{
1892  BIO *bmem, *b64;
1893  BUF_MEM *bptr;
1894
1895  b64 = BIO_new(BIO_f_base64());
1896  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1897  bmem = BIO_new(BIO_s_mem());
1898  b64 = BIO_push(b64, bmem);
1899  BIO_write(b64, input, length);
1900  BIO_flush(b64);
1901  BIO_get_mem_ptr(b64, &bptr);
1902
1903  char *buff = (char *)malloc((bptr->length)*sizeof(char));
1904  memcpy(buff, bptr->data, bptr->length-1);
1905  buff[bptr->length-1] = 0;
1906
1907  BIO_free_all(b64);
1908
1909  return buff;
1910}
1911
1912char *base64d(const char *input, int length,int* red)
1913{
1914  BIO *b64, *bmem;
1915
1916  char *buffer = (char *)malloc(length);
1917  if(buffer){
1918    memset(buffer, 0, length);
1919    b64 = BIO_new(BIO_f_base64());
1920    if(b64){
1921      bmem = BIO_new_mem_buf((unsigned char*)input,length);
1922      bmem = BIO_push(b64, bmem);
1923      *red=BIO_read(bmem, buffer, length);
1924      buffer[length-1]=0;
1925      BIO_free_all(bmem);
1926    }
1927  }
1928  return buffer;
1929}
1930
1931void ensureDecodedBase64(maps **in){
1932  maps* cursor=*in;
1933  while(cursor!=NULL){
1934    map *tmp=getMap(cursor->content,"encoding");
1935    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
1936      tmp=getMap(cursor->content,"value");
1937      addToMap(cursor->content,"base64_value",tmp->value);
1938      int size=0;
1939      char *s=strdup(tmp->value);
1940      free(tmp->value);
1941      tmp->value=base64d(s,strlen(s),&size);
1942      free(s);
1943      char sizes[1024];
1944      sprintf(sizes,"%d",size);
1945      addToMap(cursor->content,"size",sizes);
1946    }
1947    cursor=cursor->next;
1948  }
1949}
1950
1951char* addDefaultValues(maps** out,elements* in,maps* m,int type){
1952  elements* tmpInputs=in;
1953  maps* out1=*out;
1954  while(tmpInputs!=NULL){
1955    maps *tmpMaps=getMaps(out1,tmpInputs->name);
1956    if(tmpMaps==NULL){
1957      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
1958      tmpMaps2->name=strdup(tmpInputs->name);
1959      tmpMaps2->content=NULL;
1960      tmpMaps2->next=NULL;
1961     
1962      if(type==0){
1963        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
1964        if(tmpMapMinO!=NULL)
1965          if(atoi(tmpMapMinO->value)>=1){
1966            freeMaps(&tmpMaps2);
1967            free(tmpMaps2);
1968            return tmpInputs->name;
1969          }
1970          else{
1971            if(tmpMaps2->content==NULL)
1972              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
1973            else
1974              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
1975          }
1976        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
1977        if(tmpMaxO!=NULL)
1978          if(tmpMaps2->content==NULL)
1979            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
1980          else
1981            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
1982      }
1983
1984      iotype* tmpIoType=tmpInputs->defaults;
1985      if(tmpIoType!=NULL){
1986        map* tmpm=tmpIoType->content;
1987        while(tmpm!=NULL){
1988          if(tmpMaps2->content==NULL)
1989            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
1990          else
1991            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
1992          tmpm=tmpm->next;
1993        }
1994      }
1995      addToMap(tmpMaps2->content,"inRequest","false");
1996      if(type==0){
1997        map *tmpMap=getMap(tmpMaps2->content,"value");
1998        if(tmpMap==NULL)
1999          addToMap(tmpMaps2->content,"value","NULL");
2000      }
2001      if(out1==NULL){
2002        *out=dupMaps(&tmpMaps2);
2003        out1=*out;
2004      }
2005      else
2006        addMapsToMaps(&out1,tmpMaps2);
2007      freeMap(&tmpMaps2->content);
2008      free(tmpMaps2->content);
2009      tmpMaps2->content=NULL;
2010      freeMaps(&tmpMaps2);
2011      free(tmpMaps2);
2012      tmpMaps2=NULL;
2013    }
2014    else{
2015      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2016                                             tmpMaps->content);
2017      if(type==0) {
2018        /**
2019         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2020         * content map.
2021         */
2022        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2023        if(tmpMap1!=NULL){
2024          if(tmpMaps->content==NULL)
2025            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2026          else
2027            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2028        }
2029        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2030        if(tmpMaxO!=NULL){
2031          if(tmpMaps->content==NULL)
2032            tmpMaps->content=createMap("maxOccurs",tmpMap1->value);
2033          else
2034            addToMap(tmpMaps->content,"maxOccurs",tmpMap1->value);
2035        }
2036        /**
2037         * Parsing BoundingBoxData, fill the following map and then add it to
2038         * the content map of the Input maps:
2039         * lowerCorner, upperCorner, srs and dimensions
2040         * cf. parseBoundingBox
2041         */
2042        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2043          maps* tmpI=getMaps(*out,tmpInputs->name);
2044          if(tmpI!=NULL){
2045            map* tmpV=getMap(tmpI->content,"value");
2046            if(tmpV!=NULL){
2047              char *tmpVS=strdup(tmpV->value);
2048              map* tmp=parseBoundingBox(tmpVS);
2049              free(tmpVS);
2050              map* tmpC=tmp;
2051              while(tmpC!=NULL){
2052                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2053                tmpC=tmpC->next;
2054              }
2055              freeMap(&tmp);
2056              free(tmp);
2057            }
2058          }
2059        }
2060      }
2061
2062      if(tmpIoType!=NULL){
2063        map* tmpContent=tmpIoType->content;
2064        map* cval=NULL;
2065
2066        while(tmpContent!=NULL){
2067          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2068#ifdef DEBUG
2069            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2070#endif
2071            if(tmpMaps->content==NULL)
2072              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2073            else
2074              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2075          }
2076          tmpContent=tmpContent->next;
2077        }
2078      }
2079      if(tmpMaps->content==NULL)
2080        tmpMaps->content=createMap("inRequest","true");
2081      else
2082        addToMap(tmpMaps->content,"inRequest","true");
2083    }
2084    tmpInputs=tmpInputs->next;
2085  }
2086  return "";
2087}
2088
2089/**
2090 * parseBoundingBox : parse a BoundingBox string
2091 *
2092 * OGC 06-121r3 : 10.2 Bounding box
2093 *
2094 * value is provided as : lowerCorner,upperCorner,crs,dimension
2095 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2096 *
2097 * Need to create a map to store boundingbox informations :
2098 *  - lowerCorner : double,double (minimum within this bounding box)
2099 *  - upperCorner : double,double (maximum within this bounding box)
2100 *  - crs : URI (Reference to definition of the CRS)
2101 *  - dimensions : int
2102 *
2103 * Note : support only 2D bounding box.
2104 */
2105map* parseBoundingBox(const char* value){
2106  map *res=NULL;
2107  if(value!=NULL){
2108    char *cv,*cvp;
2109    cv=strtok_r((char*) value,",",&cvp);
2110    int cnt=0;
2111    int icnt=0;
2112    char *currentValue=NULL;
2113    while(cv){
2114      if(cnt<2)
2115        if(currentValue!=NULL){
2116          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
2117          sprintf(finalValue,"%s%s",currentValue,cv);
2118          switch(cnt){
2119          case 0:
2120            res=createMap("lowerCorner",finalValue);
2121            break;
2122          case 1:
2123            addToMap(res,"upperCorner",finalValue);
2124            icnt=-1;
2125            break;
2126          }
2127          cnt++;
2128          free(currentValue);
2129          currentValue=NULL;
2130          free(finalValue);
2131        }
2132        else{
2133          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
2134          sprintf(currentValue,"%s ",cv);
2135        }
2136      else
2137        if(cnt==2){
2138          addToMap(res,"crs",cv);
2139          cnt++;
2140        }
2141        else
2142          addToMap(res,"dimensions",cv);
2143      icnt++;
2144      cv=strtok_r(NULL,",",&cvp);
2145    }
2146  }
2147  return res;
2148}
2149
2150/**
2151 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2152 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2153 * Lower/UpperCorner nodes to a pre-existing XML node.
2154 */
2155void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2156
2157  xmlNodePtr bb,lw,uc;
2158
2159  map* tmp=getMap(boundingbox,"value");
2160
2161  tmp=getMap(boundingbox,"lowerCorner");
2162  if(tmp!=NULL){
2163    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2164    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2165  }
2166
2167  tmp=getMap(boundingbox,"upperCorner");
2168  if(tmp!=NULL){
2169    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2170    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2171  }
2172
2173  tmp=getMap(boundingbox,"crs");
2174  if(tmp!=NULL)
2175    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2176
2177  tmp=getMap(boundingbox,"dimensions");
2178  if(tmp!=NULL)
2179    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2180
2181  xmlAddChild(n,lw);
2182  xmlAddChild(n,uc);
2183
2184}
2185
2186void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2187  if(file==NULL)
2188    rewind(stdout);
2189  xmlNodePtr n;
2190  xmlDocPtr doc;
2191  xmlNsPtr ns_ows,ns_xsi;
2192  xmlChar *xmlbuff;
2193  int buffersize;
2194  char *encoding=getEncoding(m);
2195  map *tmp;
2196  if(file==NULL){
2197    int pid=0;
2198    tmp=getMapFromMaps(m,"lenv","sid");
2199    if(tmp!=NULL)
2200      pid=atoi(tmp->value);
2201    if(pid==getpid()){
2202      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2203    }
2204    fflush(stdout);
2205  }
2206
2207  doc = xmlNewDoc(BAD_CAST "1.0");
2208  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2209  ns_ows=usedNs[owsId];
2210  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2211  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
2212  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2213  ns_xsi=usedNs[xsiId];
2214  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2215  map *tmp1=getMap(boundingbox->content,"value");
2216  tmp=parseBoundingBox(tmp1->value);
2217  printBoundingBox(ns_ows,n,tmp);
2218  xmlDocSetRootElement(doc, n);
2219
2220  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2221  if(file==NULL)
2222    printf("%s",xmlbuff);
2223  else{
2224    fprintf(file,"%s",xmlbuff);
2225  }
2226
2227  if(tmp!=NULL){
2228    freeMap(&tmp);
2229    free(tmp);
2230  }
2231  xmlFree(xmlbuff);
2232  xmlFreeDoc(doc);
2233  xmlCleanupParser();
2234  zooXmlCleanupNs();
2235 
2236}
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