From fe2bee1577de21db57da9e5ee85f2ae212b18dba Mon Sep 17 00:00:00 2001 From: Hadrien Tulipe Date: Sun, 16 Mar 2014 19:47:13 +0100 Subject: [PATCH] Add basic reading support for OWS Capabilities document. --- src/ol/format/owscapabilitiesformat.js | 511 ++++++++++++++++++ .../ol/format/owscapabilitiesformat.test.js | 154 ++++++ 2 files changed, 665 insertions(+) create mode 100644 src/ol/format/owscapabilitiesformat.js create mode 100644 test/spec/ol/format/owscapabilitiesformat.test.js diff --git a/src/ol/format/owscapabilitiesformat.js b/src/ol/format/owscapabilitiesformat.js new file mode 100644 index 0000000000..c525bd6aa2 --- /dev/null +++ b/src/ol/format/owscapabilitiesformat.js @@ -0,0 +1,511 @@ +goog.provide('ol.format.OWSCapabilities'); + +goog.require('goog.asserts'); +goog.require('goog.dom.NodeType'); +goog.require('goog.object'); +goog.require('ol.format.XLink'); +goog.require('ol.format.XML'); +goog.require('ol.format.XSD'); +goog.require('ol.xml'); + + + +/** + * @constructor + * @extends {ol.format.XML} + */ +ol.format.OWSCapabilities = function() { + goog.base(this); +}; +goog.inherits(ol.format.OWSCapabilities, ol.format.XML); + + +/** + * @param {Document} doc Document. + * @return {Object} OWS object. + */ +ol.format.OWSCapabilities.prototype.readFromDocument = function(doc) { + goog.asserts.assert(doc.nodeType == goog.dom.NodeType.DOCUMENT); + for (var n = doc.firstChild; !goog.isNull(n); n = n.nextSibling) { + if (n.nodeType == goog.dom.NodeType.ELEMENT) { + return this.readFromNode(n); + } + } + return null; +}; + + +/** + * @param {Node} node Node. + * @return {Object} OWS object. + */ +ol.format.OWSCapabilities.prototype.readFromNode = function(node) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + var owsObject = ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.PARSERS_, node, []); + return goog.isDef(owsObject) ? owsObject : null; +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readAddress_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Address'); + return ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.ADDRESS_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readAllowedValues_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'AllowedValues'); + return ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.ALLOWED_VALUES_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readConstraint_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Constraint'); + var object = objectStack[objectStack.length - 1]; + goog.asserts.assert(goog.isObject(object)); + var name = node.getAttribute('name'); + var value = ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.CONSTRAINT_PARSERS_, node, + objectStack); + if (!goog.isDef(object.constraints)) { + object.constraints = {}; + } + object.constraints[name] = value; + +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readContactInfo_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ContactInfo'); + return ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.CONTACT_INFO_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readDcp_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'DCP'); + return ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.DCP_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readGet_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Get'); + var object = objectStack[objectStack.length - 1]; + var url = ol.format.XLink.readHref(node); + goog.asserts.assert(goog.isObject(object)); + var value = ol.xml.pushParseAndPop({'url': url}, + ol.format.OWSCapabilities.REQUEST_METHOD_PARSERS_, node, objectStack); + if (!goog.isDef(object.get)) { + goog.object.set(object, 'get', [value]); + }else { + goog.asserts.assert(goog.isArray(object.get)); + object.get.push(value); + } + +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readHttp_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'HTTP'); + /*var rawArray = ol.xml.pushParseAndPop([], + ol.format.OWSCapabilities.HTTP_PARSERS_, node, objectStack); + var object = {}; + goog.array.forEach(rawArray,function(item){ + if(goog.isDef(object[item.method])){ + object[item.method].push(item.url); + } else { + object[item.method] = [item.url]; + } + });*/ + return ol.xml.pushParseAndPop({}, ol.format.OWSCapabilities.HTTP_PARSERS_, + node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readOperation_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Operation'); + var name = node.getAttribute('name'); + var value = ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.OPERATION_PARSERS_, node, objectStack); + var object = /** @type {Object} */ + (objectStack[objectStack.length - 1]); + goog.asserts.assert(goog.isObject(object)); + goog.object.set(object, name, value); + +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readOperationsMetadata_ = function(node, + objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'OperationsMetadata'); + return ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.OPERATIONS_METADATA_PARSERS_, node, + objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readPhone_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Phone'); + return ol.xml.pushParseAndPop({}, + ol.format.OWSCapabilities.PHONE_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readServiceIdentification_ = function(node, + objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ServiceIdentification'); + return ol.xml.pushParseAndPop( + {}, ol.format.OWSCapabilities.SERVICE_IDENTIFICATION_PARSERS_, node, + objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readServiceContact_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ServiceContact'); + return ol.xml.pushParseAndPop( + {}, ol.format.OWSCapabilities.SERVICE_CONTACT_PARSERS_, node, + objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readServiceProvider_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ServiceProvider'); + return ol.xml.pushParseAndPop( + {}, ol.format.OWSCapabilities.SERVICE_PROVIDER_PARSERS_, node, + objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} + */ +ol.format.OWSCapabilities.readValue_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Value'); + var object = objectStack[objectStack.length - 1]; + goog.asserts.assert(goog.isObject(object)); + var key = /** @type {string} */ (ol.format.XSD.readString(node)); + goog.object.set(object, key, true); +}; + + +/** + * @const + * @type {Array.} + * @private + */ +ol.format.OWSCapabilities.NAMESPACE_URIS_ = [ + null, + 'http://www.opengis.net/ows/1.1' +]; + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'ServiceIdentification' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readServiceIdentification_, + 'serviceIdentification'), + 'ServiceProvider' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readServiceProvider_, + 'serviceProvider'), + 'OperationsMetadata': ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readOperationsMetadata_, + 'operationsMetadata') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.ADDRESS_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'DeliveryPoint' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'deliveryPoint'), + 'City' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'city'), + 'AdministrativeArea' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'administrativeArea'), + 'PostalCode' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'postalCode'), + 'Country' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'country'), + 'ElectronicMailAddress' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'electronicMailAddress') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.ALLOWED_VALUES_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Value': ol.format.OWSCapabilities.readValue_ + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.CONSTRAINT_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'AllowedValues': ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readAllowedValues_, 'allowedValues' + ) + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.CONTACT_INFO_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Phone' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readPhone_, 'phone'), + 'Address' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readAddress_, 'address') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.DCP_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'HTTP' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readHttp_, 'http') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.HTTP_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Get': ol.format.OWSCapabilities.readGet_, + 'Post': undefined // TODO + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.OPERATION_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'DCP' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readDcp_, 'dcp') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.OPERATIONS_METADATA_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Operation' : ol.format.OWSCapabilities.readOperation_ + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.PHONE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Voice' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'voice'), + 'Facsimile' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'facsimile') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.REQUEST_METHOD_PARSERS_ = ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Constraint': ol.format.OWSCapabilities.readConstraint_ + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.SERVICE_CONTACT_PARSERS_ = + ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'IndividualName' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'individualName'), + 'PositionName' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'positionName'), + 'ContactInfo' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readContactInfo_, 'contactInfo') + } + ); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.SERVICE_IDENTIFICATION_PARSERS_ = + ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'Title' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'title'), + 'ServiceTypeVersion' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'serviceTypeVersion'), + 'ServiceType' : ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString, 'serviceType') + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.OWSCapabilities.SERVICE_PROVIDER_PARSERS_ = + ol.xml.makeParsersNS( + ol.format.OWSCapabilities.NAMESPACE_URIS_, { + 'ProviderName' : ol.xml.makeObjectPropertySetter(ol.format.XSD.readString, + 'providerName'), + 'ProviderSite' : ol.xml.makeObjectPropertySetter(ol.format.XLink.readHref, + 'providerSite'), + 'ServiceContact' : ol.xml.makeObjectPropertySetter( + ol.format.OWSCapabilities.readServiceContact_, 'serviceContact') + } + ); diff --git a/test/spec/ol/format/owscapabilitiesformat.test.js b/test/spec/ol/format/owscapabilitiesformat.test.js new file mode 100644 index 0000000000..d0db568d13 --- /dev/null +++ b/test/spec/ol/format/owscapabilitiesformat.test.js @@ -0,0 +1,154 @@ +goog.provide('ol.test.format.OWSCapabilities'); + +goog.require('ol.xml'); + +describe('ol.format.OWSCapabilities 1.1', function() { + + var parser = new ol.format.OWSCapabilities(); + + it('should read ServiceProvider tag properly', function() { + var doc = ol.xml.load( + '' + + '' + + 'MiraMon' + + '' + + '' + + 'Joan Maso Pau' + + '' + + 'Senior Software Engineer' + + '' + + '' + + '' + + '+34 93 581 1312' + + '+34 93 581 4151' + + '' + + '' + + '' + + 'Fac Ciencies UAB' + + '' + + 'Bellaterra' + + 'Barcelona' + + '' + + '08193' + + 'Spain' + + 'joan.maso@uab.es' + + '' + + '' + + '' + + '' + + '' + + '' + ); + + var obj = parser.read(doc); + expect(obj).to.be.ok(); + var serviceProvider = obj.serviceProvider; + expect(serviceProvider).to.be.ok(); + expect(serviceProvider.providerName).to.eql('MiraMon'); + var url = 'http://www.creaf.uab.es/miramon'; + expect(serviceProvider.providerSite).to.eql(url); + var name = 'Joan Maso Pau'; + expect(serviceProvider.serviceContact.individualName).to.eql(name); + var position = 'Senior Software Engineer'; + expect(serviceProvider.serviceContact.positionName).to.eql(position); + }); + + it('should read ServiceIdentification tag properly', function() { + var doc = ol.xml.load( + '' + + '' + + 'Web Map Tile Service' + + 'Service that contrains the map access interface ' + + 'to some TileMatrixSets' + + '' + + 'tile' + + 'tile matrix set' + + 'map' + + '' + + 'OGC WMTS' + + '1.0.0' + + 'none' + + 'none' + + '' + + '' + ); + var obj = parser.readFromNode(doc.firstChild); + expect(obj).to.be.ok(); + + var serviceIdentification = obj.serviceIdentification; + expect(serviceIdentification).to.be.ok(); + expect(serviceIdentification.title).to.eql('Web Map Tile Service'); + expect(serviceIdentification.serviceTypeVersion).to.eql('1.0.0'); + expect(serviceIdentification.serviceType).to.eql('OGC WMTS'); + }); + + it('should read OperationsMetadata tag properly', function() { + var doc = ol.xml.load( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + 'KVP' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + ); + var obj = parser.readFromNode(doc.firstChild); + expect(obj).to.be.ok(); + + var operationsMetadata = obj.operationsMetadata; + expect(operationsMetadata).to.be.ok(); + var dcp = operationsMetadata.GetCapabilities.dcp; + var url = 'http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?'; + expect(dcp.http.get[0].url).to.eql(url); + dcp = operationsMetadata.GetCapabilities.dcp; + expect(dcp.http.get[0].constraints.GetEncoding.allowedValues).to.eql( + {'KVP': true}); + url = 'http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?'; + dcp = operationsMetadata.GetFeatureInfo.dcp; + expect(dcp.http.get[0].url).to.eql(url); + dcp = operationsMetadata.GetFeatureInfo.dcp; + expect(dcp.http.get[0].constraints).to.be(undefined); + url = 'http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?'; + expect(operationsMetadata.GetTile.dcp.http.get[0].url).to.eql(url); + dcp = operationsMetadata.GetTile.dcp; + expect(dcp.http.get[0].constraints).to.be(undefined); + }); + +}); + +goog.require('ol.format.OWSCapabilities');