~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to gis/dhis-gis-geostat/mfbase/openlayers/lib/OpenLayers/Protocol/HTTP.js

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
 
2
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 
3
 * full text of the license. */
 
4
 
 
5
/**
 
6
 * @requires OpenLayers/Protocol.js
 
7
 * @requires OpenLayers/Feature/Vector.js
 
8
 */
 
9
 
 
10
/**
 
11
 * Class: OpenLayers.Protocol.HTTP
 
12
 * A basic HTTP protocol for vector layers.  Create a new instance with the
 
13
 *     <OpenLayers.Protocol.HTTP> constructor.
 
14
 *
 
15
 * Inherits from:
 
16
 *  - <OpenLayers.Protocol>
 
17
 */
 
18
OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
 
19
 
 
20
    /**
 
21
     * Property: url
 
22
     * {String} Service URL, read-only, set through the options
 
23
     *     passed to constructor.
 
24
     */
 
25
    url: null,
 
26
 
 
27
    /**
 
28
     * Property: headers
 
29
     * {Object} HTTP request headers, read-only, set through the options
 
30
     *     passed to the constructor,
 
31
     *     Example: {'Content-Type': 'plain/text'}
 
32
     */
 
33
    headers: null,
 
34
 
 
35
    /**
 
36
     * Property: params
 
37
     * {Object} Parameters of GET requests, read-only, set through the options
 
38
     *     passed to the constructor,
 
39
     *     Example: {'bbox': '5,5,5,5'}
 
40
     */
 
41
    params: null,
 
42
    
 
43
    /**
 
44
     * Property: callback
 
45
     * {Object} Function to be called when the <read>, <create>,
 
46
     *     <update>, <delete> or <commit> operation completes, read-only,
 
47
     *     set through the options passed to the constructor.
 
48
     */
 
49
    callback: null,
 
50
 
 
51
    /**
 
52
     * Property: scope
 
53
     * {Object} Callback execution scope, read-only, set through the
 
54
     *     options passed to the constructor.
 
55
     */
 
56
    scope: null,
 
57
 
 
58
    /**
 
59
     * Constructor: OpenLayers.Protocol.HTTP
 
60
     * A class for giving layers generic HTTP protocol.
 
61
     *
 
62
     * Parameters:
 
63
     * options - {Object} Optional object whose properties will be set on the
 
64
     *     instance.
 
65
     *
 
66
     * Valid options include:
 
67
     * url - {String}
 
68
     * headers - {Object} 
 
69
     * params - {Object}
 
70
     * format - {<OpenLayers.Format>}
 
71
     * callback - {Function}
 
72
     * scope - {Object}
 
73
     */
 
74
    initialize: function(options) {
 
75
        this.params = {};
 
76
        this.headers = {};
 
77
        OpenLayers.Protocol.prototype.initialize.apply(this, arguments);
 
78
    },
 
79
    
 
80
    /**
 
81
     * APIMethod: destroy
 
82
     * Clean up the protocol.
 
83
     */
 
84
    destroy: function() {
 
85
        this.params = null;
 
86
        this.headers = null;
 
87
        OpenLayers.Protocol.prototype.destroy.apply(this);
 
88
    },
 
89
   
 
90
    /**
 
91
     * Method: createCallback
 
92
     * Returns a function that applies the given public method with resp and
 
93
     *     options arguments.
 
94
     *
 
95
     * Parameters:
 
96
     * method - {Function} The method to be applied by the callback.
 
97
     * response - {<OpenLayers.Protocol.Response>} The protocol response object.
 
98
     * options - {Object} Options sent to the protocol method (read, create,
 
99
     *     update, or delete).
 
100
     */
 
101
    createCallback: function(method, response, options) {
 
102
        return OpenLayers.Function.bind(function() {
 
103
            method.apply(this, [response, options]);
 
104
        }, this);
 
105
    },
 
106
 
 
107
    /**
 
108
     * Method: read
 
109
     * Construct a request for reading new features.
 
110
     *
 
111
     * Parameters:
 
112
     * options - {Object} Optional object for configuring the request.
 
113
     *     This object is modified and should not be reused.
 
114
     *
 
115
     * Valid options:
 
116
     * url - {String} Url for the request.
 
117
     * params - {Object} Parameters to get serialized as a query string.
 
118
     * headers - {Object} Headers to be set on the request.
 
119
     * filter - {<OpenLayers.Filter.BBOX>} If a bbox filter is sent, it will be
 
120
     *     serialized according to the OpenSearch Geo extension
 
121
     *     (bbox=minx,miny,maxx,maxy).  Note that a BBOX filter as the child
 
122
     *     of a logical filter will not be serialized.
 
123
     *
 
124
     * Returns:
 
125
     * {<OpenLayers.Protocol.Response>} A response object, whose "priv" property
 
126
     *     references the HTTP request, this object is also passed to the
 
127
     *     callback function when the request completes, its "features" property
 
128
     *     is then populated with the the features received from the server.
 
129
     */
 
