More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / Protocol / WFS / v1.js
blob:a/labs/openlayers/lib/OpenLayers/Protocol/WFS/v1.js -> blob:b/labs/openlayers/lib/OpenLayers/Protocol/WFS/v1.js
--- a/labs/openlayers/lib/OpenLayers/Protocol/WFS/v1.js
+++ b/labs/openlayers/lib/OpenLayers/Protocol/WFS/v1.js
@@ -1,1 +1,343 @@
-
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Protocol/WFS.js
+ */
+
+/**
+ * Class: OpenLayers.Protocol.WFS.v1
+ * Abstract class for for v1.0.0 and v1.1.0 protocol.
+ *
+ * Inherits from:
+ *  - <OpenLayers.Protocol>
+ */
+OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, {
+    
+    /**
+     * Property: version
+     * {String} WFS version number.
+     */
+    version: null,
+    
+    /**
+     * Property: srsName
+     * {String} Name of spatial reference system.  Default is "EPSG:4326".
+     */
+    srsName: "EPSG:4326",
+    
+    /**
+     * Property: featureType
+     * {String} Local feature typeName.
+     */
+    featureType: null,
+    
+    /**
+     * Property: featureNS
+     * {String} Feature namespace.
+     */
+    featureNS: null,
+    
+    /**
+     * Property: geometryName
+     * {String} Name of the geometry attribute for features.  Default is
+     *     "the_geom".
+     */
+    geometryName: "the_geom",
+    
+    /**
+     * Property: schema
+     * {String} Optional schema location that will be included in the
+     *     schemaLocation attribute value.  Note that the feature type schema
+     *     is required for a strict XML validator (on transactions with an
+     *     insert for example), but is *not* required by the WFS specification
+     *     (since the server is supposed to know about feature type schemas).
+     */
+    schema: null,
+
+    /**
+     * Property: featurePrefix
+     * {String} Namespace alias for feature type.  Default is "feature".
+     */
+    featurePrefix: "feature",
+    
+    /**
+     * Property: formatOptions
+     * {Object} Optional options for the format.  If a format is not provided,
+     *     this property can be used to extend the default format options.
+     */
+    formatOptions: null,
+
+    /** 
+     * Property: readFormat 
+     * {<OpenLayers.Format>} For WFS requests it is possible to get a  
+     *     different output format than GML. In that case, we cannot parse  
+     *     the response with the default format (WFST) and we need a different 
+     *     format for reading. 
+     */ 
+    readFormat: null,     
+    
+    /**
+     * Constructor: OpenLayers.Protocol.WFS
+     * A class for giving layers WFS protocol.
+     *
+     * Parameters:
+     * options - {Object} Optional object whose properties will be set on the
+     *     instance.
+     *
+     * Valid options properties:
+     * url - {String} URL to send requests to (required).
+     * featureType - {String} Local (without prefix) feature typeName (required).
+     * featureNS - {String} Feature namespace (required, but can be autodetected
+     *     for reading if featurePrefix is provided and identical to the prefix
+     *     in the server response).
+     * featurePrefix - {String} Feature namespace alias (optional - only used
+     *     for writing if featureNS is provided).  Default is 'feature'.
+     * geometryName - {String} Name of geometry attribute.  Default is 'the_geom'.
+     */
+    initialize: function(options) {
+        OpenLayers.Protocol.prototype.initialize.apply(this, [options]);
+        if(!options.format) {
+            this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({
+                version: this.version,
+                featureType: this.featureType,
+                featureNS: this.featureNS,
+                featurePrefix: this.featurePrefix,
+                geometryName: this.geometryName,
+                srsName: this.srsName,
+                schema: this.schema
+            }, this.formatOptions));
+        }
+        if(!this.featureNS && this.featurePrefix) {
+            // featureNS autodetection
+            var readNode = this.format.readNode;
+            this.format.readNode = function(node, obj) {
+                if(!this.featureNS && node.prefix == this.featurePrefix) {
+                    this.featureNS = node.namespaceURI;
+                    this.setNamespace("feature", this.featureNS);
+                }
+                return readNode.apply(this, arguments);
+            };
+        }
+    },
+    
+    /**
+     * APIMethod: destroy
+     * Clean up the protocol.
+     */
+    destroy: function() {
+        if(this.options && !this.options.format) {
+            this.format.destroy();
+        }
+        this.format = null;
+        OpenLayers.Protocol.prototype.destroy.apply(this);
+    },
+
+    /**
+     * Method: read
+     * Construct a request for reading new features.  Since WFS splits the
+     *     basic CRUD operations into GetFeature requests (for read) and
+     *     Transactions (for all others), this method does not make use of the
+     *     format's read method (that is only about reading transaction
+     *     responses).
+     */
+    read: function(options) {
+        OpenLayers.Protocol.prototype.read.apply(this, arguments);
+        options = OpenLayers.Util.extend({}, options);
+        OpenLayers.Util.applyDefaults(options, this.options || {});
+        var response = new OpenLayers.Protocol.Response({requestType: "read"});
+        
+        var data = OpenLayers.Format.XML.prototype.write.apply(
+            this.format, [this.format.writeNode("wfs:GetFeature", options)]
+        );
+
+        response.priv = OpenLayers.Request.POST({
+            url: options.url,
+            callback: this.createCallback(this.handleRead, response, options),
+            params: options.params,
+            headers: options.headers,
+            data: data
+        });        
+
+        return response;
+    },
+    
+    /**
+     * Method: handleRead
+     * Deal with response from the read request.
+     *
+     * Parameters:
+     * response - {<OpenLayers.Protocol.Response>} The response object to pass
+     *     to the user callback.
+     * options - {Object} The user options passed to the read call.
+     */
+    handleRead: function(response, options) {
+        if(options.callback) {
+            var request = response.priv;
+            if(request.status >= 200 && request.status < 300) {
+                // success
+                response.features = this.parseFeatures(request);
+                response.code = OpenLayers.Protocol.Response.SUCCESS;
+            } else {
+                // failure
+                response.code = OpenLayers.Protocol.Response.FAILURE;
+            }
+            options.callback.call(options.scope, response);
+        }
+    },
+
+    /**
+     * Method: parseFeatures
+     * Read HTTP response body and return features
+     *
+     * Parameters:
+     * request - {XMLHttpRequest} The request object
+     *
+     * Returns:
+     * {Array({<OpenLayers.Feature.Vector>})} or
+     *     {<OpenLayers.Feature.Vector>} Array of features or a single feature.
+     */
+    parseFeatures: function(request) {
+        var doc = request.responseXML;
+        if(!doc || !doc.documentElement) {
+            doc = request.responseText;
+        }
+        if(!doc || doc.length <= 0) {
+            return null;
+        }
+        return (this.readFormat !== null) ? this.readFormat.read(doc) : 
+            this.format.read(doc);
+    },
+
+    /**
+     * Method: commit
+     * Given a list of feature, assemble a batch request for update, create,
+     *     and delete transactions.  A commit call on the prototype amounts
+     *     to writing a WFS transaction - so the write method on the format
+     *     is used.
+     *
+     * Parameters:
+     * features - {Array(<OpenLayers.Feature.Vector>}
+     *
+     * Returns:
+     * {<OpenLayers.Protocol.Response>} A response object with a features
+     *     property containing any insertIds and a priv property referencing
+     *     the XMLHttpRequest object.
+     */
+    commit: function(features, options) {
+
+        options = OpenLayers.Util.extend({}, options);
+        OpenLayers.Util.applyDefaults(options, this.options);
+        
+        var response = new OpenLayers.Protocol.Response({
+            requestType: "commit",
+            reqFeatures: features
+        });
+        response.priv = OpenLayers.Request.POST({
+            url: options.url,
+            data: this.format.write(features, options),
+            callback: this.createCallback(this.handleCommit, response, options)
+        });
+        
+        return response;
+    },
+    
+    /**
+     * Method: handleCommit
+     * Called when the commit request returns.
+     * 
+     * Parameters:
+     * response - {<OpenLayers.Protocol.Response>} The response object to pass
+     *     to the user callback.
+     * options - {Object} The user options passed to the commit call.
+     */
+    handleCommit: function(response, options) {
+        if(options.callback) {
+            var request = response.priv;
+
+            // ensure that we have an xml doc
+            var data = request.responseXML;
+            if(!data || !data.documentElement) {
+                data = request.responseText;
+            }
+            
+            var obj = this.format.read(data) || {};
+            
+            response.insertIds = obj.insertIds || [];
+            response.code = (obj.success) ?
+                OpenLayers.Protocol.Response.SUCCESS :
+                OpenLayers.Protocol.Response.FAILURE;
+            options.callback.call(options.scope, response);
+        }
+    },
+    
+    /**
+     * Method: filterDelete
+     * Send a request that deletes all features by their filter.
+     * 
+     * Parameters:
+     * filter - {OpenLayers.Filter} filter
+     */
+    filterDelete: function(filter, options) {
+        options = OpenLayers.Util.extend({}, options);
+        OpenLayers.Util.applyDefaults(options, this.options);    
+        
+        var response = new OpenLayers.Protocol.Response({
+            requestType: "commit"
+        });    
+        
+        var root = this.format.createElementNSPlus("wfs:Transaction", {
+            attributes: {
+                service: "WFS",
+                version: this.version
+            }
+        });
+        
+        var deleteNode = this.format.createElementNSPlus("wfs:Delete", {
+            attributes: {
+                typeName: (options.featureNS ? this.featurePrefix + ":" : "") +
+                    options.featureType
+            }
+        });       
+        
+        if(options.featureNS) {
+            deleteNode.setAttribute("xmlns:" + this.featurePrefix, options.featureNS);
+        }
+        var filterNode = this.format.writeNode("ogc:Filter", filter);
+        
+        deleteNode.appendChild(filterNode);
+        
+        root.appendChild(deleteNode);
+        
+        var data = OpenLayers.Format.XML.prototype.write.apply(
+            this.format, [root]
+        );
+        
+        return OpenLayers.Request.POST({
+            url: this.url,
+            callback : options.callback || function(){},
+            data: data
+        });   
+        
+    },
+
+    /**
+     * Method: abort
+     * Abort an ongoing request, the response object passed to
+     * this method must come from this protocol (as a result
+     * of a read, or commit operation).
+     *
+     * Parameters:
+     * response - {<OpenLayers.Protocol.Response>}
+     */
+    abort: function(response) {
+        if (response) {
+            response.priv.abort();
+        }
+    },
+  
+    CLASS_NAME: "OpenLayers.Protocol.WFS.v1" 
+});
+