Index: Core/Components/src/Core.Components.DotSpatial/Core.Components.DotSpatial.csproj =================================================================== diff -u -r8a885188327983ccc75c5ae70c6abf91fb6cdac1 -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Core.Components.DotSpatial.csproj (.../Core.Components.DotSpatial.csproj) (revision 8a885188327983ccc75c5ae70c6abf91fb6cdac1) +++ Core/Components/src/Core.Components.DotSpatial/Core.Components.DotSpatial.csproj (.../Core.Components.DotSpatial.csproj) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -98,6 +98,7 @@ + Index: Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/IConfiguration.cs =================================================================== diff -u -r825240f8a4a6b63e3845195ff3366e4c58628c1b -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/IConfiguration.cs (.../IConfiguration.cs) (revision 825240f8a4a6b63e3845195ff3366e4c58628c1b) +++ Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/IConfiguration.cs (.../IConfiguration.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -61,6 +61,10 @@ /// Gets a deep copy of the configuration. /// /// The cloned configuration. + /// Thrown when calling this method while + /// this instance is disposed. + /// Thrown when creating the file + /// cache failed. IConfiguration Clone(); /// @@ -72,6 +76,8 @@ /// tile cache cannot be created. /// Thrown when /// doesn't allow for tiles to be received. + /// Thrown when calling this method while + /// this instance is disposed. void Initialize(); } } \ No newline at end of file Index: Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/PersistentCacheConfiguration.cs =================================================================== diff -u -rfa3b352bc1b1c01fc73a9a45268c5573807a6381 -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/PersistentCacheConfiguration.cs (.../PersistentCacheConfiguration.cs) (revision fa3b352bc1b1c01fc73a9a45268c5573807a6381) +++ Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/PersistentCacheConfiguration.cs (.../PersistentCacheConfiguration.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -21,8 +21,10 @@ using System; using System.IO; +using BruTile; using BruTile.Cache; using Core.Common.Utils; +using Core.Components.DotSpatial.Layer.BruTile.TileFetching; using Core.Components.DotSpatial.Properties; namespace Core.Components.DotSpatial.Layer.BruTile.Configurations @@ -34,9 +36,9 @@ /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/CacheConfiguration.cs /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html /// - public abstract class PersistentCacheConfiguration + public abstract class PersistentCacheConfiguration : IConfiguration { - protected readonly string persistentCacheDirectoryPath; + protected readonly string PersistentCacheDirectoryPath; /// /// Initialized a new instance of . @@ -53,22 +55,101 @@ persistentCacheDirectoryPath), nameof(persistentCacheDirectoryPath)); } - this.persistentCacheDirectoryPath = persistentCacheDirectoryPath; + PersistentCacheDirectoryPath = persistentCacheDirectoryPath; } + public string LegendText { get; protected set; } + public ITileSource TileSource { get; private set; } + public ITileFetcher TileFetcher { get; private set; } + public bool Initialized { get; protected set; } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public abstract IConfiguration Clone(); + + public abstract void Initialize(); + + protected virtual void Dispose(bool disposing) + { + if (IsDisposed) + { + return; + } + + if (disposing) + { + TileFetcher?.Dispose(); + } + + IsDisposed = true; + } + /// + /// Initialized the configuration based on the given . + /// + /// The tile source to initialize for. + /// Thrown when a critical error + /// occurs when creating the tile cache. + /// Thrown when + /// does not allow for tiles to be retrieved. + /// Thrown when calling this method while + /// this instance is disposed. + protected void InitializeFromTileSource(ITileSource tileSource) + { + ThrowExceptionIfDisposed(); + + TileSource = tileSource; + IPersistentCache tileCache = CreateTileCache(); + try + { + ITileProvider provider = BruTileReflectionHelper.GetProviderFromTileSource(tileSource); + TileFetcher = new AsyncTileFetcher(provider, + BruTileSettings.MemoryCacheMinimum, + BruTileSettings.MemoryCacheMaximum, + tileCache); + } + catch (Exception e) when (e is NotSupportedException || e is ArgumentException) + { + throw new CannotReceiveTilesException(Resources.Configuration_InitializeFromTileSource_TileSource_does_not_allow_access_to_provider, e); + } + Initialized = true; + } + + /// + /// Thrown an when + /// is true. + /// + /// Thrown when calling this method while + /// this instance is disposed. + protected void ThrowExceptionIfDisposed() + { + if (IsDisposed) + { + throw new ObjectDisposedException(GetType().Name); + } + } + + /// /// Creates the tile cache. /// /// The file cache. /// Thrown when a critical error /// occurs when creating the tile cache. + /// Thrown when calling this method while + /// this instance is disposed. protected IPersistentCache CreateTileCache() { - if (!Directory.Exists(persistentCacheDirectoryPath)) + ThrowExceptionIfDisposed(); + + if (!Directory.Exists(PersistentCacheDirectoryPath)) { try { - Directory.CreateDirectory(persistentCacheDirectoryPath); + Directory.CreateDirectory(PersistentCacheDirectoryPath); } catch (Exception e) when (SupportedCreateDirectoryExceptions(e)) { @@ -77,10 +158,12 @@ } } - return new FileCache(persistentCacheDirectoryPath, BruTileSettings.PersistentCacheFormat, + return new FileCache(PersistentCacheDirectoryPath, BruTileSettings.PersistentCacheFormat, TimeSpan.FromDays(BruTileSettings.PersistentCacheExpireInDays)); } + private bool IsDisposed { get; set; } + private static bool SupportedCreateDirectoryExceptions(Exception exception) { return exception is IOException Index: Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfiguration.cs =================================================================== diff -u --- Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfiguration.cs (revision 0) +++ Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfiguration.cs (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -0,0 +1,122 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using System.IO; +using BruTile; +using BruTile.Predefined; +using BruTile.Web; + +namespace Core.Components.DotSpatial.Layer.BruTile.Configurations +{ + /// + /// A configuration for a connection to built-in web-based tile services. + /// + /// + /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/KnownTileLayerConfiguration.cs + /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html + /// + public class WellKnownTileSourceLayerConfiguration : PersistentCacheConfiguration + { + private readonly KnownTileSource knownTileSource; + + /// + /// Creates an instance of . + /// + /// The built-in tile provider to be used. + /// The directory path to the persistent tile cache. + /// Thrown when + /// is an invalid folder path + /// Thrown when + /// isn't a supported member. + /// Thrown when creating the file + /// cache failed. + private WellKnownTileSourceLayerConfiguration(string persistentCacheDirectoryPath, KnownTileSource knownTileSource) + : base(persistentCacheDirectoryPath) + { + this.knownTileSource = knownTileSource; + LegendText = knownTileSource.ToString(); + + HttpTileSource httpTileSource = KnownTileSources.Create(knownTileSource); + InitializeFromTileSource(httpTileSource); + } + + /// + /// Creates a new initialized instance of . + /// + /// The built-in tile provider to be used. + /// The tile source corresponding to . + /// Thrown when creating the file + /// cache failed. + private WellKnownTileSourceLayerConfiguration(KnownTileSource knownTileSource, ITileSource tileSource) + : base(SuggestTileCachePath(tileSource, knownTileSource)) + { + this.knownTileSource = knownTileSource; + LegendText = knownTileSource.ToString(); + + InitializeFromTileSource(tileSource); + } + + /// + /// Creates a fully initialized instance of . + /// + /// The built-in tile provider to be used. + /// The new . + /// Thrown when + /// isn't a supported member. + /// Thrown when creating the file + /// cache failed. + public static WellKnownTileSourceLayerConfiguration CreateInitializedConfiguration(KnownTileSource knownTileSource) + { + HttpTileSource tileSource = KnownTileSources.Create(knownTileSource); + + return new WellKnownTileSourceLayerConfiguration(knownTileSource, tileSource); + } + + public override IConfiguration Clone() + { + ThrowExceptionIfDisposed(); + + return new WellKnownTileSourceLayerConfiguration(PersistentCacheDirectoryPath, knownTileSource); + } + + public override void Initialize() + { + ThrowExceptionIfDisposed(); + + Initialized = true; + } + + private static string SuggestTileCachePath(ITileSource tileSource, KnownTileSource knownTileSource) + { + ITileSchema tileSchema = tileSource.Schema; + string host = knownTileSource.ToString(); + string format = tileSchema.Format; + + foreach (var c in Path.GetInvalidFileNameChars()) + { + host = host.Replace(c, '$'); + } + + return Path.Combine(BruTileSettings.PersistentCacheDirectoryRoot, "WellKnown", host, format); + } + } +} \ No newline at end of file Index: Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/WmtsLayerConfiguration.cs =================================================================== diff -u -r825240f8a4a6b63e3845195ff3366e4c58628c1b -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/WmtsLayerConfiguration.cs (.../WmtsLayerConfiguration.cs) (revision 825240f8a4a6b63e3845195ff3366e4c58628c1b) +++ Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/Configurations/WmtsLayerConfiguration.cs (.../WmtsLayerConfiguration.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -24,9 +24,7 @@ using System.IO; using System.Linq; using BruTile; -using BruTile.Cache; using BruTile.Wmts; -using Core.Components.DotSpatial.Layer.BruTile.TileFetching; using Core.Components.DotSpatial.Properties; namespace Core.Components.DotSpatial.Layer.BruTile.Configurations @@ -38,12 +36,11 @@ /// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/WmtsLayerConfiguration.cs /// Original license: http://www.apache.org/licenses/LICENSE-2.0.html /// - public class WmtsLayerConfiguration : PersistentCacheConfiguration, IConfiguration + public class WmtsLayerConfiguration : PersistentCacheConfiguration { private readonly string capabilitiesUri; private readonly string capabilityIdentifier; private readonly string preferredFormat; - private ITileCache tileCache; /// /// Creates an instance of . @@ -88,14 +85,6 @@ InitializeFromTileSource(tileSource); } - public bool Initialized { get; private set; } - - public string LegendText { get; } - - public ITileSource TileSource { get; private set; } - - public ITileFetcher TileFetcher { get; private set; } - /// /// Creates a fully initialized instance of . /// @@ -117,13 +106,17 @@ return new WmtsLayerConfiguration(wmtsCapabilitiesUrl, tileSource); } - public IConfiguration Clone() + public override IConfiguration Clone() { - return new WmtsLayerConfiguration(capabilitiesUri, capabilityIdentifier, preferredFormat, persistentCacheDirectoryPath); + ThrowExceptionIfDisposed(); + + return new WmtsLayerConfiguration(capabilitiesUri, capabilityIdentifier, preferredFormat, PersistentCacheDirectoryPath); } - public void Initialize() + public override void Initialize() { + ThrowExceptionIfDisposed(); + if (Initialized) { return; @@ -134,11 +127,6 @@ InitializeFromTileSource(tileSource); } - public void Dispose() - { - TileFetcher?.Dispose(); - } - /// /// Validates a . /// @@ -236,32 +224,5 @@ return Path.Combine(BruTileSettings.PersistentCacheDirectoryRoot, "Wmts", host, layerStyle, format); } - - /// - /// Initialized the configuration based on the given . - /// - /// The tile source to initialize for. - /// Thrown when a critical error - /// occurs when creating the tile cache. - /// Thrown when - /// does not allow for tiles to be retrieved. - private void InitializeFromTileSource(ITileSource tileSource) - { - TileSource = tileSource; - tileCache = CreateTileCache(); - try - { - ITileProvider provider = BruTileReflectionHelper.GetProviderFromTileSource(tileSource); - TileFetcher = new AsyncTileFetcher(provider, - BruTileSettings.MemoryCacheMinimum, - BruTileSettings.MemoryCacheMaximum, - tileCache); - } - catch (Exception e) when (e is NotSupportedException || e is ArgumentException) - { - throw new CannotReceiveTilesException(Resources.WmtsLayerConfiguration_InitializeFromTileSource_TileSource_does_not_allow_access_to_provider, e); - } - Initialized = true; - } } } \ No newline at end of file Index: Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/TileFetching/AsyncTileFetcher.cs =================================================================== diff -u -r825240f8a4a6b63e3845195ff3366e4c58628c1b -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/TileFetching/AsyncTileFetcher.cs (.../AsyncTileFetcher.cs) (revision 825240f8a4a6b63e3845195ff3366e4c58628c1b) +++ Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/TileFetching/AsyncTileFetcher.cs (.../AsyncTileFetcher.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -90,6 +90,8 @@ public byte[] GetTile(TileInfo tileInfo) { + ThrowExceptionIfDisposed(); + byte[] res = GetTileFromCache(tileInfo); if (res != null) { @@ -102,11 +104,15 @@ public bool IsReady() { + ThrowExceptionIfDisposed(); + return activeTileRequests.Count == 0 && openTileRequests.Count == 0; } public void DropAllPendingTileRequests() { + ThrowExceptionIfDisposed(); + // Notes: http://dotspatial.codeplex.com/discussions/473428 threadPool.Cancel(false); int dummy; @@ -125,26 +131,45 @@ public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { if (IsDisposed) { return; } - volatileCache.Clear(); + if (disposing) + { + volatileCache.Clear(); - threadPool.Dispose(); - threadPool = null; + threadPool.Dispose(); + threadPool = null; - volatileCache = null; - provider = null; - persistentCache = null; + volatileCache = null; + provider = null; + persistentCache = null; + } + + IsDisposed = true; } - private bool IsDisposed + private bool IsDisposed { get; set; } + + /// + /// Thrown an when + /// is true. + /// + /// Thrown when calling this method while + /// this instance is disposed. + private void ThrowExceptionIfDisposed() { - get + if (IsDisposed) { - return threadPool == null; + throw new ObjectDisposedException(GetType().Name); } } Index: Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/TileFetching/ITileFetcher.cs =================================================================== diff -u -r825240f8a4a6b63e3845195ff3366e4c58628c1b -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/TileFetching/ITileFetcher.cs (.../ITileFetcher.cs) (revision 825240f8a4a6b63e3845195ff3366e4c58628c1b) +++ Core/Components/src/Core.Components.DotSpatial/Layer/BruTile/TileFetching/ITileFetcher.cs (.../ITileFetcher.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -50,16 +50,22 @@ /// If no tile can be returned, you can use and /// events for handling tile retrieval once the queued /// request has been served. + /// Thrown when calling this method while + /// this instance is disposed. byte[] GetTile(TileInfo tileInfo); /// /// Stops all pending tile requests. + /// Thrown when calling this method while + /// this instance is disposed. /// void DropAllPendingTileRequests(); /// /// Determines if this instance is idle and has no tile requests unserved. /// + /// Thrown when calling this method while + /// this instance is disposed. bool IsReady(); } } \ No newline at end of file Index: Core/Components/src/Core.Components.DotSpatial/Properties/Resources.Designer.cs =================================================================== diff -u -rb38a6537a602c558abf8f8ab3e349457604fa4f4 -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision b38a6537a602c558abf8f8ab3e349457604fa4f4) +++ Core/Components/src/Core.Components.DotSpatial/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -110,6 +110,16 @@ } /// + /// Looks up a localized string similar to Bron staat het niet toe om toegang te krijgen tot de kaart tegels.. + /// + internal static string Configuration_InitializeFromTileSource_TileSource_does_not_allow_access_to_provider { + get { + return ResourceManager.GetString("Configuration_InitializeFromTileSource_TileSource_does_not_allow_access_to_provid" + + "er", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Een kritieke fout is opgetreden bij het aanmaken van de cache.. /// internal static string PersistentCacheConfiguration_CreateTileCache_Critical_error_while_creating_tile_cache { @@ -157,16 +167,6 @@ } /// - /// Looks up a localized string similar to Bron staat het niet toe om toegang te krijgen tot de kaart tegels.. - /// - internal static string WmtsLayerConfiguration_InitializeFromTileSource_TileSource_does_not_allow_access_to_provider { - get { - return ResourceManager.GetString("WmtsLayerConfiguration_InitializeFromTileSource_TileSource_does_not_allow_access_" + - "to_provider", resourceCulture); - } - } - - /// /// Looks up a localized string similar to Afbeelding formaat moet opgegeven worden als MIME-type.. /// internal static string WmtsLayerConfiguration_ValidateConfigurationParameters_PreferredFormat_must_be_mimetype { Index: Core/Components/src/Core.Components.DotSpatial/Properties/Resources.resx =================================================================== diff -u -rb38a6537a602c558abf8f8ab3e349457604fa4f4 -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/src/Core.Components.DotSpatial/Properties/Resources.resx (.../Resources.resx) (revision b38a6537a602c558abf8f8ab3e349457604fa4f4) +++ Core/Components/src/Core.Components.DotSpatial/Properties/Resources.resx (.../Resources.resx) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -126,7 +126,7 @@ Ongeldige transformatie parameters: transformatie moet omkeerbaar zijn. - + Bron staat het niet toe om toegang te krijgen tot de kaart tegels. Index: Core/Components/test/Core.Components.DotSpatial.Test/Core.Components.DotSpatial.Test.csproj =================================================================== diff -u -r20d628d409984082edb491f5fe246d1ea80f382f -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/test/Core.Components.DotSpatial.Test/Core.Components.DotSpatial.Test.csproj (.../Core.Components.DotSpatial.Test.csproj) (revision 20d628d409984082edb491f5fe246d1ea80f382f) +++ Core/Components/test/Core.Components.DotSpatial.Test/Core.Components.DotSpatial.Test.csproj (.../Core.Components.DotSpatial.Test.csproj) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -110,6 +110,7 @@ + Index: Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/PersistentCacheConfigurationTest.cs =================================================================== diff -u -rfa3b352bc1b1c01fc73a9a45268c5573807a6381 -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/PersistentCacheConfigurationTest.cs (.../PersistentCacheConfigurationTest.cs) (revision fa3b352bc1b1c01fc73a9a45268c5573807a6381) +++ Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/PersistentCacheConfigurationTest.cs (.../PersistentCacheConfigurationTest.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -22,10 +22,13 @@ using System; using System.IO; using System.Security.AccessControl; +using BruTile; using BruTile.Cache; using Core.Common.TestUtil; using Core.Components.DotSpatial.Layer.BruTile.Configurations; +using Core.Components.DotSpatial.Layer.BruTile.TileFetching; using NUnit.Framework; +using Rhino.Mocks; namespace Core.Components.DotSpatial.Test.Layer.BruTile.Configurations { @@ -48,59 +51,231 @@ } [Test] + public void Constructor_ExpectedValues() + { + // Call + using (var configuration = new SimplePersistentCacheConfiguration("folder")) + { + // Assert + Assert.IsInstanceOf(configuration); + + Assert.IsFalse(configuration.Initialized); + Assert.IsNull(configuration.LegendText); + Assert.IsNull(configuration.TileSource); + Assert.IsNull(configuration.TileFetcher); + } + } + + [Test] public void CreateTileCache_DirectoryNotCreated_CreatesFileCacheDirectoryStructure() { // Setup var rootPath = $"CreateTileCache_DirectoryNotCreated_CreatesFileCacheDirectoryStructure{Path.DirectorySeparatorChar}"; - var configuration = new SimplePersistentCacheConfiguration(rootPath); - if (Directory.Exists(rootPath)) - { - Directory.Delete(rootPath, true); - } - - try - { - // Call - IPersistentCache cache = configuration.TestCreateTileCache(); - - // Assert - Assert.IsInstanceOf(cache); - Assert.IsTrue(Directory.Exists(rootPath)); - } - finally - { - if (Directory.Exists(rootPath)) + DoAndCleanupAfter( + () => { - Directory.Delete(rootPath, true); - } - } + using (var configuration = new SimplePersistentCacheConfiguration(rootPath)) + { + // Call + IPersistentCache cache = configuration.TestCreateTileCache(); + + // Assert + Assert.IsInstanceOf(cache); + Assert.IsTrue(Directory.Exists(rootPath)); + } + }, rootPath); } [Test] public void CreateTileCache_CreationOfDirectoryNotAllowed_ThrowCannotCreateTileCacheException() { // Setup var rootPath = $"CreateTileCache_CreationOfDirectoryNotAllowed_ThrowCannotCreateTileCacheException{Path.DirectorySeparatorChar}"; + + DoAndCleanupAfter( + () => + { + using (var configuration = new SimplePersistentCacheConfiguration(rootPath)) + using (new DirectoryPermissionsRevoker(Directory.GetCurrentDirectory(), FileSystemRights.Write)) + { + // Call + TestDelegate call = () => configuration.TestCreateTileCache(); + + // Assert + string expectedMessage = "Een kritieke fout is opgetreden bij het aanmaken van de cache."; + string message = Assert.Throws(call).Message; + Assert.AreEqual(message, expectedMessage); + } + }, + rootPath); + } + + [Test] + public void CreateTileCache_ConfigurationDisposed_ThrowObjectDisposedException() + { + // Setup + var configuration = new SimplePersistentCacheConfiguration("path"); + configuration.Dispose(); + + // Call + TestDelegate call = () => configuration.TestCreateTileCache(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("SimplePersistentCacheConfiguration", objectName); + } + + [Test] + public void InitializeFromTileSource_ValidTileSource_InitializeConfiguration() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + var tileSchema = mocks.Stub(); + mocks.ReplayAll(); + + var rootPath = $"InitializeFromTileSource_ValidTileSource_InitializeConfiguration{Path.DirectorySeparatorChar}"; + + DoAndCleanupAfter( + () => + { + using (var configuration = new SimplePersistentCacheConfiguration(rootPath)) + { + var tileSource = new TileSource(tileProvider, tileSchema); + + // Call + configuration.TestInitializeFromTileSource(tileSource); + + // Assert + Assert.AreSame(tileSource, configuration.TileSource); + Assert.IsInstanceOf(configuration.TileFetcher); + Assert.IsTrue(configuration.Initialized); + } + }, + rootPath); + + mocks.VerifyAll(); + } + + [Test] + public void InitializeFromTileSource_InvalidTileSource_ThrowCannotReceiveTilesException() + { + // Setup + var mocks = new MockRepository(); + var tileSource = mocks.Stub(); + mocks.ReplayAll(); + + var rootPath = $"InitializeFromTileSource_InvalidTileSource_ThrowCannotReceiveTilesException{Path.DirectorySeparatorChar}"; + + DoAndCleanupAfter( + () => + { + using (var configuration = new SimplePersistentCacheConfiguration(rootPath)) + { + // Call + TestDelegate call = () => configuration.TestInitializeFromTileSource(tileSource); + + // Assert + string message = Assert.Throws(call).Message; + string expectedMessage = "Bron staat het niet toe om toegang te krijgen tot de kaart tegels."; + Assert.AreEqual(expectedMessage, message); + } + }, + rootPath); + + mocks.VerifyAll(); + } + + [Test] + public void TestInitializeFromTileSource_CreationOfDirectoryNotAllowed_ThrowCannotCreateTileCacheException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + var tileSchema = mocks.Stub(); + mocks.ReplayAll(); + + var tileSource = new TileSource(tileProvider, tileSchema); + + var rootPath = $"TestInitializeFromTileSource_CreationOfDirectoryNotAllowed_ThrowCannotCreateTileCacheException{Path.DirectorySeparatorChar}"; + + DoAndCleanupAfter( + () => + { + using (var configuration = new SimplePersistentCacheConfiguration(rootPath)) + using (new DirectoryPermissionsRevoker(Directory.GetCurrentDirectory(), FileSystemRights.Write)) + { + // Call + TestDelegate call = () => configuration.TestInitializeFromTileSource(tileSource); + + // Assert + string expectedMessage = "Een kritieke fout is opgetreden bij het aanmaken van de cache."; + string message = Assert.Throws(call).Message; + Assert.AreEqual(message, expectedMessage); + } + }, + rootPath); + } + + [Test] + public void InitializeFromTileSource_ConfigurationDisposed_ThrownObjectDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + var tileSchema = mocks.Stub(); + mocks.ReplayAll(); + + var rootPath = $"InitializeFromTileSource_ConfigurationDisposed_ThrownObjectDisposedException{Path.DirectorySeparatorChar}"; + var configuration = new SimplePersistentCacheConfiguration(rootPath); + configuration.Dispose(); + var tileSource = new TileSource(tileProvider, tileSchema); + + DoAndCleanupAfter( + () => + { + // Call + TestDelegate call = () => configuration.TestInitializeFromTileSource(tileSource); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("SimplePersistentCacheConfiguration", objectName); + }, + rootPath); + + mocks.VerifyAll(); + } + + [Test] + public void Dispose_CalledMultipleTimes_DoesNotThrow() + { + // Setup + var configuration = new SimplePersistentCacheConfiguration("folder"); + + // Call + TestDelegate call = () => + { + configuration.Dispose(); + configuration.Dispose(); + }; + + // Assert + Assert.DoesNotThrow(call); + } + + private static void DoAndCleanupAfter(Action test, string rootPath) + { if (Directory.Exists(rootPath)) { Directory.Delete(rootPath, true); } try { - using (new DirectoryPermissionsRevoker(Directory.GetCurrentDirectory(), FileSystemRights.Write)) - { - // Call - TestDelegate call = () => configuration.TestCreateTileCache(); - - // Assert - string expectedMessage = "Een kritieke fout is opgetreden bij het aanmaken van de cache."; - string message = Assert.Throws(call).Message; - Assert.AreEqual(message, expectedMessage); - } + test(); } finally { @@ -119,6 +294,21 @@ { return CreateTileCache(); } + + public void TestInitializeFromTileSource(ITileSource tileSource) + { + InitializeFromTileSource(tileSource); + } + + public override IConfiguration Clone() + { + throw new NotImplementedException(); + } + + public override void Initialize() + { + throw new NotImplementedException(); + } } } } \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfigurationTest.cs =================================================================== diff -u --- Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfigurationTest.cs (revision 0) +++ Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WellKnownTileSourceLayerConfigurationTest.cs (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -0,0 +1,151 @@ +// Copyright (C) Stichting Deltares 2016. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using BruTile; +using BruTile.Predefined; +using Core.Components.DotSpatial.Layer.BruTile.Configurations; +using Core.Components.DotSpatial.Layer.BruTile.TileFetching; +using NUnit.Framework; + +namespace Core.Components.DotSpatial.Test.Layer.BruTile.Configurations +{ + [TestFixture] + public class WellKnownTileSourceLayerConfigurationTest + { + [Test] + public void CreateInitializedConfiguration_InvalidKnownTileSource_ThrowNotSupportedException() + { + // Setup + var invalidValue = (KnownTileSource) 9999; + + // Call + TestDelegate call = () => WellKnownTileSourceLayerConfiguration.CreateInitializedConfiguration(invalidValue); + + // Assert + Assert.Throws(call); + } + + [Test] + public void GivenAllAvailableKnownTileSources_WhenCreatingInitializedConfiguration_ThenConfigurationHasExpectedValues() + { + // Given + foreach (KnownTileSource knownTileSource in Enum.GetValues(typeof(KnownTileSource))) + { + // When + using (var configuration = WellKnownTileSourceLayerConfiguration.CreateInitializedConfiguration(knownTileSource)) + { + // Then + Assert.IsTrue(configuration.Initialized); + + Assert.IsNotNull(configuration.TileSource); + Assert.IsInstanceOf(configuration.TileFetcher); + Assert.AreEqual(knownTileSource.ToString(), configuration.LegendText); + } + } + } + + [Test] + public void Clone_FromFullyInitializedConfiguration_ReturnInitializedConfiguration() + { + // Setup + var knownTileSource = KnownTileSource.BingAerial; + using (var configuration = WellKnownTileSourceLayerConfiguration.CreateInitializedConfiguration(knownTileSource)) + { + // Call + using (var clone = (WellKnownTileSourceLayerConfiguration) configuration.Clone()) + { + // Assert + Assert.IsTrue(clone.Initialized); + + Assert.AreEqual(configuration.LegendText, clone.LegendText); + Assert.AreNotSame(configuration.TileSource, clone.TileSource); + Assert.AreEqual(configuration.TileSource.Name, clone.TileSource.Name); + AssertAttribution(configuration.TileSource.Attribution, clone.TileSource.Attribution); + Assert.AreEqual(configuration.TileSource.Schema.Format, clone.TileSource.Schema.Format); + + Assert.IsInstanceOf(clone.TileFetcher); + } + } + } + + [Test] + public void Clone_ConfigurationDisposed_ThrowObjectDisposedException() + { + // Setup + var configuration = WellKnownTileSourceLayerConfiguration.CreateInitializedConfiguration(KnownTileSource.BingAerial); + configuration.Dispose(); + + // Call + TestDelegate call = () => configuration.Clone(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("WellKnownTileSourceLayerConfiguration", objectName); + } + + [Test] + public void Initialize_InitializedTrue() + { + // Setup + using (var configuration = WellKnownTileSourceLayerConfiguration.CreateInitializedConfiguration(KnownTileSource.BingAerial)) + { + configuration.GetType() + .GetProperty(nameof(configuration.Initialized)) + .SetValue(configuration, false, null); + + // Call + configuration.Initialize(); + + // Assert + Assert.IsTrue(configuration.Initialized); + } + } + + [Test] + public void Initialize_ConfigurationDisposed_ThrowObjectDisposedException() + { + // Setup + var configuration = WellKnownTileSourceLayerConfiguration.CreateInitializedConfiguration(KnownTileSource.BingAerial); + configuration.Dispose(); + + // Call + TestDelegate call = () => configuration.Initialize(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("WellKnownTileSourceLayerConfiguration", objectName); + } + + private void AssertAttribution(Attribution expectedAttribution, Attribution actualAttribution) + { + if (expectedAttribution == null) + { + Assert.IsNull(actualAttribution); + } + else + { + Assert.AreEqual(expectedAttribution.Text, actualAttribution.Text); + Assert.AreEqual(expectedAttribution.Url, actualAttribution.Url); + } + } + } +} \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WmtsLayerConfigurationTest.cs =================================================================== diff -u -rb38a6537a602c558abf8f8ab3e349457604fa4f4 -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WmtsLayerConfigurationTest.cs (.../WmtsLayerConfigurationTest.cs) (revision b38a6537a602c558abf8f8ab3e349457604fa4f4) +++ Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/Configurations/WmtsLayerConfigurationTest.cs (.../WmtsLayerConfigurationTest.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -131,7 +131,9 @@ using (new UseCustomTileSourceFactoryConfig(factory)) { // Call - using (WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, targetMapData.SelectedCapabilityIdentifier, targetMapData.PreferredFormat)) + using (WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, + targetMapData.SelectedCapabilityIdentifier, + targetMapData.PreferredFormat)) { // Assert Assert.IsTrue(configuration.Initialized); @@ -163,7 +165,9 @@ mocks.ReplayAll(); using (new UseCustomTileSourceFactoryConfig(factory)) - using (WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, targetMapData.SelectedCapabilityIdentifier, targetMapData.PreferredFormat)) + using (WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, + targetMapData.SelectedCapabilityIdentifier, + targetMapData.PreferredFormat)) { // Call IConfiguration clone = configuration.Clone(); @@ -181,6 +185,42 @@ } [Test] + public void Clone_ConfigurationDisposed_ThrowObjectDisposedException() + { + // Setup + var targetMapData = WmtsMapData.CreateAlternativePdokMapData(); + + IRequest nullRequest = null; + var tileSource = new HttpTileSource(TileSchemaFactory.CreateWmtsTileSchema(targetMapData), + nullRequest); + var tileSources = new ITileSource[] + { + tileSource + }; + + var mocks = new MockRepository(); + var factory = mocks.Stub(); + factory.Stub(f => f.GetWmtsTileSources(targetMapData.SourceCapabilitiesUrl)).Return(tileSources); + mocks.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(factory)) + { + WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, + targetMapData.SelectedCapabilityIdentifier, + targetMapData.PreferredFormat); + configuration.Dispose(); + + // Call + TestDelegate call = () => configuration.Clone(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("WmtsLayerConfiguration", objectName); + } + mocks.VerifyAll(); + } + + [Test] public void GivenFullyInitializedConfiguration_WhenClonedAndInitialized_ConfigurationAreEqual() { // Given @@ -200,7 +240,9 @@ mocks.ReplayAll(); using (new UseCustomTileSourceFactoryConfig(factory)) - using (WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, targetMapData.SelectedCapabilityIdentifier, targetMapData.PreferredFormat)) + using (WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, + targetMapData.SelectedCapabilityIdentifier, + targetMapData.PreferredFormat)) { // When IConfiguration clone = configuration.Clone(); @@ -214,5 +256,41 @@ } mocks.VerifyAll(); } + + [Test] + public void Initialize_ConfigurationDisposed_ThrowsObjectDisposedException() + { + // Setup + var targetMapData = WmtsMapData.CreateAlternativePdokMapData(); + + IRequest nullRequest = null; + var tileSource = new HttpTileSource(TileSchemaFactory.CreateWmtsTileSchema(targetMapData), + nullRequest); + var tileSources = new ITileSource[] + { + tileSource + }; + + var mocks = new MockRepository(); + var factory = mocks.Stub(); + factory.Stub(f => f.GetWmtsTileSources(targetMapData.SourceCapabilitiesUrl)).Return(tileSources); + mocks.ReplayAll(); + + using (new UseCustomTileSourceFactoryConfig(factory)) + { + WmtsLayerConfiguration configuration = WmtsLayerConfiguration.CreateInitializedConfiguration(targetMapData.SourceCapabilitiesUrl, + targetMapData.SelectedCapabilityIdentifier, + targetMapData.PreferredFormat); + configuration.Dispose(); + + // Call + TestDelegate call = () => configuration.Initialize(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("WmtsLayerConfiguration", objectName); + } + mocks.VerifyAll(); + } } } \ No newline at end of file Index: Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/TileFetching/AsyncTileFetcherTest.cs =================================================================== diff -u -r825240f8a4a6b63e3845195ff3366e4c58628c1b -rd931a61857360da73c642ea9decf7882cd4cdb1c --- Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/TileFetching/AsyncTileFetcherTest.cs (.../AsyncTileFetcherTest.cs) (revision 825240f8a4a6b63e3845195ff3366e4c58628c1b) +++ Core/Components/test/Core.Components.DotSpatial.Test/Layer/BruTile/TileFetching/AsyncTileFetcherTest.cs (.../AsyncTileFetcherTest.cs) (revision d931a61857360da73c642ea9decf7882cd4cdb1c) @@ -244,6 +244,29 @@ } [Test] + public void GetTile_TileFetcherDisposed_ThrowObjectDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + tileFetcher.Dispose(); + + var tileInfo = new TileInfo(); + + // Call + TestDelegate call = () => tileFetcher.GetTile(tileInfo); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("AsyncTileFetcher", objectName); + + mocks.VerifyAll(); + } + + [Test] public void GivenTileFetcherWithoutCachedTile_WhenGettingSameTimeMultipleTimes_IgnoreDuplicateRequests() { // Given @@ -416,6 +439,27 @@ } [Test] + public void DropAllPendingTileRequests_TileFetcherDisposed_ThrowObjectDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + tileFetcher.Dispose(); + + // Call + TestDelegate call = () => tileFetcher.DropAllPendingTileRequests(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("AsyncTileFetcher", objectName); + + mocks.VerifyAll(); + } + + [Test] public void IsReady_TileFetcherIdle_ReturnTrue() { // Setup @@ -464,6 +508,48 @@ } } + [Test] + public void IsRead_TileFetcherDisposed_ThrowObjetDisposedException() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + tileFetcher.Dispose(); + + // Call + TestDelegate call = () => tileFetcher.IsReady(); + + // Assert + string objectName = Assert.Throws(call).ObjectName; + Assert.AreEqual("AsyncTileFetcher", objectName); + + mocks.VerifyAll(); + } + + [Test] + public void Dispose_CalledMultipleTimes_DoesNotThrow() + { + // Setup + var mocks = new MockRepository(); + var tileProvider = mocks.Stub(); + mocks.ReplayAll(); + + var tileFetcher = new AsyncTileFetcher(tileProvider, 1, 2); + + // Call + TestDelegate call = () => + { + tileFetcher.Dispose(); + tileFetcher.Dispose(); + }; + + // Assert + Assert.DoesNotThrow(call); + } + /// /// A stub implementation of that can wait to return /// on its methods until an signal is given from another thread.