130
    read: function(options) {
 
131
        options = OpenLayers.Util.applyDefaults(options, this.options);
 
132
        var resp = new OpenLayers.Protocol.Response({requestType: "read"});
 
133
        
 
134
        if(options.filter && options.filter instanceof OpenLayers.Filter.Spatial) {
 
135
            if(options.filter.type == OpenLayers.Filter.Spatial.BBOX) {
 
136
                options.params = OpenLayers.Util.extend(options.params, {
 
137
                    bbox: options.filter.value.toArray()
 
138
                });
 
139
            }
 
140
        }
 
141
 
 
142
        resp.priv = OpenLayers.Request.GET({
 
143
            url: options.url,
 
144
            callback: this.createCallback(this.handleRead, resp, options),
 
145
            params: options.params,
 
146
            headers: options.headers
 
147
        });        
 
148
 
 
149
        return resp;
 
150
    },
 
151
 
 
152
    /**
 
153
     * Method: handleRead
 
154
     * Individual callbacks are created for read, create and update, should
 
155
     *     a subclass need to override each one separately.
 
156
     *
 
157
     * Parameters:
 
158
     * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
 
159
     *     the user callback.
 
160
     * options - {Object} The user options passed to the read call.
 
161
     */
 
162
    handleRead: function(resp, options) {
 
163
        this.handleResponse(resp, options);
 
164
    },
 
165
    
 
166
    /**
 
167
     * Method: create
 
168
     * Construct a request for writing newly created features.
 
169
     *
 
170
     * Parameters:
 
171
     * features - {Array({<OpenLayers.Feature.Vector>})} or
 
172
     *     {<OpenLayers.Feature.Vector>}
 
173
     * options - {Object} Optional object for configuring the request.
 
174
     *     This object is modified and should not be reused.
 
175
     *
 
176
     * Returns:
 
177
     * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
 
178
     *     object, whose "priv" property references the HTTP request, this 
 
179
     *     object is also passed to the callback function when the request
 
180
     *     completes, its "features" property is then populated with the
 
181
     *     the features received from the server.
 
182
     */
 
183
    create: function(features, options) {
 
184
        options = OpenLayers.Util.applyDefaults(options, this.options);
 
185
 
 
186
        var resp = new OpenLayers.Protocol.Response({
 
187
            reqFeatures: features,
 
188
            requestType: "create"
 
189
        });
 
190
 
 
191
        resp.priv = OpenLayers.Request.POST({
 
192
            url: options.url,
 
193
            callback: this.createCallback(this.handleCreate, resp, options),
 
194
            headers: options.headers,
 
195
            data: this.format.write(features)
 
196
        });
 
197
 
 
198
        return resp;
 
199
    },
 
200
 
 
201
    /**
 
202
     * Method: handleCreate
 
203
     * Called the the request issued by <create> is complete.  May be overridden
 
204
     *     by subclasses.
 
205
     *
 
206
     * Parameters:
 
207
     * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
 
208
     *     any user callback.
 
209
     * options - {Object} The user options passed to the create call.
 
210
     */
 
211
    handleCreate: function(resp, options) {
 
212
        this.handleResponse(resp, options);
 
213
    },
 
214
 
 
215
    /**
 
216
     * Method: update
 
217
     * Construct a request updating modified feature.
 
218
     *
 
219
     * Parameters:
 
220
     * feature - {<OpenLayers.Feature.Vector>}
 
221
     * options - {Object} Optional object for configuring the request.
 
222
     *     This object is modified and should not be reused.
 
223
     *
 
224
     * Returns:
 
225
     * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
 
226
     *     object, whose "priv" property references the HTTP request, this 
 
227
     *     object is also passed to the callback function when the request
 
228
     *     completes, its "features" property is then populated with the
 
229
     *     the feature received from the server.
 
230
     */
 
