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