1 /*
2   Copyright (c) <2007-2012> <Barbara Philippot - Olivier Courtin>
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy
5   of this software and associated documentation files (the "Software"), to deal
6   in the Software without restriction, including without limitation the rights
7   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   copies of the Software, and to permit persons to whom the Software is
9   furnished to do so, subject to the following conditions:
10 
11   The above copyright notice and this permission notice shall be included in
12   all copies or substantial portions of the Software.
13 
14   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20   IN THE SOFTWARE.
21 */
22 
23 
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <assert.h>
27 #include <limits.h>
28 #include <string.h>
29 
30 #include "ows.h"
31 
32 
33 /*
34  * Initialize an ows layer structure
35  */
ows_layer_list_init()36 ows_layer_list *ows_layer_list_init()
37 {
38   ows_layer_list *ll;
39 
40   ll = malloc(sizeof(ows_layer_list));
41   assert(ll);
42 
43   ll->first = NULL;
44   ll->last = NULL;
45   return ll;
46 }
47 
48 
49 /*
50  * Free an ows layer structure
51  */
ows_layer_list_free(ows_layer_list * ll)52 void ows_layer_list_free(ows_layer_list * ll)
53 {
54   assert(ll);
55 
56   while (ll->first) ows_layer_node_free(ll, ll->first);
57   ll->last = NULL;
58   free(ll);
59   ll = NULL;
60 }
61 
62 
63 /*
64  * Retrieve a Layer from a layer list or NULL if not found
65  */
ows_layer_get(const ows_layer_list * ll,const buffer * name)66 ows_layer * ows_layer_get(const ows_layer_list * ll, const buffer * name)
67 {
68   ows_layer_node *ln;
69 
70   assert(ll);
71   assert(name);
72 
73   for (ln = ll->first; ln ; ln = ln->next)
74     if (ln->layer->name && !strcmp(ln->layer->name->buf, name->buf))
75       return ln->layer;
76 
77   return (ows_layer *) NULL;
78 }
79 
80 
81 /*
82  * Check if a layer matchs an existing table in PostGIS
83  */
ows_layer_match_table(const ows * o,const buffer * name)84 bool ows_layer_match_table(const ows * o, const buffer * name)
85 {
86   ows_layer_node *ln;
87 
88   assert(o);
89   assert(name);
90 
91   for (ln = o->layers->first; ln ; ln = ln->next)
92     if (ln->layer->name && !strcmp(ln->layer->name->buf, name->buf)) {
93       if (ln->layer->storage) return true;
94       else return false;
95     }
96 
97   return false;
98 }
99 
100 
101 /*
102  * Retrieve a list of layer name who have a storage object
103  * (concrete layer so)
104  */
ows_layer_list_having_storage(const ows_layer_list * ll)105 list * ows_layer_list_having_storage(const ows_layer_list * ll)
106 {
107   ows_layer_node *ln;
108   list *l;
109 
110   assert(ll);
111 
112   l = list_init();
113 
114   for (ln = ll->first; ln ; ln = ln->next)
115     if (ln->layer->storage)
116       list_add_by_copy(l, ln->layer->name);
117 
118   return l;
119 }
120 
121 
122 /*
123  * Check if all layers are retrievable (defined in configuration file)
124  */
ows_layer_list_retrievable(const ows_layer_list * ll)125 bool ows_layer_list_retrievable(const ows_layer_list * ll)
126 {
127   ows_layer_node *ln;
128 
129   assert(ll);
130 
131   for (ln = ll->first; ln ; ln = ln->next)
132     if (!ln->layer->retrievable) return false;
133 
134   return true;
135 }
136 
137 
138 /*
139  * Check if a layer is retrievable (defined in configuration file)
140  */
ows_layer_retrievable(const ows_layer_list * ll,const buffer * name)141 bool ows_layer_retrievable(const ows_layer_list * ll, const buffer * name)
142 {
143   ows_layer_node *ln;
144 
145   assert(ll);
146   assert(name);
147 
148   for (ln = ll->first; ln ; ln = ln->next)
149     if (ln->layer->name && !strcmp(ln->layer->name->buf, name->buf))
150       return ln->layer->retrievable;
151 
152   return false;
153 }
154 
155 
156 /*
157  * Check if all layers are writable (defined in file conf)
158  */
ows_layer_list_writable(const ows_layer_list * ll)159 bool ows_layer_list_writable(const ows_layer_list * ll)
160 {
161   ows_layer_node *ln;
162 
163   assert(ll);
164 
165   for (ln = ll->first; ln ; ln = ln->next)
166     if (!ln->layer->writable) return false;
167 
168   return true;
169 }
170 
171 
172 /*
173  * Check if a layer is writable (defined in file conf)
174  */
ows_layer_writable(const ows_layer_list * ll,const buffer * name)175 bool ows_layer_writable(const ows_layer_list * ll, const buffer * name)
176 {
177   ows_layer_node *ln;
178 
179   assert(ll);
180   assert(name);
181 
182   for (ln = ll->first; ln ; ln = ln->next)
183     if (ln->layer->name && !strcmp(ln->layer->name->buf, name->buf))
184       return ln->layer->writable;
185 
186   return false;
187 }
188 
189 
190 /*
191  * Check if a layer is in a layer's list
192  */
ows_layer_in_list(const ows_layer_list * ll,buffer * name)193 bool ows_layer_in_list(const ows_layer_list * ll, buffer * name)
194 {
195   ows_layer_node *ln;
196 
197   assert(ll);
198   assert(name);
199 
200   for (ln = ll->first; ln ; ln = ln->next)
201     if (ln->layer->name && !strcmp(ln->layer->name->buf, name->buf))
202       return true;
203 
204   return false;
205 }
206 
207 
208 /*
209  * Check if a layer's list is in a other layer's list
210  */
ows_layer_list_in_list(const ows_layer_list * ll,const list * l)211 bool ows_layer_list_in_list(const ows_layer_list * ll, const list * l)
212 {
213   list_node *ln;
214 
215   assert(ll);
216   assert(l);
217 
218   for (ln = l->first; ln ; ln = ln->next)
219     if (!ows_layer_in_list(ll, ln->value)) return false;
220 
221   return true;
222 }
223 
224 
225 /*
226  * Return an array of prefixes and associated NS URI of a layer's list
227  */
ows_layer_list_namespaces(ows_layer_list * ll)228 array *ows_layer_list_namespaces(ows_layer_list * ll)
229 {
230   buffer *ns_prefix, *ns_uri;
231   ows_layer_node *ln;
232   array *namespaces = array_init();
233 
234   assert(ll);
235 
236   for (ln = ll->first; ln ; ln = ln->next) {
237     if (    ln->layer->ns_prefix && ln->layer->ns_prefix->use
238             && !array_is_key(namespaces, ln->layer->ns_prefix->buf)) {
239 
240       ns_prefix = buffer_init();
241       ns_uri = buffer_init();
242       buffer_copy(ns_prefix, ln->layer->ns_prefix);
243       buffer_copy(ns_uri, ln->layer->ns_uri);
244       array_add(namespaces, ns_prefix, ns_uri);
245     }
246   }
247 
248   return namespaces;
249 }
250 
251 
252 /*
253  * Return a list of layer names grouped by prefix
254  */
ows_layer_list_by_ns_prefix(ows_layer_list * ll,list * layer_name_prefix,buffer * ns_prefix)255 list *ows_layer_list_by_ns_prefix(ows_layer_list * ll, list * layer_name_prefix, buffer * ns_prefix)
256 {
257   list *typ;
258   list_node *ln;
259   buffer *layer_ns_prefix;
260 
261   assert(ll);
262   assert(layer_name_prefix);
263   assert(ns_prefix);
264 
265   typ = list_init();
266 
267   for (ln = layer_name_prefix->first; ln ; ln = ln->next) {
268     layer_ns_prefix = ows_layer_ns_prefix(ll, ln->value);
269 
270     if (buffer_cmp(layer_ns_prefix, ns_prefix->buf))
271       list_add_by_copy(typ, ln->value);
272   }
273 
274   return typ;
275 }
276 
277 
278 /*
279  * Retrieve a list of prefix used for a specified list of layers
280  */
ows_layer_list_ns_prefix(ows_layer_list * ll,list * layer_name_uri)281 list *ows_layer_list_ns_prefix(ows_layer_list * ll, list * layer_name_uri)
282 {
283   list_node *ln;
284   list *ml_ns_prefix;
285   buffer *ns_prefix;
286 
287   assert(ll && layer_name_uri);
288 
289   ml_ns_prefix = list_init();
290 
291   for (ln = layer_name_uri->first; ln ; ln = ln->next) {
292     ns_prefix = ows_layer_ns_prefix(ll, ows_layer_uri_to_prefix(ll, ln->value));
293 
294     if (!in_list(ml_ns_prefix, ns_prefix))
295       list_add_by_copy(ml_ns_prefix, ns_prefix);
296 
297     if ((ows_layer_get(ll, ln->value))->gml_ns && !in_list_str(ml_ns_prefix, "gml"))
298       list_add_str(ml_ns_prefix, "gml");
299   }
300 
301   return ml_ns_prefix;
302 }
303 
304 
305 /*
306  * TODO
307  */
ows_layer_list_prefix_to_uri(ows_layer_list * ll,list * layer_name_prefix)308 list *ows_layer_list_prefix_to_uri(ows_layer_list * ll, list * layer_name_prefix)
309 {
310   list_node *ln;
311   list *prefix;
312   assert(ll && layer_name_prefix);
313 
314   prefix = list_init();
315 
316   for (ln = layer_name_prefix->first; ln ; ln = ln->next) {
317     list_add_by_copy(prefix, ows_layer_prefix_to_uri(ll, ln->value));
318   }
319 
320   return prefix;
321 }
322 
323 
324 /*
325  * TODO
326  */
ows_layer_uri_to_prefix(ows_layer_list * ll,buffer * layer_name)327 buffer *ows_layer_uri_to_prefix(ows_layer_list * ll, buffer * layer_name)
328 {
329   ows_layer_node *ln;
330   assert(ll && layer_name);
331 
332   for (ln = ll->first; ln ; ln = ln->next)
333     if (buffer_cmp(ln->layer->name, layer_name->buf))
334       return ln->layer->name_prefix;
335 
336   return (buffer *) NULL;
337 }
338 
339 
340 /*
341  * TODO
342  */
ows_layer_prefix_to_uri(ows_layer_list * ll,buffer * layer_name_prefix)343 buffer *ows_layer_prefix_to_uri(ows_layer_list * ll, buffer * layer_name_prefix)
344 {
345   ows_layer_node *ln;
346   assert(ll && layer_name_prefix);
347 
348   for (ln = ll->first; ln ; ln = ln->next)
349     if (buffer_cmp(ln->layer->name_prefix, layer_name_prefix->buf))
350       return ln->layer->name;
351 
352   return (buffer *) NULL;
353 }
354 
355 
356 /*
357  * TODO
358  */
ows_layer_ns_prefix_to_ns_uri(ows_layer_list * ll,buffer * ns_prefix)359 buffer *ows_layer_ns_prefix_to_ns_uri(ows_layer_list * ll, buffer * ns_prefix)
360 {
361   ows_layer_node *ln;
362   assert(ll && ns_prefix);
363 
364   for (ln = ll->first; ln ; ln = ln->next) {
365     if (buffer_cmp(ln->layer->ns_prefix, ns_prefix->buf))
366       return ln->layer->ns_uri;
367   }
368 
369   return (buffer *) NULL;
370 }
371 
372 
373 /*
374  * Retrieve layer name without uri
375  */
ows_layer_no_uri(ows_layer_list * ll,buffer * layer_name)376 buffer *ows_layer_no_uri(ows_layer_list * ll, buffer * layer_name)
377 {
378   ows_layer_node *ln;
379   assert(ll && layer_name);
380 
381   for (ln = ll->first; ln ; ln = ln->next)
382     if (buffer_cmp(ln->layer->name, layer_name->buf))
383       return ln->layer->name_no_uri;
384 
385   return (buffer *) NULL;
386 }
387 
388 
389 /*
390  * Retrieve layer name without uri
391  */
ows_layer_no_uri_to_uri(const ows_layer_list * ll,buffer * layer_name_no_uri)392 buffer *ows_layer_no_uri_to_uri(const ows_layer_list * ll, buffer * layer_name_no_uri)
393 {
394   ows_layer_node *ln;
395   assert(ll && layer_name_no_uri);
396 
397   for (ln = ll->first; ln ; ln = ln->next)
398     if (buffer_cmp(ln->layer->name_no_uri, layer_name_no_uri->buf))
399       return ln->layer->name;
400 
401   return (buffer *) NULL;
402 }
403 
404 
405 /*
406  * Retrieve the prefix linked to the specified layer
407  */
ows_layer_ns_prefix(ows_layer_list * ll,buffer * layer_name_prefix)408 buffer *ows_layer_ns_prefix(ows_layer_list * ll, buffer * layer_name_prefix)
409 {
410   ows_layer_node *ln;
411   assert(ll && layer_name_prefix);
412 
413   for (ln = ll->first; ln ; ln = ln->next)
414     if (buffer_cmp(ln->layer->name_prefix, layer_name_prefix->buf))
415       return ln->layer->ns_prefix;
416 
417   return (buffer *) NULL;
418 }
419 
420 
421 /*
422  * Retrieve the ns_uri associated to the specified layer
423  */
ows_layer_ns_uri(ows_layer_list * ll,buffer * layer_name_uri)424 buffer *ows_layer_ns_uri(ows_layer_list * ll, buffer * layer_name_uri)
425 {
426   ows_layer_node *ln;
427   assert(ll && layer_name_uri);
428 
429   for (ln = ll->first; ln ; ln = ln->next)
430     if (buffer_cmp(ln->layer->name, layer_name_uri->buf))
431       return ln->layer->ns_uri;
432 
433   return (buffer *) NULL;
434 }
435 
436 
437 /*
438  * Add a layer to a layer's list
439  */
ows_layer_list_add(ows_layer_list * ll,ows_layer * l)440 void ows_layer_list_add(ows_layer_list * ll, ows_layer * l)
441 {
442   ows_layer_node *ln = ows_layer_node_init();
443   assert(ll && l);
444 
445   ln->layer = l;
446   if (!ll->first) {
447     ln->prev = NULL;
448     ll->first = ln;
449   } else {
450     ln->prev = ll->last;
451     ll->last->next = ln;
452   }
453   ll->last = ln;
454   ll->last->next = NULL;
455 }
456 
457 
458 /*
459  * Initialize a layer node
460  */
ows_layer_node_init()461 ows_layer_node *ows_layer_node_init()
462 {
463   ows_layer_node *ln = malloc(sizeof(ows_layer_node));
464   assert(ln);
465 
466   ln->prev = NULL;
467   ln->next = NULL;
468   ln->layer = NULL;
469 
470   return ln;
471 }
472 
473 
474 /*
475  * Free a layer node
476  */
ows_layer_node_free(ows_layer_list * ll,ows_layer_node * ln)477 void ows_layer_node_free(ows_layer_list * ll, ows_layer_node * ln)
478 {
479   assert(ln);
480 
481   if (ln->prev) ln->prev = NULL;
482   if (ln->next) {
483     if (ll) ll->first = ln->next;
484     ln->next = NULL;
485   } else if (ll) ll->first = NULL;
486 
487   if (ln->layer) ows_layer_free(ln->layer);
488 
489   free(ln);
490   ln = NULL;
491 }
492 
493 
494 /*
495  * Flush a layer's list to a given file
496  * (mainly to debug purpose)
497  */
498 #ifdef OWS_DEBUG
ows_layer_list_flush(ows_layer_list * ll,FILE * output)499 void ows_layer_list_flush(ows_layer_list * ll, FILE * output)
500 {
501   ows_layer_node *ln = NULL;
502   assert(ll);
503   assert(output);
504 
505   for (ln = ll->first; ln ; ln = ln->next) {
506     ows_layer_flush(ln->layer, output);
507     fprintf(output, "--------------------\n");
508   }
509 }
510 #endif
511 
512 
513 /*
514  * Initialize a layer
515  */
ows_layer_init()516 ows_layer *ows_layer_init()
517 {
518   ows_layer *l = malloc(sizeof(ows_layer));
519   assert(l);
520 
521   l->depth = 0;
522   l->parent = NULL;
523   l->title = NULL;
524   l->name = NULL;
525   l->name_prefix = NULL;
526   l->name_no_uri = NULL;
527   l->abstract = NULL;
528   l->keywords = NULL;
529   l->gml_ns = NULL;
530   l->retrievable = false;
531   l->writable = false;
532   l->srid = NULL;
533   l->geobbox = NULL;
534   l->exclude_items = NULL;
535   l->include_items = NULL;
536   l->pkey = NULL;
537   l->ns_prefix = buffer_init();
538   l->ns_uri = buffer_init();
539   l->storage = ows_layer_storage_init();
540 
541   return l;
542 }
543 
544 
545 /*
546  * Free a layer
547  */
ows_layer_free(ows_layer * l)548 void ows_layer_free(ows_layer * l)
549 {
550   assert(l);
551 
552   if (l->title)         buffer_free(l->title);
553   if (l->name)          buffer_free(l->name);
554   if (l->name_prefix)   buffer_free(l->name_prefix);
555   if (l->name_no_uri)   buffer_free(l->name_no_uri);
556   if (l->abstract)      buffer_free(l->abstract);
557   if (l->keywords)      list_free(l->keywords);
558   if (l->gml_ns)        list_free(l->gml_ns);
559   if (l->srid)          list_free(l->srid);
560   if (l->geobbox)       ows_geobbox_free(l->geobbox);
561   if (l->ns_uri)        buffer_free(l->ns_uri);
562   if (l->ns_prefix)     buffer_free(l->ns_prefix);
563   if (l->storage)       ows_layer_storage_free(l->storage);
564   if (l->exclude_items) list_free(l->exclude_items);
565   if (l->include_items) list_free(l->include_items);
566   if (l->pkey)          buffer_free(l->pkey);
567 
568   free(l);
569   l = NULL;
570 }
571 
572 
573 /*
574  * Flush a layer to a given file
575  * (mainly to debug purpose)
576  */
577 #ifdef OWS_DEBUG
ows_layer_flush(ows_layer * l,FILE * output)578 void ows_layer_flush(ows_layer * l, FILE * output)
579 {
580   assert(l);
581   assert(output);
582 
583   fprintf(output, "depth: %i\n", l->depth);
584 
585   if (l->parent) {
586     if      (l->parent->name)  fprintf(output, "parent: %s\n", l->parent->name->buf);
587     else if (l->parent->title) fprintf(output, "parent: %s\n", l->parent->title->buf);
588   }
589 
590   fprintf(output, "retrievable: %i\n", l->retrievable?1:0);
591   fprintf(output, "writable: %i\n", l->writable?1:0);
592 
593   if (l->title) {
594     fprintf(output, "title: ");
595     buffer_flush(l->title, output);
596     fprintf(output, "\n");
597   }
598 
599   if (l->name) {
600     fprintf(output, "name: ");
601     buffer_flush(l->name, output);
602     fprintf(output, "\n");
603   }
604 
605   if (l->name_prefix) {
606     fprintf(output, "name_prefix: ");
607     buffer_flush(l->name_prefix, output);
608     fprintf(output, "\n");
609   }
610 
611   if (l->name_no_uri) {
612     fprintf(output, "name_no_uri: ");
613     buffer_flush(l->name_no_uri, output);
614     fprintf(output, "\n");
615   }
616 
617   if (l->srid) {
618     fprintf(output, "srid: ");
619     list_flush(l->srid, output);
620     fprintf(output, "\n");
621   }
622 
623   if (l->keywords) {
624     fprintf(output, "keyword: ");
625     list_flush(l->keywords, output);
626     fprintf(output, "\n");
627   }
628 
629   if (l->gml_ns) {
630     fprintf(output, "gml_ns: ");
631     list_flush(l->gml_ns, output);
632     fprintf(output, "\n");
633   }
634 
635   if (l->geobbox) {
636     fprintf(output, "geobbox: ");
637     ows_geobbox_flush(l->geobbox, output);
638     fprintf(output, "\n");
639   }
640 
641   if (l->ns_prefix) {
642     fprintf(output, "ns_prefix: ");
643     buffer_flush(l->ns_prefix, output);
644     fprintf(output, "\n");
645   }
646 
647   if (l->ns_uri) {
648     fprintf(output, "ns_uri: ");
649     buffer_flush(l->ns_uri, output);
650     fprintf(output, "\n");
651   }
652 
653   if (l->storage) {
654     fprintf(output, "storage: ");
655     ows_layer_storage_flush(l->storage, output);
656     fprintf(output, "\n");
657   }
658 
659   if(l->exclude_items) {
660     fprintf(output, "exclude_items: ");
661     list_flush(l->exclude_items, output);
662     fprintf(output, "\n");
663   }
664 
665   if(l->include_items) {
666     fprintf(output, "include_items: ");
667     list_flush(l->include_items, output);
668     fprintf(output, "\n");
669   }
670 }
671 #endif
672