[OpenLayers-Commits] r12110 - in trunk/openlayers: lib/OpenLayers/Format/GML lib/OpenLayers/Format/WFST lib/OpenLayers/Protocol/WFS tests/Format/GML

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Mon Jun 20 06:59:29 EDT 2011


Author: ahocevar
Date: 2011-06-20 03:59:28 -0700 (Mon, 20 Jun 2011)
New Revision: 12110

Modified:
   trunk/openlayers/lib/OpenLayers/Format/GML/Base.js
   trunk/openlayers/lib/OpenLayers/Format/WFST/v1.js
   trunk/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js
   trunk/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js
   trunk/openlayers/lib/OpenLayers/Protocol/WFS/v1.js
   trunk/openlayers/tests/Format/GML/v2.html
   trunk/openlayers/tests/Format/GML/v3.html
Log:
auto-configure featureType and featureNS. p=bartvde (closes #3367)

Modified: trunk/openlayers/lib/OpenLayers/Format/GML/Base.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/GML/Base.js	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/lib/OpenLayers/Format/GML/Base.js	2011-06-20 10:59:28 UTC (rev 12110)
@@ -101,6 +101,18 @@
      *     of featuretypes.
      */
     singleFeatureType: null,
+    
+    /**
+     * Property: autoConfig
+     * {Boolean} Indicates if the format was configured without a <featureNS>,
+     * but auto-configured <featureNS> and <featureType> during read.
+     * Subclasses making use of <featureType> auto-configuration should make
+     * the first call to the <readNode> method (usually in the read method)
+     * with true as 3rd argument, so the auto-configured featureType can be
+     * reset and the format can be reused for subsequent reads with data from
+     * different featureTypes. Set to false after read if you want to keep the
+     * auto-configured values.
+     */
 
     /**
      * Property: regExes
@@ -110,7 +122,8 @@
         trimSpace: (/^\s*|\s*$/g),
         removeSpace: (/\s*/g),
         splitSpace: (/\s+/),
-        trimComma: (/\s*,\s*/g)
+        trimComma: (/\s*,\s*/g),
+        featureMember: (/^(.*:)?featureMembers?$/)
     },
 
     /**
@@ -125,9 +138,9 @@
      *
      * Valid options properties:
      * featureType - {Array(String) or String} Local (without prefix) feature 
-     *     typeName(s) (required).
-     * featureNS - {String} Feature namespace (required).
-     * geometryName - {String} Geometry element name.
+     *     typeName(s) (required for write).
+     * featureNS - {String} Feature namespace (required for write).
+     * geometryName - {String} Geometry element name (required for write).
      */
     initialize: function(options) {
         OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
@@ -156,7 +169,7 @@
             data = data.documentElement;
         }
         var features = [];
-        this.readNode(data, {features: features});
+        this.readNode(data, {features: features}, true);
         if(features.length == 0) {
             // look for gml:featureMember elements
             var elements = this.getElementsByTagNameNS(
@@ -164,7 +177,7 @@
             );
             if(elements.length) {
                 for(var i=0, len=elements.length; i<len; ++i) {
-                    this.readNode(elements[i], {features: features});
+                    this.readNode(elements[i], {features: features}, true);
                 }
             } else {
                 // look for gml:featureMembers elements (this is v3, but does no harm here)
@@ -173,7 +186,7 @@
                 );
                 if(elements.length) {
                     // there can be only one
-                    this.readNode(elements[0], {features: features});
+                    this.readNode(elements[0], {features: features}, true);
                 }
             }
         }
