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

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

Small fix for embedded base64 string in XML request (QGIS WPS Client for instance).

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