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

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

Small fix for reference input download and for setting value to input only.

File size: 58.6 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        xmlAddChild(nc3,xmlNewText(BAD_CAST base64((const unsigned char*)toto->value,atoi(rs->value))));
1403        if(!isSized){
1404          freeMap(&rs);
1405          free(rs);
1406        }
1407      }
1408      else if(tmp!=NULL){
1409        if(strncmp(tmp->value,"text/js",4)==0 ||
1410           strncmp(tmp->value,"application/js",14)==0)
1411          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST toto->value,strlen(toto->value)));
1412        else
1413          xmlAddChild(nc3,xmlNewText(BAD_CAST toto->value));
1414        xmlAddChild(nc2,nc3);
1415      }
1416      else
1417        xmlAddChild(nc3,xmlNewText(BAD_CAST toto->value));
1418    }
1419  }
1420  else{
1421    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
1422    if(strcasecmp(type,"Output")==0)
1423      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
1424    else
1425      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
1426    tmp=m->content;
1427    while(tmp!=NULL){
1428      if(strcasecmp(tmp->name,"mimeType")==0 ||
1429         strcasecmp(tmp->name,"encoding")==0 ||
1430         strcasecmp(tmp->name,"schema")==0 ||
1431         strcasecmp(tmp->name,"datatype")==0 ||
1432         strcasecmp(tmp->name,"uom")==0)
1433        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1434      tmp=tmp->next;
1435      xmlAddChild(nc2,nc3);
1436    }
1437  }
1438
1439  xmlAddChild(nc1,nc2);
1440  xmlAddChild(nc,nc1);
1441
1442}
1443
1444void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,char* identifier,map* amap){
1445  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
1446  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
1447  xmlAddChild(root,nc2);
1448  map* tmp=amap;
1449  char *tmp2[2];
1450  tmp2[0]="Title";
1451  tmp2[1]="Abstract";
1452  int j=0;
1453  for(j=0;j<2;j++){
1454    map* tmp1=getMap(tmp,tmp2[j]);
1455    if(tmp1!=NULL){
1456      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
1457      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
1458      xmlAddChild(root,nc2);
1459    }
1460  }
1461}
1462
1463char* getEncoding(maps* m){
1464  if(m!=NULL){
1465    map* tmp=getMap(m->content,"encoding");
1466    if(tmp!=NULL){
1467      return tmp->value;
1468    }
1469    else
1470      return "UTF-8";
1471  }
1472  else
1473    return "UTF-8"; 
1474}
1475
1476char* getVersion(maps* m){
1477  if(m!=NULL){
1478    map* tmp=getMap(m->content,"version");
1479    if(tmp!=NULL){
1480      return tmp->value;
1481    }
1482    else
1483      return "1.0.0";
1484  }
1485  else
1486    return "1.0.0";
1487}
1488
1489void printExceptionReportResponse(maps* m,map* s){
1490  int buffersize;
1491  xmlDocPtr doc;
1492  xmlChar *xmlbuff;
1493  xmlNodePtr n;
1494
1495  doc = xmlNewDoc(BAD_CAST "1.0");
1496  maps* tmpMap=getMaps(m,"main");
1497  char *encoding=getEncoding(tmpMap);
1498  if(m!=NULL){
1499    map *tmpSid=getMapFromMaps(m,"lenv","sid");
1500    if(tmpSid!=NULL){
1501      if( getpid()==atoi(tmpSid->value) )
1502        printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1503    }
1504    else
1505      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1506  }else
1507    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1508  n=createExceptionReportNode(m,s,1);
1509  xmlDocSetRootElement(doc, n);
1510  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1511  printf("%s",xmlbuff);
1512  fflush(stdout);
1513  xmlFreeDoc(doc);
1514  xmlFree(xmlbuff);
1515  xmlCleanupParser();
1516  zooXmlCleanupNs();
1517}
1518
1519xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
1520 
1521  int buffersize;
1522  xmlChar *xmlbuff;
1523  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
1524  xmlNodePtr n,nc,nc1,nc2;
1525
1526  maps* tmpMap=getMaps(m,"main");
1527
1528  int nsid=zooXmlAddNs(NULL,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
1529  ns=usedNs[nsid];
1530  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
1531
1532  if(use_ns==1){
1533    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
1534    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1535    ns_xsi=usedNs[xsiId];
1536    int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1537    ns_xlink=usedNs[xlinkId];
1538    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");
1539  }
1540  addLangAttr(n,m);
1541  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
1542 
1543  nc = xmlNewNode(ns, BAD_CAST "Exception");
1544
1545  map* tmp=getMap(s,"code");
1546  if(tmp!=NULL)
1547    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
1548  else
1549    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
1550
1551  tmp=getMap(s,"text");
1552  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
1553  nc2=NULL;
1554  if(tmp!=NULL){
1555    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
1556  }
1557  else{
1558    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
1559  }
1560  xmlAddChild(nc,nc1);
1561  xmlAddChild(n,nc);
1562  return n;
1563}
1564
1565
1566void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
1567                    map* request_inputs1,int cpid,maps* m,int res){
1568#ifdef DEBUG
1569  dumpMaps(request_inputs);
1570  dumpMaps(request_outputs);
1571  fprintf(stderr,"printProcessResponse\n");
1572#endif
1573  map* toto=getMap(request_inputs1,"RawDataOutput");
1574  int asRaw=0;
1575  if(toto!=NULL)
1576    asRaw=1;
1577 
1578  map *_tmp=getMapFromMaps(m,"lenv","cookie");
1579  if(_tmp!=NULL){
1580    printf("Set-Cookie: %s\r\n",_tmp->value);
1581    maps *tmpSess=getMaps(m,"senv");
1582    if(tmpSess!=NULL){
1583      char session_file_path[1024];
1584      map *tmpPath=getMapFromMaps(m,"main","sessPath");
1585      if(tmpPath==NULL)
1586        tmpPath=getMapFromMaps(m,"main","tmpPath");
1587      char *tmp1=strtok(_tmp->value,";");
1588      if(tmp1!=NULL)
1589        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(tmp1,"=")+1);
1590      else
1591        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(_tmp->value,"=")+1);
1592      FILE* file=fopen(session_file_path,"w");
1593      dumpMapsToFile(tmpSess,file);
1594      fclose(file);
1595    }
1596  }
1597  if(asRaw==0){
1598#ifdef DEBUG
1599    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
1600    dumpMaps(request_outputs);
1601#endif
1602    maps* tmpI=request_outputs;
1603    while(tmpI!=NULL){
1604      toto=getMap(tmpI->content,"asReference");
1605      if(toto!=NULL && strcasecmp(toto->value,"true")==0){
1606        elements* in=getElements(s->outputs,tmpI->name);
1607        char *format=NULL;
1608        if(in!=NULL){
1609          format=strdup(in->format);
1610        }else
1611          format=strdup("LiteralData");
1612        if(strcasecmp(format,"BoundingBoxData")==0){
1613          addToMap(tmpI->content,"extension","xml");
1614          addToMap(tmpI->content,"mimeType","text/xml");
1615          addToMap(tmpI->content,"encoding","UTF-8");
1616          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
1617        }
1618        map *ext=getMap(tmpI->content,"extension");
1619        map *tmp1=getMapFromMaps(m,"main","tmpPath");
1620        char *file_name;
1621        bool hasExt=true;
1622        if(ext==NULL){
1623          // We can fallback to a default list of supported formats using
1624          // mimeType information if present here. Maybe we can add more formats
1625          // here.
1626          // If mimeType was not found, we then set txt as the default extension.
1627          map* mtype=getMap(tmpI->content,"mimeType");
1628          if(mtype!=NULL){
1629            if(strcasecmp(mtype->value,"text/xml")==0)
1630              ext=createMap("extension","xml");
1631            else if(strcasecmp(mtype->value,"application/json")==0)
1632              ext=createMap("extension","js");
1633            else
1634              ext=createMap("extension","txt");
1635          }
1636          else
1637            ext=createMap("extension","txt");
1638          hasExt=false;
1639        }
1640        file_name=(char*)malloc((strlen(tmp1->value)+strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+13)*sizeof(char));
1641        sprintf(file_name,"%s/%s_%s_%i.%s",tmp1->value,s->name,tmpI->name,cpid+100000,ext->value);
1642        FILE *ofile=fopen(file_name,"w");
1643        if(ofile==NULL)
1644          fprintf(stderr,"Unable to create file on disk implying segfault ! \n");
1645        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
1646        map *tmp3=getMapFromMaps(m,"main","serverAddress");
1647        char *file_url;
1648        file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+13)*sizeof(char));
1649        sprintf(file_url,"%s/%s/%s_%s_%i.%s",tmp3->value,tmp2->value,s->name,tmpI->name,cpid+100000,ext->value);
1650        addToMap(tmpI->content,"Reference",file_url);
1651        if(hasExt!=true){
1652          freeMap(&ext);
1653          free(ext);
1654        }
1655        toto=getMap(tmpI->content,"value");
1656        if(strcasecmp(format,"BoundingBoxData")!=0){
1657          map* size=getMap(tmpI->content,"size");
1658          if(size!=NULL && toto!=NULL)
1659            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
1660          else
1661            if(toto!=NULL && toto->value!=NULL)
1662              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
1663        }else{
1664          printBoundingBoxDocument(m,tmpI,ofile);
1665        }
1666        free(format);
1667        fclose(ofile);
1668        free(file_name);
1669        free(file_url); 
1670      }
1671      tmpI=tmpI->next;
1672    }
1673    map *r_inputs=getMap(s->content,"serviceProvider");
1674#ifdef DEBUG
1675    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
1676    dumpMaps(m);
1677#endif
1678    printProcessResponse(m,request_inputs1,cpid,
1679                         s,r_inputs->value,res,
1680                         request_inputs,
1681                         request_outputs);
1682  }
1683  else
1684    if(res!=SERVICE_FAILED){
1685      /**
1686       * We get the requested output or fallback to the first one if the
1687       * requested one is not present in the resulting outputs maps.
1688       */
1689      maps* tmpI=NULL;
1690      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
1691      if(tmpIV!=NULL){
1692        tmpI=getMaps(request_outputs,tmpIV->value);
1693      }
1694      if(tmpI==NULL)
1695        tmpI=request_outputs;
1696      elements* e=getElements(s->outputs,tmpI->name);
1697      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
1698        printBoundingBoxDocument(m,tmpI,NULL);
1699      }else{
1700        toto=getMap(tmpI->content,"value");
1701        if(toto==NULL){
1702          char tmpMsg[1024];
1703          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
1704          map * errormap = createMap("text",tmpMsg);
1705          addToMap(errormap,"code", "InvalidParameterValue");
1706          printExceptionReportResponse(m,errormap);
1707          freeMap(&errormap);
1708          free(errormap);
1709          return 1;
1710        }
1711        char mime[1024];
1712        map* mi=getMap(tmpI->content,"mimeType");
1713#ifdef DEBUG
1714        fprintf(stderr,"SERVICE OUTPUTS\n");
1715        dumpMaps(request_outputs);
1716        fprintf(stderr,"SERVICE OUTPUTS\n");
1717#endif
1718        map* en=getMap(tmpI->content,"encoding");
1719        if(mi!=NULL && en!=NULL)
1720          sprintf(mime,
1721                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
1722                  mi->value,en->value);
1723        else
1724          if(mi!=NULL)
1725            sprintf(mime,
1726                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
1727                    mi->value);
1728          else
1729            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
1730        printf("%s",mime);
1731        if(mi!=NULL && strncmp(mi->value,"image",5)==0){
1732          map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
1733          fwrite(toto->value,atoi(rs->value),1,stdout);
1734        }
1735        else
1736          printf("%s",toto->value);
1737#ifdef DEBUG
1738        dumpMap(toto);
1739#endif
1740      }
1741    }else{
1742      char tmp[1024];
1743      map * errormap;
1744      map *lenv;
1745      lenv=getMapFromMaps(m,"lenv","message");
1746      if(lenv!=NULL)
1747        sprintf(tmp,_("Unable to run the Service. The message returned back by the Service was the following : %s"),lenv->value);
1748      else
1749        sprintf(tmp,_("Unable to run the Service. No more information was returned back by the Service."));
1750      errormap = createMap("text",tmp);     
1751      addToMap(errormap,"code", "InternalError");
1752      printExceptionReportResponse(m,errormap);
1753      freeMap(&errormap);
1754      free(errormap);
1755    }
1756}
1757
1758char *base64(const unsigned char *input, int length)
1759{
1760  BIO *bmem, *b64;
1761  BUF_MEM *bptr;
1762
1763  b64 = BIO_new(BIO_f_base64());
1764  bmem = BIO_new(BIO_s_mem());
1765  b64 = BIO_push(b64, bmem);
1766  BIO_write(b64, input, length);
1767  BIO_flush(b64);
1768  BIO_get_mem_ptr(b64, &bptr);
1769
1770  char *buff = (char *)malloc(bptr->length);
1771  memcpy(buff, bptr->data, bptr->length-1);
1772  buff[bptr->length-1] = 0;
1773
1774  BIO_free_all(b64);
1775
1776  return buff;
1777}
1778
1779char *base64d(unsigned char *input, int length,int* red)
1780{
1781  BIO *b64, *bmem;
1782
1783  char *buffer = (char *)malloc(length);
1784  memset(buffer, 0, length);
1785
1786  b64 = BIO_new(BIO_f_base64());
1787  bmem = BIO_new_mem_buf(input, length);
1788  bmem = BIO_push(b64, bmem);
1789
1790  *red=BIO_read(bmem, buffer, length);
1791
1792  BIO_free_all(bmem);
1793
1794  return buffer;
1795}
1796
1797void ensureDecodedBase64(maps **in){
1798  maps* cursor=*in;
1799  while(cursor!=NULL){
1800    map *tmp=getMap(cursor->content,"encoding");
1801    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
1802      tmp=getMap(cursor->content,"value");
1803      addToMap(cursor->content,"base64_value",tmp->value);
1804      char *s=strdup(tmp->value);
1805      free(tmp->value);
1806      int size=0;
1807      tmp->value=base64d(s,strlen(s),&size);
1808      char sizes[1024];
1809      sprintf(sizes,"%d",size);
1810      addToMap(cursor->content,"size",sizes);
1811    }
1812    cursor=cursor->next;
1813  }
1814}
1815
1816char* addDefaultValues(maps** out,elements* in,maps* m,int type){
1817  elements* tmpInputs=in;
1818  maps* out1=*out;
1819  while(tmpInputs!=NULL){
1820    maps *tmpMaps=getMaps(out1,tmpInputs->name);
1821    if(tmpMaps==NULL){
1822      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
1823      tmpMaps2->name=strdup(tmpInputs->name);
1824      tmpMaps2->content=NULL;
1825      tmpMaps2->next=NULL;
1826     
1827      if(type==0){
1828        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
1829        if(tmpMapMinO!=NULL)
1830          if(atoi(tmpMapMinO->value)>=1){
1831            freeMaps(&tmpMaps2);
1832            free(tmpMaps2);
1833            return tmpInputs->name;
1834          }
1835          else{
1836            if(tmpMaps2->content==NULL)
1837              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
1838            else
1839              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
1840          }
1841        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
1842        if(tmpMaxO!=NULL)
1843          if(tmpMaps2->content==NULL)
1844            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
1845          else
1846            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
1847      }
1848
1849      iotype* tmpIoType=tmpInputs->defaults;
1850      if(tmpIoType!=NULL){
1851        map* tmpm=tmpIoType->content;
1852        while(tmpm!=NULL){
1853          if(tmpMaps2->content==NULL)
1854            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
1855          else
1856            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
1857          tmpm=tmpm->next;
1858        }
1859      }
1860      addToMap(tmpMaps2->content,"inRequest","false");
1861      if(type==0){
1862        map *tmpMap=getMap(tmpMaps2->content,"value");
1863        if(tmpMap==NULL)
1864          addToMap(tmpMaps2->content,"value","NULL");
1865      }
1866      if(out1==NULL){
1867        *out=dupMaps(&tmpMaps2);
1868        out1=*out;
1869      }
1870      else
1871        addMapsToMaps(&out1,tmpMaps2);
1872      freeMap(&tmpMaps2->content);
1873      free(tmpMaps2->content);
1874      tmpMaps2->content=NULL;
1875      freeMaps(&tmpMaps2);
1876      free(tmpMaps2);
1877      tmpMaps2=NULL;
1878    }
1879    else{
1880      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
1881                                             tmpMaps->content);
1882      if(type==0) {
1883        /**
1884         * In case of an Input maps, then add the minOccurs and maxOccurs to the
1885         * content map.
1886         */
1887        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
1888        if(tmpMap1!=NULL){
1889          if(tmpMaps->content==NULL)
1890            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
1891          else
1892            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
1893        }
1894        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
1895        if(tmpMaxO!=NULL){
1896          if(tmpMaps->content==NULL)
1897            tmpMaps->content=createMap("maxOccurs",tmpMap1->value);
1898          else
1899            addToMap(tmpMaps->content,"maxOccurs",tmpMap1->value);
1900        }
1901        /**
1902         * Parsing BoundingBoxData, fill the following map and then add it to
1903         * the content map of the Input maps:
1904         * lowerCorner, upperCorner, srs and dimensions
1905         * cf. parseBoundingBox
1906         */
1907        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
1908          maps* tmpI=getMaps(*out,tmpInputs->name);
1909          if(tmpI!=NULL){
1910            map* tmpV=getMap(tmpI->content,"value");
1911            if(tmpV!=NULL){
1912              char *tmpVS=strdup(tmpV->value);
1913              map* tmp=parseBoundingBox(tmpVS);
1914              free(tmpVS);
1915              map* tmpC=tmp;
1916              while(tmpC!=NULL){
1917                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
1918                tmpC=tmpC->next;
1919              }
1920              freeMap(&tmp);
1921              free(tmp);
1922            }
1923          }
1924        }
1925      }
1926
1927      if(tmpIoType!=NULL){
1928        map* tmpContent=tmpIoType->content;
1929        map* cval=NULL;
1930
1931        while(tmpContent!=NULL){
1932          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
1933#ifdef DEBUG
1934            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
1935#endif
1936            if(tmpMaps->content==NULL)
1937              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
1938            else
1939              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
1940          }
1941          tmpContent=tmpContent->next;
1942        }
1943      }
1944      if(tmpMaps->content==NULL)
1945        tmpMaps->content=createMap("inRequest","true");
1946      else
1947        addToMap(tmpMaps->content,"inRequest","true");
1948    }
1949    tmpInputs=tmpInputs->next;
1950  }
1951  return "";
1952}
1953
1954/**
1955 * parseBoundingBox : parse a BoundingBox string
1956 *
1957 * OGC 06-121r3 : 10.2 Bounding box
1958 *
1959 * value is provided as : lowerCorner,upperCorner,crs,dimension
1960 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
1961 *
1962 * Need to create a map to store boundingbox informations :
1963 *  - lowerCorner : double,double (minimum within this bounding box)
1964 *  - upperCorner : double,double (maximum within this bounding box)
1965 *  - crs : URI (Reference to definition of the CRS)
1966 *  - dimensions : int
1967 *
1968 * Note : support only 2D bounding box.
1969 */
1970map* parseBoundingBox(char* value){
1971  map *res=NULL;
1972  if(value!=NULL){
1973    char *cv,*cvp;
1974    cv=strtok_r(value,",",&cvp);
1975    int cnt=0;
1976    int icnt=0;
1977    char *currentValue=NULL;
1978    while(cv){
1979      if(cnt<2)
1980        if(currentValue!=NULL){
1981          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
1982          sprintf(finalValue,"%s%s",currentValue,cv);
1983          switch(cnt){
1984          case 0:
1985            res=createMap("lowerCorner",finalValue);
1986            break;
1987          case 1:
1988            addToMap(res,"upperCorner",finalValue);
1989            icnt=-1;
1990            break;
1991          }
1992          cnt++;
1993          free(currentValue);
1994          currentValue=NULL;
1995          free(finalValue);
1996        }
1997        else{
1998          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
1999          sprintf(currentValue,"%s ",cv);
2000        }
2001      else
2002        if(cnt==2){
2003          addToMap(res,"crs",cv);
2004          cnt++;
2005        }
2006        else
2007          addToMap(res,"dimensions",cv);
2008      icnt++;
2009      cv=strtok_r(NULL,",",&cvp);
2010    }
2011  }
2012  return res;
2013}
2014
2015/**
2016 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2017 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2018 * Lower/UpperCorner nodes to a pre-existing XML node.
2019 */
2020void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2021
2022  xmlNodePtr bb,lw,uc;
2023
2024  map* tmp=getMap(boundingbox,"value");
2025
2026  tmp=getMap(boundingbox,"lowerCorner");
2027  if(tmp!=NULL){
2028    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2029    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2030  }
2031
2032  tmp=getMap(boundingbox,"upperCorner");
2033  if(tmp!=NULL){
2034    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2035    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2036  }
2037
2038  tmp=getMap(boundingbox,"crs");
2039  if(tmp!=NULL)
2040    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2041
2042  tmp=getMap(boundingbox,"dimensions");
2043  if(tmp!=NULL)
2044    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2045
2046  xmlAddChild(n,lw);
2047  xmlAddChild(n,uc);
2048
2049}
2050
2051void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2052  if(file==NULL)
2053    rewind(stdout);
2054  xmlNodePtr n;
2055  xmlDocPtr doc;
2056  xmlNsPtr ns_ows,ns_xsi;
2057  xmlChar *xmlbuff;
2058  int buffersize;
2059  char *encoding=getEncoding(m);
2060  map *tmp;
2061  if(file==NULL){
2062    int pid=0;
2063    tmp=getMapFromMaps(m,"lenv","sid");
2064    if(tmp!=NULL)
2065      pid=atoi(tmp->value);
2066    if(pid==getpid()){
2067      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2068    }
2069    fflush(stdout);
2070  }
2071
2072  doc = xmlNewDoc(BAD_CAST "1.0");
2073  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2074  ns_ows=usedNs[owsId];
2075  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2076  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1","ows");
2077  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2078  ns_xsi=usedNs[xsiId];
2079  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");
2080  map *tmp1=getMap(boundingbox->content,"value");
2081  tmp=parseBoundingBox(tmp1->value);
2082  printBoundingBox(ns_ows,n,tmp);
2083  xmlDocSetRootElement(doc, n);
2084
2085  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2086  if(file==NULL)
2087    printf((char *) xmlbuff);
2088  else{
2089    fprintf(file,"%s",xmlbuff);
2090  }
2091
2092  if(tmp!=NULL){
2093    freeMap(&tmp);
2094    free(tmp);
2095  }
2096  xmlFree(xmlbuff);
2097  xmlFreeDoc(doc);
2098  xmlCleanupParser();
2099  zooXmlCleanupNs();
2100 
2101}
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