diff --git a/src/ol/geom/Collection.js b/src/ol/geom/Collection.js index ddd7a9e935..fd6b82b7bc 100644 --- a/src/ol/geom/Collection.js +++ b/src/ol/geom/Collection.js @@ -13,16 +13,65 @@ goog.require('ol.Projection'); * @constructor */ ol.geom.Collection = function(components) { + + /** + * @private + * @type {Array.} + */ + this.typeBlacklist_ = [ + ol.geom.Collection + ]; + + /** + * @private + * @type {Array.} + */ + this.typeWhitelist_ = []; + /** * @private * @type {Array.} */ - this.components_ = components; + this.components_ = []; + if (arguments.length === 1 && goog.isDef(components)) { + this.setComponents(components); + } }; goog.inherits(ol.geom.Collection, ol.geom.Geometry); +/** + * Sets the list of disallowed types for the collection. + * @param {Array.} typeBlacklist Array of constructors to disallow. + */ +ol.geom.Collection.prototype.setTypeBlacklist = function(typeBlacklist){ + this.typeBlacklist_ = typeBlacklist; +}; +/** + * Gets the list of disallowed types for the collection. + * @return {Array.} Array of constructors to disallow. + */ +ol.geom.Collection.prototype.getTypeBlacklist = function(){ + return this.typeBlacklist_; +}; + +/** + * Sets the list of always allowed types for the collection. + * @param {Array.} typeWhitelist Array of constructors to allow. + */ +ol.geom.Collection.prototype.setTypeWhitelist = function(typeWhitelist){ + this.typeWhitelist_ = typeWhitelist; +}; +/** + * Gets the list of always allowed types for the collection. + * @return {Array.} Array of constructors to allow. + */ +ol.geom.Collection.prototype.getTypeWhitelist = function(){ + return this.typeWhitelist_; +}; + + /** * Sets the Collection's components. * @@ -38,7 +87,17 @@ ol.geom.Collection.prototype.getComponents = function() { * @param {Array.} components An array of components. */ ol.geom.Collection.prototype.setComponents = function(components) { - this.components_ = components; + var allValidTypes = goog.array.every( + components, + this.isAllowedComponent, + this + ); + if (allValidTypes) { + this.components_ = components; + } else { + throw new Error('ol.geom.Collection: at least one component passed to ' + + 'setComponents is not allowed.'); + } }; /** @@ -48,7 +107,52 @@ ol.geom.Collection.prototype.setComponents = function(components) { * @param {number} index The index where to add. */ ol.geom.Collection.prototype.addComponent = function(component, index) { - goog.array.insertAt(this.components_,component,index); + if (this.isAllowedComponent(component)) { + goog.array.insertAt(this.components_, component, index); + } else { + throw new Error("ol.geom.Collection: The component is not allowed " + + "to be added."); + } +}; + +/** + * Checks whether the passed component is an instance of any of the constructors + * listed in the passed list. + * + * @param {ol.geom.Geometry} component The component to check. + * @param {Array.} list The List of constructors to check the + * component against. + * + * @return {boolean} Whether the passed component is an instance of any of the + * constructors listed in the passed list. + * + * @private + */ +ol.geom.Collection.prototype.isOnList = function(component, list) { + var isOnList = !goog.array.every(list, function(listedConstr){ + if (component instanceof listedConstr) { + return false; + } else { + return true; + } + }); + return isOnList; +}; + +/** + * Checks whether the passed component is allowed according to the black and + * whitelists. + * + * @param {ol.geom.Geometry} component The component to check. + * @return {boolean} Whether the passed component is allowed as part of this + * collection according to black- and whitelist. + */ +ol.geom.Collection.prototype.isAllowedComponent = function(component){ + var whitelist = this.getTypeWhitelist(), + blacklist = this.getTypeBlacklist(), + isOnWhitelist = this.isOnList(component, whitelist), + isOnBlacklist = this.isOnList(component, blacklist); + return (isOnWhitelist || !isOnBlacklist); }; /** diff --git a/test/spec/ol/geom/Collection.test.js b/test/spec/ol/geom/Collection.test.js index 866592554e..0986459aab 100644 --- a/test/spec/ol/geom/Collection.test.js +++ b/test/spec/ol/geom/Collection.test.js @@ -29,6 +29,16 @@ describe("ol.geom.Collection", function() { expect( c ).toBeA( ol.geom.Collection ); }); + it("cannot construct instances when passed illegal components", function() { + // collection cannot contain collections + expect(function(){ + c = new ol.geom.Collection([ + new ol.geom.Collection() + ]); + }).toThrow(); + + }); + it("inherits from ol.geom.Geometry", function() { expect( c ).toBeA( ol.geom.Geometry ); }); @@ -81,7 +91,7 @@ describe("ol.geom.Collection", function() { ]), 0 ); - + var components = c.getComponents(); expect( components.length ).toBe( 4 ); @@ -92,6 +102,17 @@ describe("ol.geom.Collection", function() { }); + it("cannot add instances of 'ol.geom.Collection'", function(){ + expect(function(){ + c.addComponent( + new ol.geom.Collection([ + new ol.geom.Point(5,25), + new ol.geom.Point(6,36) + ]) + ); + }).toThrow(); + }); + it("has a method to remove components", function() { c.setComponents([ new ol.geom.Point(0,10),