231
    update: function(feature, options) {
 
232
        var url = options.url || feature.url || this.options.url;
 
233
        options = OpenLayers.Util.applyDefaults(options, this.options);
 
234
 
 
235
        var resp = new OpenLayers.Protocol.Response({
 
236
            reqFeatures: feature,
 
237
            requestType: "update"
 
238
        });
 
239
 
 
240
        resp.priv = OpenLayers.Request.PUT({
 
241
            url: url,
 
242
            callback: this.createCallback(this.handleUpdate, resp, options),
 
243
            headers: options.headers,
 
244
            data: this.format.write(feature)
 
245
        });
 
246
 
 
247
        return resp;
 
248
    },
 
249
 
 
250
    /**
 
251
     * Method: handleUpdate
 
252
     * Called the the request issued by <update> is complete.  May be overridden
 
253
     *     by subclasses.
 
254
     *
 
255
     * Parameters:
 
256
     * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
 
257
     *     any user callback.
 
258
     * options - {Object} The user options passed to the update call.
 
259
     */
 
260
    handleUpdate: function(resp, options) {
 
261
        this.handleResponse(resp, options);
 
262
    },
 
263
 
 
264
    /**
 
265
     * Method: delete
 
266
     * Construct a request deleting a removed feature.
 
267
     *
 
268
     * Parameters:
 
269
     * feature - {<OpenLayers.Feature.Vector>}
 
270
     * options - {Object} Optional object for configuring the request.
 
271
     *     This object is modified and should not be reused.
 
272
     *
 
273
     * Returns:
 
274
     * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
 
275
     *     object, whose "priv" property references the HTTP request, this 
 
276
     *     object is also passed to the callback function when the request
 
277
     *     completes.
 
278
     */
 
279
    "delete": function(feature, options) {
 
280
        var url = options.url || feature.url || this.options.url;
 
281
        options = OpenLayers.Util.applyDefaults(options, this.options);
 
282
 
 
283
        var resp = new OpenLayers.Protocol.Response({
 
284
            reqFeatures: feature,
 
285
            requestType: "delete"
 
286
        });
 
287
 
 
288
        resp.priv = OpenLayers.Request.DELETE({
 
289
            url: url,
 
290
            callback: this.createCallback(this.handleDelete, resp, options),
 
291
            headers: options.headers
 
292
        });
 
293
 
 
294
        return resp;
 
295
    },
 
296
 
 
297
    /**
 
298
     * Method: handleDelete
 
299
     * Called the the request issued by <delete> is complete.  May be overridden
 
300
     *     by subclasses.
 
301
     *
 
302
     * Parameters:
 
303
     * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
 
304
     *     any user callback.
 
305
     * options - {Object} The user options passed to the delete call.
 
306
     */
 
307
    handleDelete: function(resp, options) {
 
308
        this.handleResponse(resp, options);
 
309
    },
 
310
 
 
311
    /**
 
312
     * Method: handleResponse
 
313
     * Called by CRUD specific handlers.
 
314
     *
 
315
     * Parameters:
 
316
     * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
 
317
     *     any user callback.
 
318
     * options - {Object} The user options passed to the create, read, update,
 
319
     *     or delete call.
 
320
     */
 
321
    handleResponse: function(resp, options) {
 
322
        var request = resp.priv;
 
323
        if(options.callback) {
 
324
            if(request.status >= 200 && request.status < 300) {
 
325
                // success
 
326
                if(resp.requestType != "delete") {
 
327
                    resp.features = this.parseFeatures(request);
 
328
                }
 
329
                resp.code = OpenLayers.Protocol.Response.SUCCESS;
 
330
            } else {
 
331
                // failure
 
332
                resp.code = OpenLayers.Protocol.Response.FAILURE;
 
333
            }
 
334
            options.callback.call(options.scope, resp);
 
335
        }
 
336
    },
 
337
 
 
338
    /**
 
339
     * Method: parseFeatures
 
340
     * Read HTTP response body and return features.
 
341
     *
 
342
     * Parameters:
 
343
     * request - {XMLHttpRequest} The request object
 
344
     *
 
345
     * Returns:
 
346
     * {Array({<OpenLayers.Feature.Vector>})} or
 
347
     *     {<OpenLayers.Feature.Vector>} Array of features or a single feature.
 
348
     */
 
349
    parseFeatures: function(request) {
 
350
        var doc = request.responseXML;
 
351
        if (!doc || !doc.documentElement) {
 
352
            doc = request.responseText;
 
353
        }
 
354
        if (!doc || doc.length <= 0) {
 
355
            return null;
 
356
        }
 
357
        return this.format.read(doc);
 
358
    },
 
