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

Last change on this file since 279 was 279, checked in by djay, 13 years ago

Add KML output MimeType? to avoid base64 encoding.

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