@@ -181,6 +194,43 @@
     },
     
     /**
+     * Method: readNode
+     * Shorthand for applying one of the named readers given the node
+     *     namespace and local name.  Readers take two args (node, obj) and
+     *     generally extend or modify the second.
+     *
+     * Parameters:
+     * node - {DOMElement} The node to be read (required).
+     * obj - {Object} The object to be modified (optional).
+     * first - {Boolean} Should be set to true for the first node read. This
+     *     is usually the readNode call in the read method. Without this being
+     *     set, auto-configured properties will stick on subsequent reads.
+     *
+     * Returns:
+     * {Object} The input object, modified (or a new one if none was provided).
+     */
+    readNode: function(node, obj, first) {
+        // on subsequent calls of format.read(), we want to reset auto-
+        // configured properties and auto-configure again.
+        if (first === true && this.autoConfig === true) {
+            this.featureType = null;
+            delete this.namespaceAlias[this.featureNS];
+            delete this.namespaces["feature"];
+            this.featureNS = null;
+        }
+        // featureType auto-configuration
+        if (!this.featureNS && (!(node.prefix in this.namespaces) &&
+                node.parentNode.namespaceURI == this.namespaces["gml"] &&
+                this.regExes.featureMember.test(node.parentNode.nodeName))) {
+            this.featureType = node.nodeName.split(":").pop();
+            this.setNamespace("feature", node.namespaceURI);
+            this.featureNS = node.namespaceURI;
+            this.autoConfig = true;
+        }
+        return OpenLayers.Format.XML.prototype.readNode.apply(this, arguments);
+    },
+
+    /**
      * Property: readers
      * Contains public functions, grouped by namespace prefix, that will
      *     be applied when a namespaced node is found matching the function

Modified: trunk/openlayers/lib/OpenLayers/Format/WFST/v1.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/WFST/v1.js	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/lib/OpenLayers/Format/WFST/v1.js	2011-06-20 10:59:28 UTC (rev 12110)
@@ -140,7 +140,7 @@
         }
         var obj = {};
         if(data) {
-            this.readNode(data, obj);
+            this.readNode(data, obj, true);
         }
         if(obj.features && options.output === "features") {
             obj = obj.features;

Modified: trunk/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js	2011-06-20 10:59:28 UTC (rev 12110)
@@ -63,6 +63,29 @@
     },
     
     /**
+     * Method: readNode
+     * Shorthand for applying one of the named readers given the node
+     *     namespace and local name.  Readers take two args (node, obj) and
+     *     generally extend or modify the second.
+     *
+     * Parameters:
+     * node - {DOMElement} The node to be read (required).
+     * obj - {Object} The object to be modified (optional).
+     * first - {Boolean} Should be set to true for the first node read. This
+     *     is usually the readNode call in the read method. Without this being
+     *     set, auto-configured properties will stick on subsequent reads.
+     *
+     * Returns:
+     * {Object} The input object, modified (or a new one if none was provided).
+     */
+    readNode: function(node, obj, first) {
+        // Not the superclass, only the mixin classes inherit from
+        // Format.GML.v2. We need this because we don't want to get readNode
+        // from the superclass's superclass, which is OpenLayers.Format.XML.
+        return OpenLayers.Format.GML.v2.prototype.readNode.apply(this, [node, obj]);
+    },
+    
+    /**
      * Property: readers
      * Contains public functions, grouped by namespace prefix, that will
      *     be applied when a namespaced node is found matching the function

Modified: trunk/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js	2011-06-20 10:59:28 UTC (rev 12110)
@@ -62,6 +62,29 @@
     },
     
     /**
+     * Method: readNode
+     * Shorthand for applying one of the named readers given the node
+     *     namespace and local name.  Readers take two args (node, obj) and
+     *     generally extend or modify the second.
+     *
+     * Parameters:
+     * node - {DOMElement} The node to be read (required).
+     * obj - {Object} The object to be modified (optional).
+     * first - {Boolean} Should be set to true for the first node read. This
+     *     is usually the readNode call in the read method. Without this being
+     *     set, auto-configured properties will stick on subsequent reads.
+     *
+     * Returns:
+     * {Object} The input object, modified (or a new one if none was provided).
+     */
+    readNode: function(node, obj, first) {
+        // Not the superclass, only the mixin classes inherit from
+        // Format.GML.v3. We need this because we don't want to get readNode
+        // from the superclass's superclass, which is OpenLayers.Format.XML.
+        return OpenLayers.Format.GML.v3.prototype.readNode.apply(this, [node, obj]);
+    },
+    
+    /**
      * Property: readers
      * Contains public functions, grouped by namespace prefix, that will
      *     be applied when a namespaced node is found matching the function

Modified: trunk/openlayers/lib/OpenLayers/Protocol/WFS/v1.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Protocol/WFS/v1.js	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/lib/OpenLayers/Protocol/WFS/v1.js	2011-06-20 10:59:28 UTC (rev 12110)
@@ -116,17 +116,6 @@
                 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);
-            };
-        }
     },
     
     /**

Modified: trunk/openlayers/tests/Format/GML/v2.html
===================================================================
--- trunk/openlayers/tests/Format/GML/v2.html	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/tests/Format/GML/v2.html	2011-06-20 10:59:28 UTC (rev 12110)
@@ -177,6 +177,21 @@
         t.eq(attributes["LAND_KM"], "143986.61", "read LAND_KM");
     }
 
+    function test_read_autoconfig(t) {
+        t.plan(5);
+        var doc = readXML("v2/topp-states.xml");
+        var format = new OpenLayers.Format.GML.v2();
+        var features = format.read(doc.documentElement);
+        
+        t.eq(features.length, 3, "read 3 features");
+        var feature = features[0];
+        t.eq(feature.fid, "states.1", "read fid");
+        t.eq(feature.geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon",
+             "read multipolygon geometry");
+        t.eq(format.featureType, "states", "featureType correctly auto-configured");
+        t.eq(format.featureNS, "http://www.openplans.org/topp", "featureNS correctly auto-configured");
+    }
+    
     function test_boundedBy(t) {
         t.plan(5);
         
@@ -248,6 +263,7 @@
         t.eq(bounds.right, 337568, "bounds right correct");
         t.eq(bounds.top, 6885985, "bounds top correct");
     }
+
    </script>
 </head>
 <body>

Modified: trunk/openlayers/tests/Format/GML/v3.html
===================================================================
--- trunk/openlayers/tests/Format/GML/v3.html	2011-06-20 07:47:52 UTC (rev 12109)
+++ trunk/openlayers/tests/Format/GML/v3.html	2011-06-20 10:59:28 UTC (rev 12110)
@@ -212,6 +212,26 @@
         t.eq(attributes["LAND_KM"], "143986.61", "read LAND_KM");
     }
     
+    function test_read_autoconfig(t) {
+        t.plan(7);
+        var doc = readXML("v3/topp-states-wfs.xml");
+        var format = new OpenLayers.Format.GML.v3();
+        var features = format.read(doc.documentElement);
+        
+        t.eq(features.length, 3, "read 3 features");
+        var feature = features[0];
+        t.eq(feature.fid, "states.1", "read fid");
+        t.eq(feature.geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon",
+             "read multipolygon geometry");
+        t.eq(format.featureType, "states", "featureType correctly auto-configured");
+        t.eq(format.featureNS, "http://www.openplans.org/topp", "featureNS correctly auto-configured");
+
+        t.eq(format.autoConfig, true, "autoConfig set to true");
+        format.autoConfig = false;
+        format.read(doc.documentElement);
+        t.eq(format.autoConfig, false, "now that featureNS is set, the format does not auto-configure again");
+    }
+    
     function test_emptyAttribute(t) {
         t.plan(4);
         var str =



More information about the Commits mailing list