diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index 82249753f7..fe395f7ddf 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -296,6 +296,7 @@ "OpenLayers/Format/SLD.js", "OpenLayers/Format/SLD/v1.js", "OpenLayers/Format/SLD/v1_0_0.js", + "OpenLayers/Format/OWSCommon.js", "OpenLayers/Format/OWSCommon/v1.js", "OpenLayers/Format/OWSCommon/v1_0_0.js", "OpenLayers/Format/OWSCommon/v1_1_0.js", @@ -334,6 +335,7 @@ "OpenLayers/Format/XLS.js", "OpenLayers/Format/XLS/v1.js", "OpenLayers/Format/XLS/v1_1_0.js", + "OpenLayers/Format/OGCExceptionReport.js", "OpenLayers/Layer/WFS.js", "OpenLayers/Control/GetFeature.js", "OpenLayers/Control/MouseToolbar.js", diff --git a/lib/OpenLayers/Format/OGCExceptionReport.js b/lib/OpenLayers/Format/OGCExceptionReport.js new file mode 100644 index 0000000000..12bee74a80 --- /dev/null +++ b/lib/OpenLayers/Format/OGCExceptionReport.js @@ -0,0 +1,110 @@ +/* Copyright (c) 2006-2011 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/Format/XML.js + * @requires OpenLayers/Format/OWSCommon/v1_0_0.js + * @requires OpenLayers/Format/OWSCommon/v1_1_0.js + */ + +/** + * Class: OpenLayers.Format.OGCExceptionReport + * Class to read exception reports for various OGC services and versions. + * + * Inherits from: + * - + */ +OpenLayers.Format.OGCExceptionReport = OpenLayers.Class(OpenLayers.Format.XML, { + + /** + * Property: namespaces + * {Object} Mapping of namespace aliases to namespace URIs. + */ + namespaces: { + ogc: "http://www.opengis.net/ogc" + }, + + /** + * Property: regExes + * Compiled regular expressions for manipulating strings. + */ + regExes: { + trimSpace: (/^\s*|\s*$/g), + removeSpace: (/\s*/g), + splitSpace: (/\s+/), + trimComma: (/\s*,\s*/g) + }, + + /** + * Property: defaultPrefix + */ + defaultPrefix: "ogc", + + /** + * Constructor: OpenLayers.Format.OGCExceptionReport + * Create a new parser for OGC exception reports. + * + * Parameters: + * options - {Object} An optional object whose properties will be set on + * this instance. + */ + + /** + * APIMethod: read + * Read OGC exception report data from a string, and return an object with + * information about the exceptions. + * + * Parameters: + * data - {String} or {DOMElement} data to read/parse. + * + * Returns: + * {Object} Information about the exceptions that occurred. + */ + read: function(data) { + var result; + if(typeof data == "string") { + data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); + } + var root = data.documentElement; + var exceptionInfo = {exceptionReport: null}; + if (root) { + this.readChildNodes(data, exceptionInfo); + if (exceptionInfo.exceptionReport === null) { + // fall-back to OWSCommon since this is a common output format for exceptions + // we cannot easily use the ows readers directly since they differ for 1.0 and 1.1 + exceptionInfo = new OpenLayers.Format.OWSCommon().read(data); + } + } + return exceptionInfo; + }, + + /** + * Property: readers + * Contains public functions, grouped by namespace prefix, that will + * be applied when a namespaced node is found matching the function + * name. The function will be applied in the scope of this parser + * with two arguments: the node being read and a context object passed + * from the parent. + */ + readers: { + "ogc": { + "ServiceExceptionReport": function(node, obj) { + obj.exceptionReport = {exceptions: []}; + this.readChildNodes(node, obj.exceptionReport); + }, + "ServiceException": function(node, exceptionReport) { + var exception = { + code: node.getAttribute("code"), + locator: node.getAttribute("locator"), + text: this.getChildValue(node) + }; + exceptionReport.exceptions.push(exception); + } + } + }, + + CLASS_NAME: "OpenLayers.Format.OGCExceptionReport" + +}); diff --git a/lib/OpenLayers/Format/OWSCommon.js b/lib/OpenLayers/Format/OWSCommon.js new file mode 100644 index 0000000000..db975f2be9 --- /dev/null +++ b/lib/OpenLayers/Format/OWSCommon.js @@ -0,0 +1,91 @@ +/* Copyright (c) 2006-2011 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/Format/XML.js + */ + +/** + * Class: OpenLayers.Format.OWSCommon + * Read OWSCommon. Create a new instance with the + * constructor. + * + * Inherits from: + * - + */ +OpenLayers.Format.OWSCommon = OpenLayers.Class(OpenLayers.Format.XML, { + + /** + * APIProperty: defaultVersion + * {String} Version number to assume if none found. Default is "1.0.0". + */ + defaultVersion: "1.0.0", + + /** + * APIProperty: version + * {String} Specify a version string if one is known. + */ + version: null, + + /** + * Property: parser + * {Object} Instance of the versioned parser. Cached for multiple read and + * write calls of the same version. + */ + parser: null, + + /** + * Constructor: OpenLayers.Format.OWSCommon + * Create a new parser for OWSCommon. + * + * Parameters: + * options - {Object} An optional object whose properties will be set on + * this instance. + */ + + /** + * APIMethod: read + * Read an OWSCommon document and return an object. + * + * Parameters: + * data - {String | DOMElement} Data to read. + * options - {Object} Options for the reader. + * + * Returns: + * {Object} An object representing the structure of the document. + */ + read: function(data, options) { + if(typeof data == "string") { + data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); + } + var root = data.documentElement; + var version = this.version; + if(!version) { + // remember version does not correspond to the OWS version + // it corresponds to the WMS/WFS/WCS etc. request version + var uri = root.getAttribute("xmlns:ows"); + if (uri.substring(uri.lastIndexOf("/")+1) === "1.1") { + version ="1.1.0"; + } + if(!version) { + version = this.defaultVersion; + } + } + if(!this.parser || this.parser.VERSION != version) { + var format = OpenLayers.Format.OWSCommon[ + "v" + version.replace(/\./g, "_") + ]; + if(!format) { + throw "Can't find a OWSCommon parser for version " + + version; + } + this.parser = new format(this.options); + } + var ows = this.parser.read(data, options); + return ows; + }, + + CLASS_NAME: "OpenLayers.Format.OWSCommon" +}); diff --git a/lib/OpenLayers/Format/OWSCommon/v1.js b/lib/OpenLayers/Format/OWSCommon/v1.js index 4716b17461..924d25874e 100644 --- a/lib/OpenLayers/Format/OWSCommon/v1.js +++ b/lib/OpenLayers/Format/OWSCommon/v1.js @@ -4,13 +4,9 @@ * full text of the license. */ /** - * @requires OpenLayers/Format/XML.js + * @requires OpenLayers/Format/OWSCommon.js */ -if (!OpenLayers.Format.OWSCommon) { - OpenLayers.Format.OWSCommon = {}; -} - /** * Class: OpenLayers.Format.OWSCommon.v1 * Common readers and writers for OWSCommon v1.X formats @@ -28,6 +24,23 @@ OpenLayers.Format.OWSCommon.v1 = OpenLayers.Class(OpenLayers.Format.XML, { trimComma: (/\s*,\s*/g) }, + /** + * Method: read + * + * Parameters: + * data - {DOMElement} An OWSCommon document element. + * options - {Object} Options for the reader. + * + * Returns: + * {Object} An object representing the OWSCommon document. + */ + read: function(data, options) { + options = OpenLayers.Util.applyDefaults(options, this.options); + var ows = {}; + this.readChildNodes(data, ows); + return ows; + }, + /** * Property: readers * Contains public functions, grouped by namespace prefix, that will @@ -38,6 +51,19 @@ OpenLayers.Format.OWSCommon.v1 = OpenLayers.Class(OpenLayers.Format.XML, { */ readers: { "ows": { + "Exception": function(node, exceptionReport) { + var exception = { + code: node.getAttribute('exceptionCode'), + locator: node.getAttribute('locator'), + texts: [] + }; + exceptionReport.exceptions.push(exception); + this.readChildNodes(node, exception); + }, + "ExceptionText": function(node, exception) { + var text = this.getChildValue(node); + exception.texts.push(text); + }, "ServiceIdentification": function(node, obj) { obj.serviceIdentification = {}; this.readChildNodes(node, obj.serviceIdentification); diff --git a/lib/OpenLayers/Format/OWSCommon/v1_0_0.js b/lib/OpenLayers/Format/OWSCommon/v1_0_0.js index f864b9b00a..590cca3b6c 100644 --- a/lib/OpenLayers/Format/OWSCommon/v1_0_0.js +++ b/lib/OpenLayers/Format/OWSCommon/v1_0_0.js @@ -9,8 +9,7 @@ /** * Class: OpenLayers.Format.OWSCommon.v1_0_0 - * Parser for OWS Common version 1.0.0 which can be used by other parsers. - * It is not intended to be used on its own. + * Parser for OWS Common version 1.0.0. */ OpenLayers.Format.OWSCommon.v1_0_0 = OpenLayers.Class(OpenLayers.Format.OWSCommon.v1, { @@ -19,7 +18,7 @@ OpenLayers.Format.OWSCommon.v1_0_0 = OpenLayers.Class(OpenLayers.Format.OWSCommo * {Object} Mapping of namespace aliases to namespace URIs. */ namespaces: { - ows: "http://www.opengis.net/ows/1.0", + ows: "http://www.opengis.net/ows", xlink: "http://www.w3.org/1999/xlink" }, @@ -32,7 +31,16 @@ OpenLayers.Format.OWSCommon.v1_0_0 = OpenLayers.Class(OpenLayers.Format.OWSCommo * from the parent. */ readers: { - "ows": OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"] + "ows": OpenLayers.Util.applyDefaults({ + "ExceptionReport": function(node, obj) { + obj.exceptionReport = { + version: node.getAttribute('version'), + language: node.getAttribute('language'), + exceptions: [] + }; + this.readChildNodes(node, obj.exceptionReport); + } + }, OpenLayers.Format.OWSCommon.v1.prototype.readers.ows) }, /** @@ -42,9 +50,9 @@ OpenLayers.Format.OWSCommon.v1_0_0 = OpenLayers.Class(OpenLayers.Format.OWSCommo * node names they produce. */ writers: { - "ows": OpenLayers.Format.OWSCommon.v1.prototype.writers["ows"] + "ows": OpenLayers.Format.OWSCommon.v1.prototype.writers.ows }, - CLASS_NAME: "OpenLayers.Format.OWSCommon.v1_1_0" + CLASS_NAME: "OpenLayers.Format.OWSCommon.v1_0_0" }); diff --git a/lib/OpenLayers/Format/OWSCommon/v1_1_0.js b/lib/OpenLayers/Format/OWSCommon/v1_1_0.js index 3c5aad03aa..167d6dfc59 100644 --- a/lib/OpenLayers/Format/OWSCommon/v1_1_0.js +++ b/lib/OpenLayers/Format/OWSCommon/v1_1_0.js @@ -9,8 +9,7 @@ /** * Class: OpenLayers.Format.OWSCommon.v1_1_0 - * Parser for OWS Common version 1.1.0 which can be used by other parsers. - * It is not intended to be used on its own. + * Parser for OWS Common version 1.1.0. */ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.OWSCommon.v1, { @@ -33,6 +32,14 @@ OpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.OWSCommo */ readers: { "ows": OpenLayers.Util.applyDefaults({ + "ExceptionReport": function(node, obj) { + obj.exceptionReport = { + version: node.getAttribute('version'), + language: node.getAttribute('xml:lang'), + exceptions: [] + }; + this.readChildNodes(node, obj.exceptionReport); + }, "AllowedValues": function(node, parameter) { parameter.allowedValues = {}; this.readChildNodes(node, parameter.allowedValues); diff --git a/lib/OpenLayers/Format/WFSCapabilities.js b/lib/OpenLayers/Format/WFSCapabilities.js index 0c6d4460c9..45f62a5af2 100644 --- a/lib/OpenLayers/Format/WFSCapabilities.js +++ b/lib/OpenLayers/Format/WFSCapabilities.js @@ -5,6 +5,7 @@ /** * @requires OpenLayers/Format/XML.js + * @requires OpenLayers/Format/OGCExceptionReport.js */ /** @@ -67,6 +68,11 @@ OpenLayers.Format.WFSCapabilities = OpenLayers.Class(OpenLayers.Format.XML, { } var parser = new constr(this.options); var capabilities = parser.read(data); + if (capabilities.service === undefined) { + // an error must have happened, so parse it and report back + var format = new OpenLayers.Format.OGCExceptionReport(); + capabilities.error = format.read(data); + } capabilities.version = version; return capabilities; }, diff --git a/lib/OpenLayers/Format/WMSCapabilities/v1.js b/lib/OpenLayers/Format/WMSCapabilities/v1.js index b715bfd6e8..2c693aa468 100644 --- a/lib/OpenLayers/Format/WMSCapabilities/v1.js +++ b/lib/OpenLayers/Format/WMSCapabilities/v1.js @@ -5,6 +5,7 @@ /** * @requires OpenLayers/Format/WMSCapabilities.js + * @requires OpenLayers/Format/OGCExceptionReport.js * @requires OpenLayers/Format/XML.js */ @@ -60,15 +61,20 @@ OpenLayers.Format.WMSCapabilities.v1 = OpenLayers.Class( if(typeof data == "string") { data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); } + var raw = data; if(data && data.nodeType == 9) { data = data.documentElement; } var capabilities = {}; this.readNode(data, capabilities); - - // postprocess the layer list - this.postProcessLayers(capabilities); - + if (capabilities.service === undefined) { + // an exception must have occurred, so parse it + var parser = new OpenLayers.Format.OGCExceptionReport(); + capabilities.error = parser.read(raw); + } else { + // postprocess the layer list + this.postProcessLayers(capabilities); + } return capabilities; }, diff --git a/tests/Format/OGCExceptionReport.html b/tests/Format/OGCExceptionReport.html new file mode 100644 index 0000000000..7846f94290 --- /dev/null +++ b/tests/Format/OGCExceptionReport.html @@ -0,0 +1,100 @@ + + + + + + + + diff --git a/tests/Format/OWSCommon/v1_0_0.html b/tests/Format/OWSCommon/v1_0_0.html new file mode 100644 index 0000000000..9d255b2252 --- /dev/null +++ b/tests/Format/OWSCommon/v1_0_0.html @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/tests/Format/OWSCommon/v1_1_0.html b/tests/Format/OWSCommon/v1_1_0.html new file mode 100644 index 0000000000..e899ea8486 --- /dev/null +++ b/tests/Format/OWSCommon/v1_1_0.html @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/tests/Format/WFSCapabilities/v1.html b/tests/Format/WFSCapabilities/v1.html index f574fff925..d7132701dc 100644 --- a/tests/Format/WFSCapabilities/v1.html +++ b/tests/Format/WFSCapabilities/v1.html @@ -2,6 +2,23 @@