359
 
 
360
    /**
 
361
     * Method: commit
 
362
     * Iterate over each feature and take action based on the feature state.
 
363
     *     Possible actions are create, update and delete.
 
364
     *
 
365
     * Parameters:
 
366
     * features - {Array({<OpenLayers.Feature.Vector>})}
 
367
     * options - {Object} Optional object for setting up intermediate commit
 
368
     *     callbacks.
 
369
     *
 
370
     * Valid options:
 
371
     * create - {Object} Optional object to be passed to the <create> method.
 
372
     * update - {Object} Optional object to be passed to the <update> method.
 
373
     * delete - {Object} Optional object to be passed to the <delete> method.
 
374
     * callback - {Function} Optional function to be called when the commit
 
375
     *     is complete.
 
376
     * scope - {Object} Optional object to be set as the scope of the callback.
 
377
     *
 
378
     * Returns:
 
379
     * {Array(<OpenLayers.Protocol.Response>)} An array of response objects,
 
380
     *     one per request made to the server, each object's "priv" property
 
381
     *     references the corresponding HTTP request.
 
382
     */
 
383
    commit: function(features, options) {
 
384
        options = OpenLayers.Util.applyDefaults(options, this.options);
 
385
        var resp = [], nResponses = 0;
 
386
        
 
387
        // Divide up features before issuing any requests.  This properly
 
388
        // counts requests in the event that any responses come in before
 
389
        // all requests have been issued.
 
390
        var types = {};
 
391
        types[OpenLayers.State.INSERT] = [];
 
392
        types[OpenLayers.State.UPDATE] = [];
 
393
        types[OpenLayers.State.DELETE] = [];
 
394
        var feature, list;
 
395
        for(var i=0, len=features.length; i<len; ++i) {
 
396
            feature = features[i];
 
397
            list = types[feature.state];
 
398
            if(list) {
 
399
                list.push(feature);
 
400
            }
 
401
        }
 
402
        // tally up number of requests
 
403
        var nRequests = (types[OpenLayers.State.INSERT].length > 0 ? 1 : 0) +
 
404
            types[OpenLayers.State.UPDATE].length +
 
405
            types[OpenLayers.State.DELETE].length;
 
406
        
 
407
        function callback(response) {
 
408
            nResponses++;
 
409
            response.last = (nResponses >= nRequests);
 
410
            this.callUserCallback(response, options);
 
411
        }
 
412
        
 
413
        // start issuing requests
 
414
        var queue = types[OpenLayers.State.INSERT];
 
415
        if(queue.length > 0) {
 
416
            resp.push(this.create(
 
417
                queue, OpenLayers.Util.applyDefaults(
 
418
                    {callback: callback, scope: this},
 
419
                    options.create || {} // remove || when #1716 is resolved
 
420
                )
 
421
            ));
 
422
        }
 
423
        queue = types[OpenLayers.State.UPDATE];
 
424
        for(var i=queue.length-1; i>=0; --i) {
 
425
            resp.push(this.update(
 
426
                queue[i], OpenLayers.Util.applyDefaults(
 
427
                    {callback: callback, scope: this}, 
 
428
                    options.update || {} // remove || when #1716 is resolved
 
429
                ))
 
430
            );
 
431
        }
 
432
        queue = types[OpenLayers.State.DELETE];
 
433
        for(var i=queue.length-1; i>=0; --i) {
 
434
            resp.push(this["delete"](
 
435
                queue[i], OpenLayers.Util.applyDefaults(
 
436
                    {callback: callback, scope: this},
 
437
                    options["delete"] || {} // remove || when #1716 is resolved
 
438
                ))
 
439
            );
 
440
        }
 
441
        return resp;
 
442
    },
 
443
 
 
444
    /**
 
445
     * Method: callUserCallback
 
446
     * This method is used from within the commit method each time an
 
447
     *     an HTTP response is received from the server, it is responsible
 
448
     *     for calling the user-supplied callbacks.
 
449
     *
 
450
     * Parameters:
 
451
     * resp - {<OpenLayers.Protocol.Response>}
 
452
     * options - {Object} The map of options passed to the commit call.
 
453
     */
 
454
    callUserCallback: function(resp, options) {
 
455
        var opt = options[resp.requestType];
 
456
        if(opt && opt.callback) {
 
457
            opt.callback.call(opt.scope, resp);
 
458
        }
 
459
        if(resp.last && options.callback) {
 
460
            options.callback.call(options.scope);
 
461
        }
 
462
    },
 
463
 
 
464
    CLASS_NAME: "OpenLayers.Protocol.HTTP" 
 
465
});