root/src/wfs/wfs_describe.c @ 196

Revision 196, 8.6 kB (checked in by ol, 7 months ago)

Fix warning gcc with Ubuntu 4.x - Thanks to Tony Vincent for report

Line 
1/*
2  Copyright (c) <2007-2009> <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
28#include "../ows/ows.h"
29
30
31/*
32 * Describe the layer_name in GML according
33 * with PostGIS table definition
34 */
35static void wfs_complex_type(ows * o, wfs_request * wr,
36                             buffer * layer_name)
37{
38    buffer *id_name;
39    array *table;
40    array_node *an;
41    list *mandatory_prop;
42
43    assert(o != NULL);
44    assert(wr != NULL);
45    assert(layer_name != NULL);
46
47    mandatory_prop = ows_psql_not_null_properties(o, layer_name);
48
49    fprintf(o->output, "<xs:complexType name='");
50    buffer_flush(layer_name, o->output);
51    fprintf(o->output, "Type'>\n");
52    fprintf(o->output, " <xs:complexContent>\n");
53    fprintf(o->output,
54            "  <xs:extension base='gml:AbstractFeatureType'>\n");
55    fprintf(o->output, "   <xs:sequence>\n");
56
57    id_name = ows_psql_id_column(o, layer_name);
58    table = ows_psql_describe_table(o, layer_name);
59
60    assert(table != NULL);
61
62    /* Output the description of the layer_name */
63    for (an = table->first; an != NULL; an = an->next) {
64        if (!buffer_cmp(an->key, id_name->buf)) {
65            fprintf(o->output, "    <xs:element name ='");
66            buffer_flush(an->key, o->output);
67            fprintf(o->output, "' type='%s' ", ows_psql_to_xsd(an->value));
68
69            if (in_list(mandatory_prop, an->key))
70                fprintf(o->output, "minOccurs='1' ");
71            else
72                fprintf(o->output, "minOccurs='0' ");
73
74            fprintf(o->output, "maxOccurs='1'/>\n");
75        }
76    }
77
78    fprintf(o->output, "   </xs:sequence>\n");
79    fprintf(o->output, "  </xs:extension>\n");
80    fprintf(o->output, " </xs:complexContent>\n");
81    fprintf(o->output, "</xs:complexType>\n");
82}
83
84
85/*
86 * Execute the DescribeFeatureType request according to version
87 * (GML version differ between WFS 1.0.0 and WFS 1.1.0)
88 */
89void wfs_describe_feature_type(ows * o, wfs_request * wr)
90{
91    int wfs_version;
92    list_node *elemt, *ln;
93    list *prefix, *typ;
94    buffer *namespace;
95
96    assert(o != NULL);
97    assert(wr != NULL);
98
99    wfs_version = ows_version_get(o->request->version);
100
101    fprintf(o->output, "Content-Type: application/xml\n\n");
102    fprintf(o->output, "<?xml version='1.0' encoding='UTF-8'?>\n");
103    prefix = ows_layer_list_prefix(o->layers, wr->typename);
104
105    /* if all layers belong to different prefixes, import the matching namespaces */
106    if (prefix->first->next != NULL) {
107        fprintf(o->output,
108                "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns='http://www.w3.org/2001/XMLSchema' ");
109        fprintf(o->output, "elementFormDefault='qualified'> ");
110
111        for (elemt = prefix->first; elemt != NULL; elemt = elemt->next) {
112            namespace = ows_layer_server(o->layers, elemt->value);
113            fprintf(o->output, "<xs:import namespace='%s' ",
114                    namespace->buf);
115            fprintf(o->output, "schemaLocation='%s?service=WFS&amp;version=",
116                    o->online_resource->buf);
117
118            if (wfs_version == 100)
119                fprintf(o->output, "1.0.0&amp;request=DescribeFeatureType&amp;typename=");
120            else
121                fprintf(o->output, "1.1.0&amp;request=DescribeFeatureType&amp;typename=");
122
123            /* print the describeFeatureType request with typenames for each prefix */
124            typ = ows_layer_list_by_prefix(o->layers, wr->typename, elemt->value);
125
126            for (ln = typ->first; ln != NULL; ln = ln->next) {
127                fprintf(o->output, "%s", ln->value->buf);
128
129                if (ln->next != NULL) fprintf(o->output, ",");
130            }
131
132            list_free(typ);
133            fprintf(o->output, "' />\n\n");
134        }
135
136        fprintf(o->output, "</xs:schema>\n");
137    }
138    /* if all layers belong to the same prefix, print the xsd schema describing features */
139    else {
140        namespace = ows_layer_server(o->layers, prefix->first->value);
141        fprintf(o->output,
142                "<xs:schema targetNamespace='%s' ", namespace->buf);
143        fprintf(o->output,
144                "xmlns:%s='%s' ", prefix->first->value->buf, namespace->buf);
145        fprintf(o->output, "xmlns:ogc='http://www.opengis.net/ogc' ");
146        fprintf(o->output, "xmlns:xs='http://www.w3.org/2001/XMLSchema' ");
147        fprintf(o->output, "xmlns='http://www.w3.org/2001/XMLSchema' ");
148        fprintf(o->output, "xmlns:gml='http://www.opengis.net/gml' ");
149        fprintf(o->output, "elementFormDefault='qualified' ");
150
151        if (wfs_version == 100)
152            fprintf(o->output, "version='1.0'>\n");
153        else
154            fprintf(o->output, "version='1.1'>\n");
155
156        fprintf(o->output,
157                "<xs:import namespace='http://www.opengis.net/gml'");
158
159        if (wfs_version == 100)
160            fprintf(o->output,
161                    " schemaLocation='http://schemas.opengis.net/gml/2.1.2/feature.xsd'/>\n");
162        else
163            fprintf(o->output,
164                    " schemaLocation='http://schemas.opengis.net/gml/3.1.1/base/gml.xsd'/>\n");
165
166        /* Describe each feature type specified in the request */
167        for (elemt = wr->typename->first; elemt != NULL;
168                elemt = elemt->next)
169
170        {
171            fprintf(o->output, "<xs:element name='");
172            buffer_flush(elemt->value, o->output);
173            fprintf(o->output, "' type='%s:", prefix->first->value->buf);
174            buffer_flush(elemt->value, o->output);
175            fprintf(o->output,
176                    "Type' substitutionGroup='gml:_Feature' />\n");
177            wfs_complex_type(o, wr, elemt->value);
178        }
179
180        fprintf(o->output, "</xs:schema>");
181    }
182
183    list_free(prefix);
184}
185
186
187/*
188 * Generate a WFS Schema related to current Server (all valid layers)
189 * with GML XSD import
190 * This is needed by WFS Insert operation validation as libxml2 only handle
191 * a single schema validation at a time
192 */
193buffer * wfs_generate_schema(ows * o)
194{
195    int wfs_version;
196    list_node *elemt;
197    list *prefix;
198    buffer *namespace;
199    buffer *schema;
200    list * layers;
201
202    assert(o != NULL);
203
204    wfs_version = ows_version_get(o->request->version);
205    schema = buffer_init();
206    layers = ows_layer_list_having_storage(o->layers);
207
208    buffer_add_str(schema, "<?xml version='1.0' encoding='UTF-8'?>\n"); 
209    prefix = ows_layer_list_prefix(o->layers, layers);
210
211    buffer_add_str(schema, "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'");
212    buffer_add_str(schema, " xmlns='http://www.w3.org/2001/XMLSchema'");
213    buffer_add_str(schema, " elementFormDefault='qualified'>\n");
214
215    buffer_add_str(schema, "<xs:import namespace='http://www.opengis.net/wfs' ");
216    buffer_add_str(schema, "schemaLocation='");
217    buffer_copy(schema, o->schema_dir);
218    if (wfs_version == 100) buffer_add_str(schema, WFS_SCHEMA_100_TRANS);
219    else buffer_add_str(schema, WFS_SCHEMA_110);
220
221    buffer_add_str(schema, "'/>\n");
222
223    for (elemt = prefix->first; elemt != NULL; elemt = elemt->next) {
224        namespace = ows_layer_server(o->layers, elemt->value);
225        buffer_add_str(schema, "<xs:import namespace='");
226        buffer_copy(schema, namespace);
227        buffer_add_str(schema, "' schemaLocation='");
228        buffer_copy(schema, o->online_resource);
229        buffer_add_str(schema, "?service=WFS&amp;request=DescribeFeatureType");
230
231        if (wfs_version == 100)
232            buffer_add_str(schema, "&amp;version=1.0.0");
233        else
234            buffer_add_str(schema, "&amp;version=1.1.0");
235
236        buffer_add_str(schema, "'/>\n");
237    }
238
239    buffer_add_str(schema, "</xs:schema>");
240    list_free(prefix);
241    list_free(layers);
242
243    return schema;
244}
245
246
247/*
248 * vim: expandtab sw=4 ts=4
249 */
Note: See TracBrowser for help on using the browser.