]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Protocol/WFS/v1.js
initial commit
[syp.git] / openlayers / lib / OpenLayers / Protocol / WFS / v1.js
1 /**
2  * @requires OpenLayers/Protocol/WFS.js
3  */
4
5 /**
6  * Class: OpenLayers.Protocol.WFS.v1
7  * Abstract class for for v1.0.0 and v1.1.0 protocol.
8  *
9  * Inherits from:
10  *  - <OpenLayers.Protocol>
11  */
12 OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, {
13     
14     /**
15      * Property: version
16      * {String} WFS version number.
17      */
18     version: null,
19     
20     /**
21      * Property: srsName
22      * {String} Name of spatial reference system.  Default is "EPSG:4326".
23      */
24     srsName: "EPSG:4326",
25     
26     /**
27      * Property: featureType
28      * {String} Local feature typeName.
29      */
30     featureType: null,
31     
32     /**
33      * Property: featureNS
34      * {String} Feature namespace.
35      */
36     featureNS: null,
37     
38     /**
39      * Property: geometryName
40      * {String} Name of the geometry attribute for features.  Default is
41      *     "the_geom".
42      */
43     geometryName: "the_geom",
44     
45     /**
46      * Property: schema
47      * {String} Optional schema location that will be included in the
48      *     schemaLocation attribute value.  Note that the feature type schema
49      *     is required for a strict XML validator (on transactions with an
50      *     insert for example), but is *not* required by the WFS specification
51      *     (since the server is supposed to know about feature type schemas).
52      */
53     schema: null,
54
55     /**
56      * Property: featurePrefix
57      * {String} Namespace alias for feature type.  Default is "feature".
58      */
59     featurePrefix: "feature",
60     
61     /**
62      * Property: formatOptions
63      * {Object} Optional options for the format.  If a format is not provided,
64      *     this property can be used to extend the default format options.
65      */
66     formatOptions: null,
67     
68     /**
69      * Constructor: OpenLayers.Protocol.WFS
70      * A class for giving layers WFS protocol.
71      *
72      * Parameters:
73      * options - {Object} Optional object whose properties will be set on the
74      *     instance.
75      *
76      * Valid options properties:
77      * url - {String} URL to send requests to (required).
78      * featureType - {String} Local (without prefix) feature typeName (required).
79      * featureNS - {String} Feature namespace (required, but can be autodetected
80      *     for reading if featurePrefix is provided and identical to the prefix
81      *     in the server response).
82      * featurePrefix - {String} Feature namespace alias (optional - only used
83      *     for writing if featureNS is provided).  Default is 'feature'.
84      * geometryName - {String} Name of geometry attribute.  Default is 'the_geom'.
85      */
86     initialize: function(options) {
87         OpenLayers.Protocol.prototype.initialize.apply(this, [options]);
88         if(!options.format) {
89             this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({
90                 version: this.version,
91                 featureType: this.featureType,
92                 featureNS: this.featureNS,
93                 featurePrefix: this.featurePrefix,
94                 geometryName: this.geometryName,
95                 srsName: this.srsName,
96                 schema: this.schema
97             }, this.formatOptions));
98         }
99         if(!this.featureNS) {
100             // featureNS autodetection
101             var readNode = this.format.readNode;
102             this.format.readNode = function(node, obj) {
103                 if(!this.featureNS && node.prefix == this.featurePrefix) {
104                     this.featureNS = node.namespaceURI;
105                     this.setNamespace("feature", this.featureNS);
106                 }
107                 return readNode.apply(this, arguments);
108             }
109         }
110     },
111     
112     /**
113      * APIMethod: destroy
114      * Clean up the protocol.
115      */
116     destroy: function() {
117         if(this.options && !this.options.format) {
118             this.format.destroy();
119         }
120         this.format = null;
121         OpenLayers.Protocol.prototype.destroy.apply(this);
122     },
123
124     /**
125      * Method: createCallback
126      * Returns a function that applies the given public method with resp and
127      *     options arguments.
128      *
129      * Parameters:
130      * method - {Function} The method to be applied by the callback.
131      * response - {<OpenLayers.Protocol.Response>} The protocol response object.
132      * options - {Object} Options sent to the protocol method (read, create,
133      *     update, or delete).
134      */
135     createCallback: function(method, response, options) {
136         return OpenLayers.Function.bind(function() {
137             method.apply(this, [response, options]);
138         }, this);
139     },
140
141     /**
142      * Method: read
143      * Construct a request for reading new features.  Since WFS splits the
144      *     basic CRUD operations into GetFeature requests (for read) and
145      *     Transactions (for all others), this method does not make use of the
146      *     format's read method (that is only about reading transaction
147      *     responses).
148      */
149     read: function(options) {
150         options = OpenLayers.Util.extend({}, options);
151         OpenLayers.Util.applyDefaults(options, this.options || {});
152         var response = new OpenLayers.Protocol.Response({requestType: "read"});
153         
154         var data = OpenLayers.Format.XML.prototype.write.apply(
155             this.format, [this.format.writeNode("wfs:GetFeature", options)]
156         );
157
158         response.priv = OpenLayers.Request.POST({
159             url: options.url,
160             callback: this.createCallback(this.handleRead, response, options),
161             params: options.params,
162             headers: options.headers,
163             data: data
164         });        
165
166         return response;
167     },
168     
169     /**
170      * Method: handleRead
171      * Deal with response from the read request.
172      *
173      * Parameters:
174      * response - {<OpenLayers.Protocol.Response>} The response object to pass
175      *     to the user callback.
176      * options - {Object} The user options passed to the read call.
177      */
178     handleRead: function(response, options) {
179         if(options.callback) {
180             var request = response.priv;
181             if(request.status >= 200 && request.status < 300) {
182                 // success
183                 response.features = this.parseFeatures(request);
184                 response.code = OpenLayers.Protocol.Response.SUCCESS;
185             } else {
186                 // failure
187                 response.code = OpenLayers.Protocol.Response.FAILURE;
188             }
189             options.callback.call(options.scope, response);
190         }; 
191     },
192
193     /**
194      * Method: parseFeatures
195      * Read HTTP response body and return features
196      *
197      * Parameters:
198      * request - {XMLHttpRequest} The request object
199      *
200      * Returns:
201      * {Array({<OpenLayers.Feature.Vector>})} or
202      *     {<OpenLayers.Feature.Vector>} Array of features or a single feature.
203      */
204     parseFeatures: function(request) {
205         var doc = request.responseXML;
206         if(!doc || !doc.documentElement) {
207             doc = request.responseText;
208         }
209         if(!doc || doc.length <= 0) {
210             return null;
211         }
212         return this.format.read(doc);
213     },
214
215     /**
216      * Method: commit
217      * Given a list of feature, assemble a batch request for update, create,
218      *     and delete transactions.  A commit call on the prototype amounts
219      *     to writing a WFS transaction - so the write method on the format
220      *     is used.
221      *
222      * Parameters:
223      * features - {Array(<OpenLayers.Feature.Vector>}
224      *
225      * Returns:
226      * {<OpenLayers.Protocol.Response>} A response object with a features
227      *     property containing any insertIds and a priv property referencing
228      *     the XMLHttpRequest object.
229      */
230     commit: function(features, options) {
231
232         options = OpenLayers.Util.extend({}, options);
233         OpenLayers.Util.applyDefaults(options, this.options);
234         
235         var response = new OpenLayers.Protocol.Response({
236             requestType: "commit",
237             reqFeatures: features
238         });
239         response.priv = OpenLayers.Request.POST({
240             url: options.url,
241             data: this.format.write(features, options),
242             callback: this.createCallback(this.handleCommit, response, options)
243         });
244         
245         return response;
246     },
247     
248     /**
249      * Method: handleCommit
250      * Called when the commit request returns.
251      * 
252      * Parameters:
253      * response - {<OpenLayers.Protocol.Response>} The response object to pass
254      *     to the user callback.
255      * options - {Object} The user options passed to the commit call.
256      */
257     handleCommit: function(response, options) {
258         if(options.callback) {
259             var request = response.priv;
260
261             // ensure that we have an xml doc
262             var data = request.responseXML;
263             if(!data || !data.documentElement) {
264                 data = request.responseText;
265             }
266             
267             var obj = this.format.read(data) || {};
268             
269             response.insertIds = obj.insertIds || [];
270             response.code = (obj.success) ?
271                 OpenLayers.Protocol.Response.SUCCESS :
272                 OpenLayers.Protocol.Response.FAILURE;
273             options.callback.call(options.scope, response);
274         }
275     },
276     
277     /**
278      * Method: filterDelete
279      * Send a request that deletes all features by their filter.
280      * 
281      * Parameters:
282      * filter - {OpenLayers.Filter} filter
283      */
284     filterDelete: function(filter, options) {
285         options = OpenLayers.Util.extend({}, options);
286         OpenLayers.Util.applyDefaults(options, this.options);    
287         
288         var response = new OpenLayers.Protocol.Response({
289             requestType: "commit"
290         });    
291         
292         var root = this.format.createElementNSPlus("wfs:Transaction", {
293                 attributes: {
294                 service: "WFS",
295                     version: this.version
296             }
297         });
298         
299         var deleteNode = this.format.createElementNSPlus("wfs:Delete", {
300             attributes: {
301                 typeName: (options.featureNS ? this.featurePrefix + ":" : "") +
302                     options.featureType
303             }
304         });       
305         
306         if(options.featureNS) {
307             deleteNode.setAttribute("xmlns:" + this.featurePrefix, options.featureNS);
308         }
309         var filterNode = this.format.writeNode("ogc:Filter", filter);
310         
311         deleteNode.appendChild(filterNode);
312         
313         root.appendChild(deleteNode);
314         
315         var data = OpenLayers.Format.XML.prototype.write.apply(
316             this.format, [root]
317         );
318         
319         return OpenLayers.Request.POST({
320             url: this.url,
321             callback : options.callback || function(){},
322             data: data
323         });   
324         
325     },
326
327     /**
328      * Method: abort
329      * Abort an ongoing request, the response object passed to
330      * this method must come from this protocol (as a result
331      * of a read, or commit operation).
332      *
333      * Parameters:
334      * response - {<OpenLayers.Protocol.Response>}
335      */
336     abort: function(response) {
337         if (response) {
338             response.priv.abort();
339         }
340     },
341   
342     CLASS_NAME: "OpenLayers.Protocol.WFS.v1" 
343 });