Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationExporter.cs
===================================================================
diff -u -r0404544d0354a059a0b7a02e5f1bca72d6e81d75 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationExporter.cs (.../ClosingStructuresCalculationConfigurationExporter.cs) (revision 0404544d0354a059a0b7a02e5f1bca72d6e81d75)
+++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationExporter.cs (.../ClosingStructuresCalculationConfigurationExporter.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -25,8 +25,8 @@
using Ringtoets.ClosingStructures.IO.Configurations.Helpers;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.Structures;
+using Ringtoets.Common.IO.Configurations.Export;
using Ringtoets.Common.IO.Configurations.Helpers;
-using Ringtoets.Common.IO.Exporters;
namespace Ringtoets.ClosingStructures.IO.Configurations
{
Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationImporter.cs
===================================================================
diff -u -r4e27904f8aee7ae9723f57336764c585a3b9300d -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationImporter.cs (.../ClosingStructuresCalculationConfigurationImporter.cs) (revision 4e27904f8aee7ae9723f57336764c585a3b9300d)
+++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationImporter.cs (.../ClosingStructuresCalculationConfigurationImporter.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -31,8 +31,7 @@
using Ringtoets.Common.Data.Structures;
using Ringtoets.Common.IO.Configurations;
using Ringtoets.Common.IO.Configurations.Helpers;
-using Ringtoets.Common.IO.FileImporters;
-using Ringtoets.Common.IO.Schema;
+using Ringtoets.Common.IO.Configurations.Import;
using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources;
namespace Ringtoets.ClosingStructures.IO.Configurations
Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationReader.cs
===================================================================
diff -u -r924f2389eed79b61cb12b8042fe23b9a0499e3b5 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationReader.cs (.../ClosingStructuresCalculationConfigurationReader.cs) (revision 924f2389eed79b61cb12b8042fe23b9a0499e3b5)
+++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationReader.cs (.../ClosingStructuresCalculationConfigurationReader.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -27,8 +27,7 @@
using Ringtoets.ClosingStructures.IO.Properties;
using Ringtoets.Common.IO.Configurations;
using Ringtoets.Common.IO.Configurations.Helpers;
-using Ringtoets.Common.IO.Readers;
-using Ringtoets.Common.IO.Schema;
+using Ringtoets.Common.IO.Configurations.Import;
using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources;
namespace Ringtoets.ClosingStructures.IO.Configurations
@@ -90,7 +89,7 @@
{
structureBaseSchemaName, RingtoetsCommonIOResources.KunstwerkenBasisSchema
}
- }) {}
+ }) { }
protected override ClosingStructuresCalculationConfiguration ParseCalculationElement(XElement calculationElement)
{
Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationWriter.cs
===================================================================
diff -u -r16c94d05c67237dec9fcab0f3f03c6b48d3c335b -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationWriter.cs (.../ClosingStructuresCalculationConfigurationWriter.cs) (revision 16c94d05c67237dec9fcab0f3f03c6b48d3c335b)
+++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.IO/Configurations/ClosingStructuresCalculationConfigurationWriter.cs (.../ClosingStructuresCalculationConfigurationWriter.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -22,7 +22,7 @@
using System;
using System.Xml;
using Ringtoets.ClosingStructures.IO.Configurations.Helpers;
-using Ringtoets.Common.IO.Writers;
+using Ringtoets.Common.IO.Configurations.Export;
namespace Ringtoets.ClosingStructures.IO.Configurations
{
@@ -44,7 +44,7 @@
/// - does not end with a directory or path separator (empty file name).
///
public ClosingStructuresCalculationConfigurationWriter(string filePath)
- : base(filePath) {}
+ : base(filePath) { }
protected override void WriteSpecificStructureParameters(ClosingStructuresCalculationConfiguration configuration, XmlWriter writer)
{
Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationImporterTest.cs
===================================================================
diff -u -r36b8629b18443a58866edc869420795588eaf168 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationImporterTest.cs (.../ClosingStructuresCalculationConfigurationImporterTest.cs) (revision 36b8629b18443a58866edc869420795588eaf168)
+++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationImporterTest.cs (.../ClosingStructuresCalculationConfigurationImporterTest.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -27,15 +27,15 @@
using Core.Common.Base.Geometry;
using Core.Common.TestUtil;
using NUnit.Framework;
+using Ringtoets.ClosingStructures.Data;
+using Ringtoets.ClosingStructures.Data.TestUtil;
+using Ringtoets.ClosingStructures.IO.Configurations;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.DikeProfiles;
using Ringtoets.Common.Data.Hydraulics;
using Ringtoets.Common.Data.Structures;
using Ringtoets.Common.Data.TestUtil;
-using Ringtoets.Common.IO.FileImporters;
-using Ringtoets.ClosingStructures.Data;
-using Ringtoets.ClosingStructures.Data.TestUtil;
-using Ringtoets.ClosingStructures.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Import;
namespace Ringtoets.ClosingStructures.IO.Test.Configurations
{
@@ -49,10 +49,10 @@
{
// Call
var importer = new ClosingStructuresCalculationConfigurationImporter("",
- new CalculationGroup(),
- Enumerable.Empty(),
- Enumerable.Empty(),
- Enumerable.Empty());
+ new CalculationGroup(),
+ Enumerable.Empty(),
+ Enumerable.Empty(),
+ Enumerable.Empty());
// Assert
Assert.IsInstanceOf>(importer);
@@ -63,10 +63,10 @@
{
// Call
TestDelegate test = () => new ClosingStructuresCalculationConfigurationImporter("",
- new CalculationGroup(),
- null,
- Enumerable.Empty(),
- Enumerable.Empty());
+ new CalculationGroup(),
+ null,
+ Enumerable.Empty(),
+ Enumerable.Empty());
// Assert
var exception = Assert.Throws(test);
@@ -78,10 +78,10 @@
{
// Call
TestDelegate test = () => new ClosingStructuresCalculationConfigurationImporter("",
- new CalculationGroup(),
- Enumerable.Empty(),
- null,
- Enumerable.Empty());
+ new CalculationGroup(),
+ Enumerable.Empty(),
+ null,
+ Enumerable.Empty());
// Assert
var exception = Assert.Throws(test);
@@ -93,10 +93,10 @@
{
// Call
TestDelegate test = () => new ClosingStructuresCalculationConfigurationImporter("",
- new CalculationGroup(),
- Enumerable.Empty(),
- Enumerable.Empty(),
- null);
+ new CalculationGroup(),
+ Enumerable.Empty(),
+ Enumerable.Empty(),
+ null);
// Assert
var exception = Assert.Throws(test);
@@ -200,16 +200,16 @@
var foreshoreProfile = new TestForeshoreProfile("profiel 1");
var importer = new ClosingStructuresCalculationConfigurationImporter(filePath,
- calculationGroup,
- Enumerable.Empty(),
- new ForeshoreProfile[]
- {
- foreshoreProfile
- },
- new ClosingStructure[]
- {
- structure
- });
+ calculationGroup,
+ Enumerable.Empty(),
+ new ForeshoreProfile[]
+ {
+ foreshoreProfile
+ },
+ new ClosingStructure[]
+ {
+ structure
+ });
var successful = false;
// Call
@@ -222,36 +222,6 @@
CollectionAssert.IsEmpty(calculationGroup.Children);
}
- [TestCase("validConfigurationUnknownForeshoreProfile.xml",
- "Het voorlandprofiel 'unknown' bestaat niet.")]
- [TestCase("validConfigurationUnknownHydraulicBoundaryLocation.xml",
- "De locatie met hydraulische randvoorwaarden 'unknown' bestaat niet.")]
- [TestCase("validConfigurationUnknownStructure.xml",
- "Het kunstwerk 'unknown' bestaat niet.")]
- public void Import_ValidConfigurationUnknownData_LogMessageAndContinueImport(string file, string expectedErrorMessage)
- {
- // Setup
- string filePath = Path.Combine(importerPath, file);
-
- var calculationGroup = new CalculationGroup();
-
- var importer = new ClosingStructuresCalculationConfigurationImporter(filePath,
- calculationGroup,
- Enumerable.Empty(),
- Enumerable.Empty(),
- Enumerable.Empty());
- var successful = false;
-
- // Call
- Action call = () => successful = importer.Import();
-
- // Assert
- string expectedMessage = $"{expectedErrorMessage} Berekening 'Berekening 1' is overgeslagen.";
- TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessage, LogLevelConstant.Error), 1);
- Assert.IsTrue(successful);
- CollectionAssert.IsEmpty(calculationGroup.Children);
- }
-
[Test]
public void Import_UseForeshoreButForeshoreProfileWithoutGeometry_LogMessageAndContinueImport()
{
@@ -292,7 +262,7 @@
var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation("Locatie1");
var foreshoreProfile = new TestForeshoreProfile("profiel1", new List
{
- new Point2D(0,3)
+ new Point2D(0, 3)
});
var structure = new TestClosingStructure("kunstwerk1");
var importer = new ClosingStructuresCalculationConfigurationImporter(
@@ -310,9 +280,9 @@
{
structure
});
-
+
// Call
- var successful = importer.Import();
+ bool successful = importer.Import();
// Assert
Assert.IsTrue(successful);
@@ -377,21 +347,21 @@
Mean = (RoundedDouble) 4.3,
StandardDeviation = (RoundedDouble) 0.2
},
- AreaFlowApertures =
+ AreaFlowApertures =
{
Mean = (RoundedDouble) 80.5,
StandardDeviation = (RoundedDouble) 1
},
- DrainCoefficient =
+ DrainCoefficient =
{
Mean = (RoundedDouble) 1.1,
},
- InsideWaterLevel =
+ InsideWaterLevel =
{
Mean = (RoundedDouble) 0.5,
StandardDeviation = (RoundedDouble) 0.1
},
- ThresholdHeightOpenWeir =
+ ThresholdHeightOpenWeir =
{
Mean = (RoundedDouble) 1.2,
StandardDeviation = (RoundedDouble) 0.1
@@ -400,7 +370,7 @@
};
Assert.AreEqual(1, calculationGroup.Children.Count);
- AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]);
+ AssertCalculation(expectedCalculation, (StructuresCalculation) calculationGroup.Children[0]);
}
[Test]
@@ -477,14 +447,14 @@
}
}
};
-
+
// Call
- var successful = importer.Import();
+ bool successful = importer.Import();
// Assert
Assert.IsTrue(successful);
Assert.AreEqual(1, calculationGroup.Children.Count);
- AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]);
+ AssertCalculation(expectedCalculation, (StructuresCalculation) calculationGroup.Children[0]);
}
[Test]
@@ -549,14 +519,14 @@
}
}
};
-
+
// Call
- var successful = importer.Import();
+ bool successful = importer.Import();
// Assert
Assert.IsTrue(successful);
Assert.AreEqual(1, calculationGroup.Children.Count);
- AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]);
+ AssertCalculation(expectedCalculation, (StructuresCalculation) calculationGroup.Children[0]);
}
[Test]
@@ -585,16 +555,46 @@
{
Name = "Berekening 1"
};
-
+
// Call
- var successful = importer.Import();
+ bool successful = importer.Import();
// Assert
Assert.IsTrue(successful);
Assert.AreEqual(1, calculationGroup.Children.Count);
- AssertCalculation(expectedCalculation, (StructuresCalculation)calculationGroup.Children[0]);
+ AssertCalculation(expectedCalculation, (StructuresCalculation) calculationGroup.Children[0]);
}
+ [TestCase("validConfigurationUnknownForeshoreProfile.xml",
+ "Het voorlandprofiel 'unknown' bestaat niet.")]
+ [TestCase("validConfigurationUnknownHydraulicBoundaryLocation.xml",
+ "De locatie met hydraulische randvoorwaarden 'unknown' bestaat niet.")]
+ [TestCase("validConfigurationUnknownStructure.xml",
+ "Het kunstwerk 'unknown' bestaat niet.")]
+ public void Import_ValidConfigurationUnknownData_LogMessageAndContinueImport(string file, string expectedErrorMessage)
+ {
+ // Setup
+ string filePath = Path.Combine(importerPath, file);
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new ClosingStructuresCalculationConfigurationImporter(filePath,
+ calculationGroup,
+ Enumerable.Empty(),
+ Enumerable.Empty(),
+ Enumerable.Empty());
+ var successful = false;
+
+ // Call
+ Action call = () => successful = importer.Import();
+
+ // Assert
+ string expectedMessage = $"{expectedErrorMessage} Berekening 'Berekening 1' is overgeslagen.";
+ TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessage, LogLevelConstant.Error), 1);
+ Assert.IsTrue(successful);
+ CollectionAssert.IsEmpty(calculationGroup.Children);
+ }
+
private static void AssertCalculation(StructuresCalculation expectedCalculation, StructuresCalculation actualCalculation)
{
Assert.AreEqual(expectedCalculation.Name, actualCalculation.Name);
Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationReaderTest.cs
===================================================================
diff -u -r4ddd71e94c1499cdbcbdaa13295ece84f2070411 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationReaderTest.cs (.../ClosingStructuresCalculationConfigurationReaderTest.cs) (revision 4ddd71e94c1499cdbcbdaa13295ece84f2070411)
+++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationReaderTest.cs (.../ClosingStructuresCalculationConfigurationReaderTest.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -28,7 +28,7 @@
using NUnit.Framework;
using Ringtoets.ClosingStructures.IO.Configurations;
using Ringtoets.Common.IO.Configurations;
-using Ringtoets.Common.IO.Readers;
+using Ringtoets.Common.IO.Configurations.Import;
namespace Ringtoets.ClosingStructures.IO.Test.Configurations
{
Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationWriterTest.cs
===================================================================
diff -u -reeac9fe0e250075e6e95683e4781b7b96ddc178c -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationWriterTest.cs (.../ClosingStructuresCalculationConfigurationWriterTest.cs) (revision eeac9fe0e250075e6e95683e4781b7b96ddc178c)
+++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.IO.Test/Configurations/ClosingStructuresCalculationConfigurationWriterTest.cs (.../ClosingStructuresCalculationConfigurationWriterTest.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -25,8 +25,8 @@
using NUnit.Framework;
using Ringtoets.ClosingStructures.IO.Configurations;
using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Export;
using Ringtoets.Common.IO.TestUtil;
-using Ringtoets.Common.IO.Writers;
namespace Ringtoets.ClosingStructures.IO.Test.Configurations
{
@@ -69,11 +69,6 @@
}
}
- protected override void AssertDefaultConstructedInstance(ClosingStructuresCalculationConfigurationWriter writer)
- {
- Assert.IsInstanceOf>(writer);
- }
-
[Test]
[TestCaseSource(nameof(Calculations))]
public void Write_ValidCalculation_ValidFile(string expectedFileName, IConfigurationItem[] configuration)
@@ -103,6 +98,11 @@
}
}
+ protected override void AssertDefaultConstructedInstance(ClosingStructuresCalculationConfigurationWriter writer)
+ {
+ Assert.IsInstanceOf>(writer);
+ }
+
private static ClosingStructuresCalculationConfiguration CreateFullCalculation()
{
return new ClosingStructuresCalculationConfiguration("Berekening 1")
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/ConfigurationSchemaIdentifiers.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/ConfigurationSchemaIdentifiers.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/ConfigurationSchemaIdentifiers.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,189 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.
+
+namespace Ringtoets.Common.IO.Configurations
+{
+ ///
+ /// Container of general identifiers related to configuration schema definitions.
+ ///
+ public static class ConfigurationSchemaIdentifiers
+ {
+ ///
+ /// The identifier for configuration elements.
+ ///
+ public const string ConfigurationElement = "configuratie";
+
+ ///
+ /// The identifier for calculation elements.
+ ///
+ public const string CalculationElement = "berekening";
+
+ ///
+ /// The identifier for folder elements.
+ ///
+ public const string FolderElement = "map";
+
+ ///
+ /// The identifier for name attributes.
+ ///
+ public const string NameAttribute = "naam";
+
+ ///
+ /// The identifier for hydraulic boundary location elements.
+ ///
+ public const string HydraulicBoundaryLocationElement = "hrlocatie";
+
+ ///
+ /// The tag of elements containing the orientation of the profile.
+ ///
+ public const string Orientation = "orientatie";
+
+ #region stochasts
+
+ ///
+ /// The identifier for stochasts elements.
+ ///
+ public const string StochastsElement = "stochasten";
+
+ ///
+ /// The identifier for stochast elements.
+ ///
+ public const string StochastElement = "stochast";
+
+ ///
+ /// The identifier for mean elements.
+ ///
+ public const string MeanElement = "verwachtingswaarde";
+
+ ///
+ /// The identifier for standard deviation elements.
+ ///
+ public const string StandardDeviationElement = "standaardafwijking";
+
+ ///
+ /// The identifier for variation coefficient elements.
+ ///
+ public const string VariationCoefficientElement = "variatiecoefficient";
+
+ ///
+ /// The identifier for the phreatic level exit stochast name.
+ ///
+ public const string AllowedLevelIncreaseStorageStochastName = "peilverhogingkomberging";
+
+ ///
+ /// The identifier for the critical overtopping discharge stochast name.
+ ///
+ public const string CriticalOvertoppingDischargeStochastName = "kritiekinstromenddebiet";
+
+ ///
+ /// The identifier for the model factor super critical flow stochast name.
+ ///
+ public const string ModelFactorSuperCriticalFlowStochastName = "modelfactoroverloopdebiet";
+
+ ///
+ /// The identifier for the model factor super critical flow stochast name.
+ ///
+ public const string FlowWidthAtBottomProtectionStochastName = "breedtebodembescherming";
+
+ ///
+ /// The identifier for the storage structure area stochast name.
+ ///
+ public const string StorageStructureAreaStochastName = "kombergendoppervlak";
+
+ ///
+ /// The identifier for the storm duration stochast name.
+ ///
+ public const string StormDurationStochastName = "stormduur";
+
+ ///
+ /// The identifier for the width flow apertures stochast name.
+ ///
+ public const string WidthFlowAperturesStochastName = "breedtedoorstroomopening";
+
+ #endregion
+
+ #region wave reduction
+
+ ///
+ /// The tag of elements containing parameters that define wave reduction.
+ ///
+ public const string WaveReduction = "golfreductie";
+
+ ///
+ /// The tag of elements containing the value indicating whether to use break water.
+ ///
+ public const string UseBreakWater = "damgebruiken";
+
+ ///
+ /// The tag of elements containing the type of the break water.
+ ///
+ public const string BreakWaterType = "damtype";
+
+ ///
+ /// The tag of elements containing the height of the break water.
+ ///
+ public const string BreakWaterHeight = "damhoogte";
+
+ ///
+ /// The tag of elements containing the value indicating whether to use break water.
+ ///
+ public const string UseForeshore = "voorlandgebruiken";
+
+ ///
+ /// The possible content of the element indicating a
+ /// caisson type of break water.
+ ///
+ public const string BreakWaterCaisson = "caisson";
+
+ ///
+ /// The possible content of the element indicating a
+ /// dam type of break water.
+ ///
+ public const string BreakWaterDam = "havendam";
+
+ ///
+ /// The possible content of the element indicating a
+ /// wall type of break water.
+ ///
+ public const string BreakWaterWall = "verticalewand";
+
+ #endregion
+
+ #region structure calculation
+
+ ///
+ /// The tag of elements containing the failure probability of a structure with erosion.
+ ///
+ public const string FailureProbabilityStructureWithErosionElement = "faalkansgegevenerosiebodem";
+
+ ///
+ /// The tag of elements containing the name of the structure.
+ ///
+ public const string StructureElement = "kunstwerk";
+
+ ///
+ /// The tag of elements containing the name of the foreshore profile.
+ ///
+ public const string ForeshoreProfileNameElement = "voorlandprofiel";
+
+ #endregion
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/CalculationConfigurationExporter.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/CalculationConfigurationExporter.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/CalculationConfigurationExporter.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,82 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using Core.Common.Base.IO;
+using Core.Common.IO.Exceptions;
+using Core.Common.Utils;
+using log4net;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.IO.Properties;
+
+namespace Ringtoets.Common.IO.Configurations.Export
+{
+ ///
+ /// Base class for exporting a calculation configuration and storing it as an XML file.
+ ///
+ /// The
+ /// to use for exporting .
+ /// The type to export.
+ public abstract class CalculationConfigurationExporter : IFileExporter
+ where TCalculation : class, ICalculation
+ where TWriter : CalculationConfigurationWriter, new()
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(CalculationConfigurationExporter));
+ private readonly IEnumerable configuration;
+ private readonly string filePath;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The calculation configuration to export.
+ /// The path of the XML file to export to.
+ /// Thrown when is null.
+ /// Thrown when is invalid.
+ protected CalculationConfigurationExporter(IEnumerable configuration, string filePath)
+ {
+ if (configuration == null)
+ {
+ throw new ArgumentNullException(nameof(configuration));
+ }
+
+ IOUtils.ValidateFilePath(filePath);
+
+ this.configuration = configuration;
+ this.filePath = filePath;
+ }
+
+ public bool Export()
+ {
+ try
+ {
+ new TWriter().Write(configuration, filePath);
+ }
+ catch (CriticalFileWriteException e)
+ {
+ log.ErrorFormat(Resources.CalculationConfigurationExporter_Export_ExceptionMessage_0_no_configuration_exported, e.Message);
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/CalculationConfigurationWriter.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/CalculationConfigurationWriter.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/CalculationConfigurationWriter.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,235 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.Xml;
+using Core.Common.IO.Exceptions;
+using Core.Common.Utils.Properties;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.Data.DikeProfiles;
+using Ringtoets.Common.Data.Probabilistics;
+using Ringtoets.Common.IO.Configurations.Helpers;
+
+namespace Ringtoets.Common.IO.Configurations.Export
+{
+ ///
+ /// Base implementation of writing calculation configurations to XML.
+ ///
+ /// The type of calculations which are written to file.
+ public abstract class CalculationConfigurationWriter where T : class, ICalculation
+ {
+ ///
+ /// Writes a calculation configuration to an XML file.
+ ///
+ /// The calculation configuration to write.
+ /// The path to the target XML file.
+ /// Thrown when any parameter is null.
+ /// Thrown when unable to write to .
+ /// The itself will not be part of the written XML, only its children.
+ public void Write(IEnumerable configuration, string filePath)
+ {
+ if (configuration == null)
+ {
+ throw new ArgumentNullException(nameof(configuration));
+ }
+ if (filePath == null)
+ {
+ throw new ArgumentNullException(nameof(filePath));
+ }
+
+ try
+ {
+ var settings = new XmlWriterSettings
+ {
+ Indent = true
+ };
+
+ using (XmlWriter writer = XmlWriter.Create(filePath, settings))
+ {
+ writer.WriteStartDocument();
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.ConfigurationElement);
+
+ WriteConfiguration(configuration, writer);
+
+ writer.WriteEndElement();
+ writer.WriteEndDocument();
+ }
+ }
+ catch (SystemException e)
+ {
+ throw new CriticalFileWriteException(string.Format(Resources.Error_General_output_error_0, filePath), e);
+ }
+ }
+
+ ///
+ /// Writes a single in XML format to file.
+ ///
+ /// The calculation to write.
+ /// The writer to use for writing.
+ /// Thrown when the is closed.
+ protected abstract void WriteCalculation(T calculation, XmlWriter writer);
+
+ ///
+ /// Writes the in XML format to file.
+ ///
+ /// The dictionary of distributions, keyed on name, to write.
+ /// The writer to use for writing.
+ /// Thrown when is null.
+ /// Thrown when the is closed.
+ protected static void WriteDistributions(IDictionary distributions, XmlWriter writer)
+ {
+ if (distributions == null)
+ {
+ throw new ArgumentNullException(nameof(distributions));
+ }
+
+ if (distributions.Count > 0)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.StochastsElement);
+
+ foreach (KeyValuePair keyValuePair in distributions)
+ {
+ WriteDistribution(keyValuePair.Value, keyValuePair.Key, writer);
+ }
+
+ writer.WriteEndElement();
+ }
+ }
+
+ ///
+ /// Writes the in XML format to file.
+ ///
+ /// The dictionary of variation coefficient distributions, keyed on name, to write.
+ /// The writer to use for writing.
+ /// Thrown when is null.
+ /// Thrown when the is closed.
+ protected static void WriteVariationCoefficientDistributions(IDictionary variationCoefficientDistributions, XmlWriter writer)
+ {
+ if (variationCoefficientDistributions == null)
+ {
+ throw new ArgumentNullException(nameof(variationCoefficientDistributions));
+ }
+
+ if (variationCoefficientDistributions.Count > 0)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.StochastsElement);
+
+ foreach (KeyValuePair keyValuePair in variationCoefficientDistributions)
+ {
+ WriteVariationCoefficientDistribution(keyValuePair.Value, keyValuePair.Key, writer);
+ }
+
+ writer.WriteEndElement();
+ }
+ }
+
+ ///
+ /// Writes the properties of the in XML format to file.
+ ///
+ /// The break water to write.
+ /// The writer to use for writing.
+ /// Thrown when the is closed.
+ protected static void WriteBreakWaterProperties(BreakWater breakWater, XmlWriter writer)
+ {
+ if (breakWater != null)
+ {
+ writer.WriteElementString(
+ ConfigurationSchemaIdentifiers.BreakWaterType,
+ BreakWaterTypeAsXmlString((ConfigurationBreakWaterType) breakWater.Type));
+ writer.WriteElementString(
+ ConfigurationSchemaIdentifiers.BreakWaterHeight,
+ XmlConvert.ToString(breakWater.Height));
+ }
+ }
+
+ ///
+ /// Writes the in XML format to file.
+ ///
+ /// The calculation group(s) and/or calculation(s) to write.
+ /// The writer to use for writing.
+ /// Thrown when
+ /// contains a value that is neither nor .
+ private void WriteConfiguration(IEnumerable configuration, XmlWriter writer)
+ {
+ foreach (ICalculationBase child in configuration)
+ {
+ var innerGroup = child as CalculationGroup;
+ if (innerGroup != null)
+ {
+ WriteCalculationGroup(innerGroup, writer);
+ }
+
+ var calculation = child as T;
+ if (calculation != null)
+ {
+ WriteCalculation(calculation, writer);
+ }
+
+ if (innerGroup == null && calculation == null)
+ {
+ throw new ArgumentException($"Cannot write calculation of type '{child.GetType()}' using this writer.");
+ }
+ }
+ }
+
+ private static string BreakWaterTypeAsXmlString(ConfigurationBreakWaterType type)
+ {
+ return new ConfigurationBreakWaterTypeConverter().ConvertToInvariantString(type);
+ }
+
+ private static void WriteDistribution(IDistribution distribution, string elementName, XmlWriter writer)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.StochastElement);
+
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, elementName);
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.MeanElement,
+ XmlConvert.ToString(distribution.Mean));
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.StandardDeviationElement,
+ XmlConvert.ToString(distribution.StandardDeviation));
+
+ writer.WriteEndElement();
+ }
+
+ private static void WriteVariationCoefficientDistribution(IVariationCoefficientDistribution distribution, string elementName, XmlWriter writer)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.StochastElement);
+
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, elementName);
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.MeanElement,
+ XmlConvert.ToString(distribution.Mean));
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.VariationCoefficientElement,
+ XmlConvert.ToString(distribution.CoefficientOfVariation));
+
+ writer.WriteEndElement();
+ }
+
+ private void WriteCalculationGroup(CalculationGroup calculationGroup, XmlWriter writer)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.FolderElement);
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, calculationGroup.Name);
+
+ WriteConfiguration(calculationGroup.Children, writer);
+
+ writer.WriteEndElement();
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/SchemaCalculationConfigurationExporter.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/SchemaCalculationConfigurationExporter.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/SchemaCalculationConfigurationExporter.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,136 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.Linq;
+using Core.Common.Base.IO;
+using Core.Common.IO.Exceptions;
+using log4net;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.IO.Properties;
+
+namespace Ringtoets.Common.IO.Configurations.Export
+{
+ ///
+ /// Base class for exporting a calculation configuration and storing it as an XML file.
+ ///
+ /// The
+ /// to use for exporting .
+ /// The type to export.
+ /// The type used to convert
+ /// into before writing to XML using a .
+ ///
+ public abstract class SchemaCalculationConfigurationExporter : IFileExporter
+ where TWriter : SchemaCalculationConfigurationWriter
+ where TCalculation : class, ICalculation
+ where TConfiguration : class, IConfigurationItem
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(SchemaCalculationConfigurationExporter));
+ private readonly IEnumerable configuration;
+ private readonly TWriter writer;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The hierarchy of calculations to export.
+ /// The path of the XML file to export to.
+ /// Thrown when is null.
+ /// Thrown when is invalid or when any element
+ /// of is null.
+ protected SchemaCalculationConfigurationExporter(IEnumerable calculations, string filePath)
+ {
+ if (calculations == null)
+ {
+ throw new ArgumentNullException(nameof(calculations));
+ }
+
+ writer = CreateWriter(filePath);
+ configuration = ToConfiguration(calculations).ToArray();
+ }
+
+ public bool Export()
+ {
+ try
+ {
+ writer.Write(configuration);
+ }
+ catch (CriticalFileWriteException e)
+ {
+ log.ErrorFormat(Resources.CalculationConfigurationExporter_Export_ExceptionMessage_0_no_configuration_exported, e.Message);
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Creates the writer that will be used in the .
+ ///
+ /// The path of the file to export to.
+ /// A new .
+ protected abstract TWriter CreateWriter(string filePath);
+
+ ///
+ /// Converts the to a .
+ ///
+ /// The to convert.
+ /// A new instance of with values set equal
+ /// to properties of .
+ protected abstract TConfiguration ToConfiguration(TCalculation calculation);
+
+ ///
+ /// Converts a sequence of into a sequence of .
+ ///
+ /// The sequence to be converted into a sequence of
+ /// .
+ /// The converted of .
+ /// Thrown when an element of
+ /// isn't a nor a .
+ private IEnumerable ToConfiguration(IEnumerable calculations)
+ {
+ foreach (ICalculationBase child in calculations)
+ {
+ var innerGroup = child as CalculationGroup;
+ if (innerGroup != null)
+ {
+ yield return ToConfiguration(innerGroup);
+ }
+
+ var calculation = child as TCalculation;
+ if (calculation != null)
+ {
+ yield return ToConfiguration(calculation);
+ }
+
+ if (innerGroup == null && calculation == null)
+ {
+ throw new ArgumentException($"Cannot export calculation of type '{child.GetType()}' using this exporter.");
+ }
+ }
+ }
+
+ private CalculationGroupConfiguration ToConfiguration(CalculationGroup group)
+ {
+ return new CalculationGroupConfiguration(group.Name, ToConfiguration(group.Children).ToArray());
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/SchemaCalculationConfigurationWriter.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/SchemaCalculationConfigurationWriter.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/SchemaCalculationConfigurationWriter.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,242 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.Xml;
+using Core.Common.IO.Exceptions;
+using Core.Common.Utils;
+using Core.Common.Utils.Properties;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Helpers;
+
+namespace Ringtoets.Common.IO.Configurations.Export
+{
+ ///
+ /// Base implementation of writing calculation configurations to XML.
+ ///
+ /// The type of calculations which are written to file.
+ public abstract class SchemaCalculationConfigurationWriter where T : class, IConfigurationItem
+ {
+ private readonly string filePath;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The path of the file to write to.
+ /// Thrown when is invalid.
+ /// A valid path:
+ ///
+ /// - is not empty or null,
+ /// - does not consist out of only whitespace characters,
+ /// - does not contain an invalid character,
+ /// - does not end with a directory or path separator (empty file name).
+ ///
+ protected SchemaCalculationConfigurationWriter(string filePath)
+ {
+ this.filePath = filePath;
+ IOUtils.ValidateFilePath(filePath);
+ }
+
+ ///
+ /// Writes a calculation configuration to an XML file.
+ ///
+ /// The calculation configuration to write.
+ /// Thrown when any parameter is null.
+ /// Thrown when unable to write the file to the provided file path.
+ public void Write(IEnumerable configuration)
+ {
+ if (configuration == null)
+ {
+ throw new ArgumentNullException(nameof(configuration));
+ }
+
+ try
+ {
+ var settings = new XmlWriterSettings
+ {
+ Indent = true
+ };
+
+ using (XmlWriter writer = XmlWriter.Create(filePath, settings))
+ {
+ writer.WriteStartDocument();
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.ConfigurationElement);
+
+ WriteConfiguration(configuration, writer);
+
+ writer.WriteEndElement();
+ writer.WriteEndDocument();
+ }
+ }
+ catch (SystemException e)
+ {
+ throw new CriticalFileWriteException(string.Format(Resources.Error_General_output_error_0, filePath), e);
+ }
+ }
+
+ ///
+ /// Writes a single in XML format to file.
+ ///
+ /// The calculation configuration to write.
+ /// The writer to use for writing.
+ /// Thrown when the is closed.
+ protected abstract void WriteCalculation(T configuration, XmlWriter writer);
+
+ ///
+ /// Writes a distribution configuration when it has a value.
+ ///
+ /// The writer to use for writing.
+ /// The name of the distribution.
+ /// The configuration for the distribution that can be null.
+ /// Thrown when or
+ /// is null.
+ protected static void WriteDistributionWhenAvailable(XmlWriter writer, string distributionName, StochastConfiguration configuration)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+ if (distributionName == null)
+ {
+ throw new ArgumentNullException(nameof(distributionName));
+ }
+
+ if (configuration != null)
+ {
+ writer.WriteDistribution(distributionName, configuration);
+ }
+ }
+
+ ///
+ /// Writes an element with some content when the content has a value.
+ ///
+ /// The writer to use for writing.
+ /// The name of the element.
+ /// The content of the element that can be null.
+ /// Thrown when or
+ /// is null.
+ protected static void WriteElementWhenContentAvailable(XmlWriter writer, string elementName, string elementContent)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+ if (elementName == null)
+ {
+ throw new ArgumentNullException(nameof(elementName));
+ }
+
+ if (elementContent != null)
+ {
+ writer.WriteElementString(
+ elementName,
+ elementContent);
+ }
+ }
+
+ ///
+ /// Writes an element with some content when the content has a value.
+ ///
+ /// The writer to use for writing.
+ /// The name of the element.
+ /// The content of the element that can be null.
+ /// Thrown when or
+ /// is null.
+ protected static void WriteElementWhenContentAvailable(XmlWriter writer, string elementName, double? elementContent)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+ if (elementName == null)
+ {
+ throw new ArgumentNullException(nameof(elementName));
+ }
+
+ if (elementContent.HasValue)
+ {
+ writer.WriteElementString(
+ elementName,
+ XmlConvert.ToString(elementContent.Value));
+ }
+ }
+
+ ///
+ /// Writes a wave reduction configuration when it has a value.
+ ///
+ /// The writer to use for writing.
+ /// The configuration for the wave reduction that can be null.
+ /// Thrown when is null.
+ protected static void WriteWaveReductionWhenAvailable(XmlWriter writer, WaveReductionConfiguration configuration)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ if (configuration != null)
+ {
+ writer.WriteWaveReduction(configuration);
+ }
+ }
+
+ ///
+ /// Writes the in XML format to file.
+ ///
+ /// The calculation group(s) and/or calculation(s) to write.
+ /// The writer to use for writing.
+ /// Thrown when
+ /// contains a value that is neither nor .
+ private void WriteConfiguration(IEnumerable configuration, XmlWriter writer)
+ {
+ foreach (IConfigurationItem child in configuration)
+ {
+ var innerGroup = child as CalculationGroupConfiguration;
+ if (innerGroup != null)
+ {
+ WriteCalculationGroup(innerGroup, writer);
+ }
+
+ var calculation = child as T;
+ if (calculation != null)
+ {
+ WriteCalculation(calculation, writer);
+ }
+
+ if (innerGroup == null && calculation == null)
+ {
+ throw new ArgumentException($"Cannot write calculation of type '{child.GetType()}' using this writer.");
+ }
+ }
+ }
+
+ private void WriteCalculationGroup(CalculationGroupConfiguration group, XmlWriter writer)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.FolderElement);
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, group.Name);
+
+ WriteConfiguration(group.Items, writer);
+
+ writer.WriteEndElement();
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/StructureCalculationConfigurationWriter.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/StructureCalculationConfigurationWriter.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Export/StructureCalculationConfigurationWriter.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,129 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Xml;
+
+namespace Ringtoets.Common.IO.Configurations.Export
+{
+ ///
+ /// Writer for writing in XML format to file.
+ ///
+ public abstract class StructureCalculationConfigurationWriter : SchemaCalculationConfigurationWriter
+ where T : StructuresCalculationConfiguration
+ {
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The path of the file to write to.
+ /// Thrown when is invalid.
+ /// A valid path:
+ ///
+ /// - is not empty or null,
+ /// - does not consist out of only whitespace characters,
+ /// - does not contain an invalid character,
+ /// - does not end with a directory or path separator (empty file name).
+ ///
+ protected StructureCalculationConfigurationWriter(string filePath) : base(filePath) { }
+
+ protected override void WriteCalculation(T configuration, XmlWriter writer)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.CalculationElement);
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, configuration.Name);
+
+ WriteParameters(configuration, writer);
+
+ WriteWaveReductionWhenAvailable(writer, configuration.WaveReduction);
+
+ WriteStochasts(configuration, writer);
+
+ writer.WriteEndElement();
+ }
+
+ ///
+ /// Writes properties specific for a structure of type .
+ ///
+ /// The instance of type for which
+ /// to write the input.
+ /// The writer that should be used to write the parameters.
+ protected virtual void WriteSpecificStructureParameters(T configuration, XmlWriter writer) { }
+
+ ///
+ /// Writes stochasts definitions specific for a structure of type .
+ ///
+ /// The instance of type for which
+ /// to write the stochasts.
+ /// The writer that should be used to write the parameters.
+ protected abstract void WriteSpecificStochasts(T configuration, XmlWriter writer);
+
+ private void WriteParameters(T configuration, XmlWriter writer)
+ {
+ WriteElementWhenContentAvailable(writer,
+ ConfigurationSchemaIdentifiers.HydraulicBoundaryLocationElement,
+ configuration.HydraulicBoundaryLocationName);
+ WriteElementWhenContentAvailable(writer,
+ ConfigurationSchemaIdentifiers.StructureElement,
+ configuration.StructureName);
+ WriteElementWhenContentAvailable(writer,
+ ConfigurationSchemaIdentifiers.Orientation,
+ configuration.StructureNormalOrientation);
+ WriteElementWhenContentAvailable(writer,
+ ConfigurationSchemaIdentifiers.FailureProbabilityStructureWithErosionElement,
+ configuration.FailureProbabilityStructureWithErosion);
+ WriteElementWhenContentAvailable(writer,
+ ConfigurationSchemaIdentifiers.ForeshoreProfileNameElement,
+ configuration.ForeshoreProfileName);
+
+ WriteSpecificStructureParameters(configuration, writer);
+ }
+
+ private void WriteStochasts(T configuration, XmlWriter writer)
+ {
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.StochastsElement);
+
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.FlowWidthAtBottomProtectionStochastName,
+ configuration.FlowWidthAtBottomProtection);
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.WidthFlowAperturesStochastName,
+ configuration.WidthFlowApertures);
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.StorageStructureAreaStochastName,
+ configuration.StorageStructureArea);
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.CriticalOvertoppingDischargeStochastName,
+ configuration.CriticalOvertoppingDischarge);
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.ModelFactorSuperCriticalFlowStochastName,
+ configuration.ModelFactorSuperCriticalFlow);
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.AllowedLevelIncreaseStorageStochastName,
+ configuration.AllowedLevelIncreaseStorage);
+ WriteDistributionWhenAvailable(writer,
+ ConfigurationSchemaIdentifiers.StormDurationStochastName,
+ configuration.StormDuration);
+
+ WriteSpecificStochasts(configuration, writer);
+
+ writer.WriteEndElement();
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/ConfigurationBreakWaterTypeConverter.cs
===================================================================
diff -u -rc0c4d914f97d3471b73898030db0066dced39331 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/ConfigurationBreakWaterTypeConverter.cs (.../ConfigurationBreakWaterTypeConverter.cs) (revision c0c4d914f97d3471b73898030db0066dced39331)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/ConfigurationBreakWaterTypeConverter.cs (.../ConfigurationBreakWaterTypeConverter.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -23,7 +23,6 @@
using System.ComponentModel;
using System.Globalization;
using Ringtoets.Common.Data.DikeProfiles;
-using Ringtoets.Common.IO.Schema;
namespace Ringtoets.Common.IO.Configurations.Helpers
{
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/XElementExtensions.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/XElementExtensions.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/XElementExtensions.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,234 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.ComponentModel;
+using System.Linq;
+using System.Xml;
+using System.Xml.Linq;
+
+namespace Ringtoets.Common.IO.Configurations.Helpers
+{
+ ///
+ /// Extensions methods for .
+ ///
+ public static class XElementExtensions
+ {
+ ///
+ /// Gets the value from a descendant element.
+ ///
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The value of the element, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when any parameter is null.
+ /// Thrown when the value isn't in the correct format.
+ /// Thrown when the value represents a number
+ /// less than or greater than .
+ public static double? GetDoubleValueFromDescendantElement(this XElement parentElement, string descendantElementName)
+ {
+ XElement descendantElement = parentElement.GetDescendantElement(descendantElementName);
+
+ return descendantElement != null
+ ? (double?) XmlConvert.ToDouble(descendantElement.Value)
+ : null;
+ }
+
+ ///
+ /// Gets the value from a descendant element.
+ ///
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The value of the element, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when any parameter is null.
+ /// Thrown when the value isn't in the correct format.
+ /// Thrown when the value represents a number
+ /// less than or greater than .
+ public static int? GetIntegerValueFromDescendantElement(this XElement parentElement, string descendantElementName)
+ {
+ XElement descendantElement = parentElement.GetDescendantElement(descendantElementName);
+
+ return descendantElement != null
+ ? (int?) XmlConvert.ToInt32(descendantElement.Value)
+ : null;
+ }
+
+ ///
+ /// Gets the value from a descendant element.
+ ///
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The value of the element, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when any parameter is null.
+ public static string GetStringValueFromDescendantElement(this XElement parentElement, string descendantElementName)
+ {
+ XElement descendantElement = parentElement.GetDescendantElement(descendantElementName);
+
+ return descendantElement?.Value;
+ }
+
+ ///
+ /// Gets the value from a descendant element.
+ ///
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The value, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when any parameter is null.
+ /// Thrown when the value does not represent a value.
+ public static bool? GetBoolValueFromDescendantElement(this XElement parentElement, string descendantElementName)
+ {
+ XElement descendantElement = parentElement.GetDescendantElement(descendantElementName);
+
+ return descendantElement != null
+ ? (bool?) XmlConvert.ToBoolean(descendantElement.Value)
+ : null;
+ }
+
+ ///
+ /// Gets the converted value from a descendant element containing a string.
+ ///
+ /// The to use
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The converted value, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when calling .
+ /// results in an exception being thrown.
+ /// Thrown when any parameter is null.
+ /// Thrown when the conversion cannot be performed.
+ public static object GetConvertedValueFromDescendantStringElement(this XElement parentElement, string descendantElementName)
+ where TConverter : TypeConverter, new()
+ {
+ string stringValue = parentElement.GetStringValueFromDescendantElement(descendantElementName);
+ if (stringValue == null)
+ {
+ return null;
+ }
+ return new TConverter().ConvertFromInvariantString(stringValue);
+ }
+
+ ///
+ /// Gets the converted value from a descendant element containing a double.
+ ///
+ /// The to use
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The converted value, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when calling .
+ /// results in an exception being thrown.
+ /// Thrown when any parameter is null.
+ /// Thrown when the value from a descendant element is
+ /// not in the correct format.
+ /// Thrown when the value from a descendant element
+ /// represents a number less than or greater than .
+ /// Thrown when the conversion cannot be performed.
+ public static object GetConvertedValueFromDescendantDoubleElement(this XElement parentElement, string descendantElementName)
+ where TConverter : TypeConverter, new()
+ {
+ double? doubleValue = parentElement.GetDoubleValueFromDescendantElement(descendantElementName);
+ if (doubleValue == null)
+ {
+ return null;
+ }
+ return new TConverter().ConvertFrom(doubleValue);
+ }
+
+ ///
+ /// Gets the 'stochast' element from the descendant 'stochasts' element.
+ ///
+ /// The that contains the descendant element.
+ /// The name of the stochast element.
+ /// The stochast element, or null when the
+ /// does not have stochast elements with the name .
+ /// Thrown when any parameter is null.
+ public static XElement GetStochastElement(this XElement parentElement, string stochastName)
+ {
+ if (parentElement == null)
+ {
+ throw new ArgumentNullException(nameof(parentElement));
+ }
+ if (stochastName == null)
+ {
+ throw new ArgumentNullException(nameof(stochastName));
+ }
+
+ return parentElement.Elements(ConfigurationSchemaIdentifiers.StochastsElement)
+ .FirstOrDefault()?
+ .Elements(ConfigurationSchemaIdentifiers.StochastElement)
+ .FirstOrDefault(e => e.Attribute(ConfigurationSchemaIdentifiers.NameAttribute)?.Value == stochastName);
+ }
+
+ ///
+ /// Gets a descendant element with the given .
+ ///
+ /// The that contains the descendant element.
+ /// The name of the descendant element.
+ /// The element, or null when the
+ /// does not have descendant elements of .
+ /// Thrown when any parameter is null.
+ public static XElement GetDescendantElement(this XElement parentElement, string descendantElementName)
+ {
+ if (parentElement == null)
+ {
+ throw new ArgumentNullException(nameof(parentElement));
+ }
+ if (descendantElementName == null)
+ {
+ throw new ArgumentNullException(nameof(descendantElementName));
+ }
+
+ return parentElement.Descendants(descendantElementName).FirstOrDefault();
+ }
+
+ /// Thrown when any parameter is null.
+ /// Thrown when the value isn't in the correct format.
+ /// Thrown when the value for mean or standard deviation represents a
+ /// number less than or greater than .
+ public static StochastConfiguration GetStochastParameters(this XElement calculationElement, string stochastName)
+ {
+ if (calculationElement == null)
+ {
+ throw new ArgumentNullException(nameof(calculationElement));
+ }
+ if (stochastName == null)
+ {
+ throw new ArgumentNullException(nameof(stochastName));
+ }
+
+ XElement element = calculationElement.GetStochastElement(stochastName);
+
+ if (element != null)
+ {
+ return new StochastConfiguration
+ {
+ Mean = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.MeanElement),
+ StandardDeviation = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.StandardDeviationElement),
+ VariationCoefficient = element.GetDoubleValueFromDescendantElement(ConfigurationSchemaIdentifiers.VariationCoefficientElement)
+ };
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/XmlWriterExtensions.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/XmlWriterExtensions.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Helpers/XmlWriterExtensions.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,138 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Xml;
+
+namespace Ringtoets.Common.IO.Configurations.Helpers
+{
+ ///
+ /// Extension methods for an , for writing generic data components in XML format
+ /// to file.
+ ///
+ public static class XmlWriterExtensions
+ {
+ ///
+ /// Writes a single as a stochast element in file.
+ ///
+ /// The writer to use to write the distribution.
+ /// The name of the distribution to write.
+ /// The distribution to write.
+ /// Thrown when the is
+ /// in an invalid state for writing.
+ /// Thrown when any of the input parameters is null.
+ public static void WriteDistribution(this XmlWriter writer, string name, StochastConfiguration distribution)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (distribution == null)
+ {
+ throw new ArgumentNullException(nameof(distribution));
+ }
+
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.StochastElement);
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, name);
+
+ if (distribution.Mean.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.MeanElement, XmlConvert.ToString(distribution.Mean.Value));
+ }
+ if (distribution.StandardDeviation.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.StandardDeviationElement, XmlConvert.ToString(distribution.StandardDeviation.Value));
+ }
+ if (distribution.VariationCoefficient.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.VariationCoefficientElement, XmlConvert.ToString(distribution.VariationCoefficient.Value));
+ }
+
+ writer.WriteEndElement();
+ }
+
+ ///
+ /// Writes a single as a wave reduction element in file.
+ ///
+ /// The writer to use to write the wave reduction.
+ /// The wave reduction to write.
+ /// Thrown when the is
+ /// in an invalid state for writing.
+ /// Thrown when any of the input parameters is null.
+ public static void WriteWaveReduction(this XmlWriter writer, WaveReductionConfiguration waveReduction)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+ if (waveReduction == null)
+ {
+ throw new ArgumentNullException(nameof(waveReduction));
+ }
+
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.WaveReduction);
+
+ if (waveReduction.UseBreakWater.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.UseBreakWater, XmlConvert.ToString(waveReduction.UseBreakWater.Value));
+ }
+ if (waveReduction.BreakWaterType.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.BreakWaterType, new ConfigurationBreakWaterTypeConverter().ConvertToInvariantString(waveReduction.BreakWaterType.Value));
+ }
+ if (waveReduction.BreakWaterHeight.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.BreakWaterHeight, XmlConvert.ToString(waveReduction.BreakWaterHeight.Value));
+ }
+ if (waveReduction.UseForeshoreProfile.HasValue)
+ {
+ writer.WriteElementString(ConfigurationSchemaIdentifiers.UseForeshore, XmlConvert.ToString(waveReduction.UseForeshoreProfile.Value));
+ }
+
+ writer.WriteEndElement();
+ }
+
+ ///
+ /// Writes the start tag of a folder element.
+ ///
+ /// The writer to use to write the folder.
+ /// The name of the folder.
+ /// Thrown when any of the input parameters is null.
+ public static void WriteStartFolder(this XmlWriter writer, string name)
+ {
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ writer.WriteStartElement(ConfigurationSchemaIdentifiers.FolderElement);
+ writer.WriteAttributeString(ConfigurationSchemaIdentifiers.NameAttribute, name);
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CalculationConfigurationImporter.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CalculationConfigurationImporter.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CalculationConfigurationImporter.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,477 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.Linq;
+using Core.Common.Base.Data;
+using Core.Common.Base.IO;
+using Core.Common.IO.Readers;
+using log4net;
+using Ringtoets.Common.Data;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.Data.DikeProfiles;
+using Ringtoets.Common.Data.Hydraulics;
+using Ringtoets.Common.Data.Probabilistics;
+using Ringtoets.Common.IO.Configurations.Helpers;
+using Ringtoets.Common.IO.Properties;
+
+namespace Ringtoets.Common.IO.Configurations.Import
+{
+ ///
+ /// Base class for importing a calculation configuration from an XML file and storing it on a .
+ ///
+ /// The type of the reader to use for reading the XML file.
+ /// The type of the data read from the XML file by the reader.
+ public abstract class CalculationConfigurationImporter
+ : FileImporterBase
+ where TCalculationConfigurationReader : CalculationConfigurationReader
+ where TReadCalculation : class, IConfigurationItem
+ {
+ protected readonly ILog Log = LogManager.GetLogger(typeof(CalculationConfigurationImporter));
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The path to the XML file to import from.
+ /// The calculation group to update.
+ /// Thrown when any parameter is null.
+ protected CalculationConfigurationImporter(string xmlFilePath, CalculationGroup importTarget)
+ : base(xmlFilePath, importTarget) { }
+
+ protected override void LogImportCanceledMessage()
+ {
+ Log.Info(Resources.CalculationConfigurationImporter_LogImportCanceledMessage_Import_canceled_no_data_read);
+ }
+
+ protected override bool OnImport()
+ {
+ NotifyProgress(Resources.CalculationConfigurationImporter_ProgressText_Reading_configuration, 1, 3);
+
+ ReadResult readResult = ReadConfiguration();
+ if (readResult.CriticalErrorOccurred || Canceled)
+ {
+ return false;
+ }
+
+ NotifyProgress(Resources.CalculationConfigurationImporter_ProgressText_Validating_imported_data, 2, 3);
+
+ var parsedCalculationItems = new List();
+
+ foreach (IConfigurationItem readItem in readResult.Items)
+ {
+ if (Canceled)
+ {
+ return false;
+ }
+
+ ICalculationBase parsedItem = ParseReadConfigurationItem(readItem);
+ if (parsedItem != null)
+ {
+ parsedCalculationItems.Add(parsedItem);
+ }
+ }
+
+ NotifyProgress(Resources.Importer_ProgressText_Adding_imported_data_to_data_model, 3, 3);
+
+ AddItemsToModel(parsedCalculationItems);
+
+ return true;
+ }
+
+ ///
+ /// Creates the reader used for reading the calculation configuration from the provided .
+ ///
+ /// The path to the XML file to import from.
+ /// A reader for reading the calculation configuration.
+ /// Thrown when is invalid.
+ /// Thrown when:
+ ///
+ /// - points to a file that does not exist.
+ /// - points to a file that does not contain valid XML.
+ /// - points to a file that does not pass the schema validation.
+ /// - points to a file that does not contain configuration elements.
+ ///
+ ///
+ protected abstract TCalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath);
+
+ ///
+ /// Parses a calculation from the provided .
+ ///
+ /// The calculation read from XML.
+ /// A parsed calculation instance, or null when something goes wrong while parsing.
+ protected abstract ICalculation ParseReadCalculation(TReadCalculation readCalculation);
+
+ ///
+ /// Tries to find the hydraulic boundary location with the given
+ /// in the .
+ ///
+ /// The name of the location to find.
+ /// Name of the calculation to assign the location to.
+ /// The collection of
+ /// to search in.
+ /// The location with the name equal to
+ /// if there was any.
+ /// true if no is given, or when a location with
+ /// the name was found, false otherwise.
+ /// Thrown when
+ /// or is null.
+ protected bool TryReadHydraulicBoundaryLocation(
+ string locationName,
+ string calculationName,
+ IEnumerable hydraulicBoundaryLocations,
+ out HydraulicBoundaryLocation foundLocation)
+ {
+ if (calculationName == null)
+ {
+ throw new ArgumentNullException(nameof(calculationName));
+ }
+ if (hydraulicBoundaryLocations == null)
+ {
+ throw new ArgumentNullException(nameof(hydraulicBoundaryLocations));
+ }
+
+ foundLocation = null;
+
+ if (locationName != null)
+ {
+ HydraulicBoundaryLocation location = hydraulicBoundaryLocations.FirstOrDefault(l => l.Name == locationName);
+
+ if (location == null)
+ {
+ Log.LogCalculationConversionError(string.Format(
+ Resources.CalculationConfigurationImporter_ReadHydraulicBoundaryLocation_HydraulicBoundaryLocation_0_does_not_exist,
+ locationName),
+ calculationName);
+
+ return false;
+ }
+
+ foundLocation = location;
+ }
+ return true;
+ }
+
+ ///
+ /// Tries to find the structure with the given
+ /// in the .
+ ///
+ /// The type of the to read.
+ /// The name of the structure to find.
+ /// Name of the calculation to assign the structure to.
+ /// The collection of to search in.
+ /// The structure with the name equal to
+ /// if there was any.
+ /// true if no is given, or when a structure with
+ /// the name was found, false otherwise.
+ /// Thrown when
+ /// or is null.
+ protected bool TryReadStructure(
+ string structureName,
+ string calculationName,
+ IEnumerable structures,
+ out T foundStructure)
+ where T : StructureBase
+ {
+ if (calculationName == null)
+ {
+ throw new ArgumentNullException(nameof(calculationName));
+ }
+ if (structures == null)
+ {
+ throw new ArgumentNullException(nameof(structures));
+ }
+ foundStructure = null;
+ if (structureName != null)
+ {
+ T structure = structures.FirstOrDefault(l => l.Name == structureName);
+
+ if (structure == null)
+ {
+ Log.LogCalculationConversionError(string.Format(
+ Resources.CalculationConfigurationImporter_ReadStructure_Structure_0_does_not_exist,
+ structureName),
+ calculationName);
+
+ return false;
+ }
+
+ foundStructure = structure;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Tries to find the foreshore profile with the given
+ /// in the .
+ ///
+ /// The name of the foreshore profile to find.
+ /// Name of the calculation to assign the foreshore profile to.
+ /// The collection of to search in.
+ /// The foreshore profile with the name equal to
+ /// if there was any.
+ /// true if no is given, or when a foreshore profile with
+ /// the name was found, false otherwise.
+ /// Thrown when
+ /// or is null.
+ protected bool TryReadForeshoreProfile(
+ string foreshoreProfileName,
+ string calculationName,
+ IEnumerable foreshoreProfiles,
+ out ForeshoreProfile foundForeshoreProfile)
+ {
+ if (calculationName == null)
+ {
+ throw new ArgumentNullException(nameof(calculationName));
+ }
+ if (foreshoreProfiles == null)
+ {
+ throw new ArgumentNullException(nameof(foreshoreProfiles));
+ }
+
+ foundForeshoreProfile = null;
+
+ if (foreshoreProfileName != null)
+ {
+ ForeshoreProfile foreshoreProfile = foreshoreProfiles.FirstOrDefault(fp => fp.Name == foreshoreProfileName);
+
+ if (foreshoreProfile == null)
+ {
+ Log.LogCalculationConversionError(string.Format(
+ Resources.CalculationConfigurationImporter_ReadForeshoreProfile_ForeshoreProfile_0_does_not_exist,
+ foreshoreProfileName),
+ calculationName);
+
+ return false;
+ }
+
+ foundForeshoreProfile = foreshoreProfile;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Assigns the parameters to the .
+ ///
+ /// Type of the input for which values are assigned from the configuration.
+ /// The wave reduction configuration containing values for the parameters.
+ /// The input to assign the values to.
+ protected static void ReadWaveReductionParameters(WaveReductionConfiguration waveReduction, T input)
+ where T : IUseBreakWater, IUseForeshore
+ {
+ if (waveReduction != null)
+ {
+ if (waveReduction.UseForeshoreProfile.HasValue)
+ {
+ input.UseForeshore = waveReduction.UseForeshoreProfile.Value;
+ }
+
+ if (waveReduction.UseBreakWater.HasValue)
+ {
+ input.UseBreakWater = waveReduction.UseBreakWater.Value;
+ }
+
+ if (waveReduction.BreakWaterType.HasValue)
+ {
+ input.BreakWater.Type = (BreakWaterType) new ConfigurationBreakWaterTypeConverter().ConvertTo(waveReduction.BreakWaterType.Value, typeof(BreakWaterType));
+ }
+
+ if (waveReduction.BreakWaterHeight.HasValue)
+ {
+ input.BreakWater.Height = (RoundedDouble) waveReduction.BreakWaterHeight.Value;
+ }
+ }
+ }
+
+ ///
+ /// Reads the stochast parameters.
+ ///
+ /// The type of the distribution to read.
+ /// The type of the calculation input.
+ /// The stochast's name.
+ /// The name of the calculation to configure.
+ /// The input for which to assign the read stochast.
+ /// The configuration of the stochast.
+ /// The function for obtaining the stochast to read.
+ /// The function to set the stochast with the read parameters.
+ /// true if reading all required stochast parameters was successful,
+ /// false otherwise.
+ protected bool TryReadStandardDeviationStochast(
+ string stochastName,
+ string calculationName,
+ TCalculationInput input,
+ StochastConfiguration stochastConfiguration,
+ Func getStochast,
+ Action setStochast)
+ where TDistribution : IDistribution
+ where TCalculationInput : ICalculationInput
+ {
+ if (stochastConfiguration == null)
+ {
+ return true;
+ }
+ if (stochastConfiguration.VariationCoefficient.HasValue)
+ {
+ Log.LogCalculationConversionError(string.Format(
+ Resources.CalculationConfigurationImporter_TryReadStandardDeviationStochast_Stochast_0_requires_standard_deviation_but_variation_coefficient_found_for_Calculation_1_,
+ stochastName,
+ calculationName),
+ calculationName);
+
+ return false;
+ }
+
+ var distribution = (TDistribution) getStochast(input).Clone();
+ if (!distribution.TrySetDistributionProperties(stochastConfiguration,
+ stochastName,
+ calculationName))
+ {
+ return false;
+ }
+ setStochast(input, distribution);
+ return true;
+ }
+
+ ///
+ /// Reads the stochast parameters.
+ ///
+ /// The type of the distribution to read.
+ /// The type of the calculation input.
+ /// The stochast's name.
+ /// The name of the calculation to configure.
+ /// The input for which to assign the read stochast.
+ /// The configuration of the stochast.
+ /// The function for obtaining the stochast to read.
+ /// The function to set the stochast with the read parameters.
+ /// true if reading all required stochast parameters was successful,
+ /// false otherwise.
+ protected bool TryReadVariationCoefficientStochast(
+ string stochastName,
+ string calculationName,
+ TCalculationInput input,
+ StochastConfiguration stochastConfiguration,
+ Func getStochast,
+ Action setStochast)
+ where TDistribution : IVariationCoefficientDistribution
+ where TCalculationInput : ICalculationInput
+ {
+ if (stochastConfiguration == null)
+ {
+ return true;
+ }
+ if (stochastConfiguration.StandardDeviation.HasValue)
+ {
+ Log.LogCalculationConversionError(string.Format(
+ Resources.CalculationConfigurationImporter_TryReadVariationCoefficientStochast_Stochast_0_requires_variation_coefficient_but_standard_deviation_found_for_Calculation_1_,
+ stochastName,
+ calculationName),
+ calculationName);
+
+ return false;
+ }
+
+ var distribution = (TDistribution) getStochast(input).Clone();
+ if (!distribution.TrySetDistributionProperties(stochastConfiguration,
+ stochastName,
+ calculationName))
+ {
+ return false;
+ }
+ setStochast(input, distribution);
+ return true;
+ }
+
+ private ReadResult ReadConfiguration()
+ {
+ try
+ {
+ return new ReadResult(false)
+ {
+ Items = CreateCalculationConfigurationReader(FilePath).Read().ToList()
+ };
+ }
+ catch (Exception exception) when (exception is ArgumentException
+ || exception is CriticalFileReadException)
+ {
+ string errorMessage = string.Format(Resources.CalculationConfigurationImporter_HandleCriticalFileReadError_Error_0_no_configuration_imported,
+ exception.Message);
+ Log.Error(errorMessage, exception);
+ return new ReadResult(true);
+ }
+ }
+
+ ///
+ /// Parses the read configuration item.
+ ///
+ /// The read item to parse.
+ /// A parsed calculation item.
+ /// Thrown when the item to parse is not valid.
+ private ICalculationBase ParseReadConfigurationItem(IConfigurationItem readConfigurationItem)
+ {
+ var readCalculationGroup = readConfigurationItem as CalculationGroupConfiguration;
+ if (readCalculationGroup != null)
+ {
+ return ParseReadCalculationGroup(readCalculationGroup);
+ }
+
+ var readCalculation = readConfigurationItem as TReadCalculation;
+ if (readCalculation != null)
+ {
+ return ParseReadCalculation(readCalculation);
+ }
+
+ throw new InvalidOperationException("Can't parse item that is not a calculation or calculation group.");
+ }
+
+ ///
+ /// Parses the read calculation group and it's children.
+ ///
+ /// The calculation group to parse.
+ /// A parsed calculation group.
+ /// Thrown when the one of the children
+ /// to parse is not valid.
+ private CalculationGroup ParseReadCalculationGroup(CalculationGroupConfiguration readCalculationGroup)
+ {
+ var calculationGroup = new CalculationGroup(readCalculationGroup.Name, true);
+
+ foreach (IConfigurationItem item in readCalculationGroup.Items)
+ {
+ ICalculationBase parsedItem = ParseReadConfigurationItem(item);
+ if (parsedItem != null)
+ {
+ calculationGroup.Children.Add(parsedItem);
+ }
+ }
+
+ return calculationGroup;
+ }
+
+ private void AddItemsToModel(IEnumerable parsedCalculationItems)
+ {
+ foreach (ICalculationBase parsedCalculationItem in parsedCalculationItems)
+ {
+ ImportTarget.Children.Add(parsedCalculationItem);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CalculationConfigurationReader.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CalculationConfigurationReader.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CalculationConfigurationReader.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,236 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using Core.Common.Base.IO;
+using Core.Common.Utils;
+using Core.Common.Utils.Builders;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Properties;
+using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources;
+
+namespace Ringtoets.Common.IO.Configurations.Import
+{
+ ///
+ /// Base class for reading a calculation configuration from XML and creating a collection of corresponding
+ /// , typically containing one or more .
+ ///
+ /// The type of calculation items read from XML.
+ public abstract class CalculationConfigurationReader
+ where TReadCalculation : IConfigurationItem
+ {
+ private const string defaultSchemaName = "ConfiguratieSchema.xsd";
+
+ private readonly XDocument xmlDocument;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The file path to the XML file.
+ /// A string representing the main schema definition.
+ /// A containing
+ /// zero to more nested schema definitions. The keys should represent unique file names by which
+ /// the schema definitions can be referenced from ; the
+ /// values should represent their corresponding schema definition string.
+ /// Thrown when
+ /// is null.
+ /// Thrown when:
+ ///
+ /// - is invalid.
+ /// - is invalid.
+ /// - contains invalid schema definition values.
+ /// - , all together with its referenced
+ /// , contains an invalid schema definition.
+ /// - contains schema definitions that are not
+ /// referenced by .
+ /// - does not reference the default schema definition
+ /// ConfiguratieSchema.xsd.
+ ///
+ ///
+ /// Thrown when:
+ ///
+ /// - points to a file that does not exist.
+ /// - points to a file that does not contain valid XML.
+ /// - points to a file that does not pass the schema validation.
+ /// - points to a file that does not contain configuration elements.
+ ///
+ ///
+ protected CalculationConfigurationReader(string xmlFilePath, string mainSchemaDefinition, IDictionary nestedSchemaDefinitions)
+ {
+ IOUtils.ValidateFilePath(xmlFilePath);
+
+ ValidateFileExists(xmlFilePath);
+
+ xmlDocument = LoadDocument(xmlFilePath);
+
+ ValidateToSchema(xmlDocument, xmlFilePath, mainSchemaDefinition, nestedSchemaDefinitions);
+
+ ValidateNotEmpty(xmlDocument, xmlFilePath);
+ }
+
+ ///
+ /// Reads the calculation configuration from the XML and creates a collection of corresponding .
+ ///
+ /// A collection of read .
+ public IEnumerable Read()
+ {
+ return ParseElements(xmlDocument.Root?.Elements());
+ }
+
+ ///
+ /// Parses a read calculation element.
+ ///
+ /// The read calculation element to parse.
+ /// A parsed .
+ protected abstract TReadCalculation ParseCalculationElement(XElement calculationElement);
+
+ ///
+ /// Validates whether a file exists at the provided .
+ ///
+ /// The file path to validate.
+ /// Thrown when no existing file is found.
+ private static void ValidateFileExists(string xmlFilePath)
+ {
+ if (!File.Exists(xmlFilePath))
+ {
+ string message = new FileReaderErrorMessageBuilder(xmlFilePath)
+ .Build(CoreCommonUtilsResources.Error_File_does_not_exist);
+
+ throw new CriticalFileReadException(message);
+ }
+ }
+
+ ///
+ /// Loads an XML document from the provided .
+ ///
+ /// The file path to load the XML document from.
+ /// Thrown when the XML document cannot be loaded.
+ private static XDocument LoadDocument(string xmlFilePath)
+ {
+ try
+ {
+ return XDocument.Load(xmlFilePath, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo | LoadOptions.SetBaseUri);
+ }
+ catch (XmlException exception)
+ {
+ string exceptionMessage = string.Format(Resources.CalculationConfigurationReader_Configuration_contains_no_valid_xml_Reason_0_,
+ exception.Message);
+
+ throw new CriticalFileReadException(new FileReaderErrorMessageBuilder(xmlFilePath).Build(exceptionMessage), exception);
+ }
+ catch (Exception exception)
+ when (exception is InvalidOperationException || exception is IOException)
+ {
+ string message = new FileReaderErrorMessageBuilder(xmlFilePath)
+ .Build(CoreCommonUtilsResources.Error_General_IO_Import_ErrorMessage);
+
+ throw new CriticalFileReadException(message, exception);
+ }
+ }
+
+ ///
+ /// Validates the provided XML document based on the provided schema definitions.
+ ///
+ /// The XML document to validate.
+ /// The file path the XML document is loaded from.
+ /// A string representing the main schema definition.
+ /// A containing
+ /// zero to more nested schema definitions
+ /// Thrown when the provided XML document does not match
+ /// the provided schema definitions.
+ /// Thrown when does not
+ /// reference the default schema definition ConfiguratieSchema.xsd.
+ private static void ValidateToSchema(XDocument document, string xmlFilePath, string mainSchemaDefinition,
+ IDictionary nestedSchemaDefinitions)
+ {
+ if (!mainSchemaDefinition.Contains(defaultSchemaName))
+ {
+ throw new ArgumentException($"'{nameof(mainSchemaDefinition)}' does not reference the default schema '{defaultSchemaName}'.");
+ }
+
+ IDictionary extendedNestedSchemaDefinitions = new Dictionary(nestedSchemaDefinitions);
+ extendedNestedSchemaDefinitions.Add(defaultSchemaName, Resources.ConfiguratieSchema);
+
+ var combinedXmlSchemaDefinition = new CombinedXmlSchemaDefinition(mainSchemaDefinition, extendedNestedSchemaDefinitions);
+
+ try
+ {
+ combinedXmlSchemaDefinition.Validate(document);
+ }
+ catch (XmlSchemaValidationException exception)
+ {
+ string message = string.Format(Resources.CalculationConfigurationReader_Configuration_contains_no_valid_xml_line_0_position_1_reason_2,
+ exception.LineNumber,
+ exception.LinePosition,
+ exception.Message);
+
+ throw new CriticalFileReadException(new FileReaderErrorMessageBuilder(xmlFilePath).Build(message), exception);
+ }
+ }
+
+ ///
+ /// Validates whether the provided XML document is not empty.
+ ///
+ /// The XML document to validate.
+ /// The file path the XML document is loaded from.
+ /// Thrown when the provided XML document does not contain configuration items.
+ private static void ValidateNotEmpty(XDocument document, string xmlFilePath)
+ {
+ if (!document.Descendants()
+ .Any(d => d.Name == ConfigurationSchemaIdentifiers.CalculationElement
+ || d.Name == ConfigurationSchemaIdentifiers.FolderElement))
+ {
+ string message = new FileReaderErrorMessageBuilder(xmlFilePath)
+ .Build(Resources.CalculationConfigurationReader_No_configuration_items_found);
+
+ throw new CriticalFileReadException(message);
+ }
+ }
+
+ private IEnumerable ParseElements(IEnumerable elements)
+ {
+ foreach (XElement element in elements)
+ {
+ if (element.Name == ConfigurationSchemaIdentifiers.CalculationElement)
+ {
+ yield return ParseCalculationElement(element);
+ }
+
+ if (element.Name == ConfigurationSchemaIdentifiers.FolderElement)
+ {
+ yield return ParseFolderElement(element);
+ }
+ }
+ }
+
+ private CalculationGroupConfiguration ParseFolderElement(XElement folderElement)
+ {
+ return new CalculationGroupConfiguration(folderElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute)?.Value,
+ ParseElements(folderElement.Elements()));
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CombinedXmlSchemaDefinition.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CombinedXmlSchemaDefinition.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Configurations/Import/CombinedXmlSchemaDefinition.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,195 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+
+namespace Ringtoets.Common.IO.Configurations.Import
+{
+ ///
+ /// Container for related/nested schema definitions, representing a combined XML Schema Definition (XSD).
+ ///
+ public class CombinedXmlSchemaDefinition
+ {
+ private readonly XmlSchemaSet xmlSchemaSet;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// A string representing the main schema definition.
+ /// A containing
+ /// zero to more nested schema definitions. The keys should represent unique file names by which
+ /// the schema definitions can be referenced from ; the
+ /// values should represent their corresponding schema definition string.
+ /// Thrown when
+ /// is null.
+ /// Thrown when:
+ ///
+ /// - is invalid.
+ /// - contains invalid schema definition values.
+ /// - , all together with its referenced
+ /// , contains an invalid schema definition.
+ /// - contains schema definitions that are not
+ /// referenced by .
+ ///
+ ///
+ public CombinedXmlSchemaDefinition(string mainSchemaDefinition, IDictionary nestedSchemaDefinitions)
+ {
+ CheckSchemaDefinitions(mainSchemaDefinition, nestedSchemaDefinitions);
+
+ var nestedSchemaDefinitionsResolver = new NestedSchemaDefinitionsResolver(nestedSchemaDefinitions);
+ xmlSchemaSet = new XmlSchemaSet
+ {
+ XmlResolver = nestedSchemaDefinitionsResolver
+ };
+
+ CompileSchemaSet(mainSchemaDefinition);
+
+ if (!nestedSchemaDefinitionsResolver.AllNestedSchemaDefinitionsReferenced)
+ {
+ throw new ArgumentException($"'{nameof(nestedSchemaDefinitions)}' contains one or more schema definitions that are not referenced.");
+ }
+ }
+
+ ///
+ /// Validates the provided XML document based on the combined schema definition.
+ ///
+ /// The XML document to validate.
+ /// Thrown when the provided XML document does not
+ /// match the combined schema definition.
+ public void Validate(XDocument document)
+ {
+ document.Validate(xmlSchemaSet, null);
+ }
+
+ ///
+ /// Check the provided schema definitions for not being null, empty or only containing white spaces.
+ ///
+ /// A string representing the main schema definition.
+ /// A containing
+ /// zero to more nested schema definitions.
+ /// Thrown when
+ /// is null.
+ /// Thrown when:
+ ///
+ /// - is invalid.
+ /// - contains invalid schema definition values.
+ ///
+ ///
+ private static void CheckSchemaDefinitions(string mainSchemaDefinition, IDictionary nestedSchemaDefinitions)
+ {
+ if (string.IsNullOrWhiteSpace(mainSchemaDefinition))
+ {
+ throw new ArgumentException($"'{nameof(mainSchemaDefinition)}' null, empty or only containing white spaces.");
+ }
+
+ if (nestedSchemaDefinitions == null)
+ {
+ throw new ArgumentNullException(nameof(nestedSchemaDefinitions));
+ }
+
+ if (nestedSchemaDefinitions.Values.Any(string.IsNullOrWhiteSpace))
+ {
+ throw new ArgumentException($"'{nameof(nestedSchemaDefinitions)}' contains one or more nested schema definitions that equal null, are empty or only contain white spaces.");
+ }
+ }
+
+ ///
+ /// Compiles the based on the provided main schema definition.
+ ///
+ /// A string representing the main schema definition.
+ /// Thrown when ,
+ /// all together with its referenced nested schema definitions, contains an invalid schema
+ /// definition.
+ private void CompileSchemaSet(string mainSchemaDefinition)
+ {
+ try
+ {
+ xmlSchemaSet.Add(XmlSchema.Read(new StringReader(mainSchemaDefinition), null));
+ xmlSchemaSet.Compile();
+ }
+ catch (Exception exception) when (exception is XmlException
+ || exception is XmlSchemaException)
+ {
+ throw new ArgumentException($"'{nameof(mainSchemaDefinition)}' invalid: {exception.Message}", exception);
+ }
+ }
+
+ ///
+ /// Resolver for nested schema definitions.
+ ///
+ private class NestedSchemaDefinitionsResolver : XmlResolver
+ {
+ private readonly IDictionary nestedSchemaDefinitions;
+ private readonly IDictionary nestedSchemaDefinitionsUsage;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// A containing
+ /// zero to more nested schema definitions.
+ public NestedSchemaDefinitionsResolver(IDictionary nestedSchemaDefinitions)
+ {
+ this.nestedSchemaDefinitions = nestedSchemaDefinitions;
+ nestedSchemaDefinitionsUsage = nestedSchemaDefinitions.Keys.ToDictionary(k => k, k => false);
+ }
+
+ public override ICredentials Credentials
+ {
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// Gets whether all nested schema definitions are used.
+ ///
+ public bool AllNestedSchemaDefinitionsReferenced
+ {
+ get
+ {
+ return nestedSchemaDefinitionsUsage.Values.All(v => v);
+ }
+ }
+
+ public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
+ {
+ string fileName = Path.GetFileName(absoluteUri.ToString());
+
+ if (nestedSchemaDefinitions.ContainsKey(fileName))
+ {
+ nestedSchemaDefinitionsUsage[fileName] = true;
+ return new MemoryStream(Encoding.UTF8.GetBytes(nestedSchemaDefinitions[fileName]));
+ }
+
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Exporters/CalculationConfigurationExporter.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Exporters/SchemaCalculationConfigurationExporter.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/FileImporters/CalculationConfigurationImporter.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Readers/CalculationConfigurationReader.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Readers/CombinedXmlSchemaDefinition.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Readers/XElementExtensions.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Index: Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj
===================================================================
diff -u -r0404544d0354a059a0b7a02e5f1bca72d6e81d75 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision 0404544d0354a059a0b7a02e5f1bca72d6e81d75)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -69,8 +69,8 @@
-
-
+
+
@@ -89,11 +89,11 @@
-
+
-
+
-
+
@@ -108,8 +108,8 @@
-
-
+
+
@@ -119,10 +119,10 @@
-
-
-
-
+
+
+
+
@@ -210,6 +210,7 @@
+
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Schema/ConfigurationSchemaIdentifiers.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Writers/CalculationConfigurationWriter.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Writers/SchemaCalculationConfigurationWriter.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Writers/StructureCalculationConfigurationWriter.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag fe7c27dc926b4087fd6ed9551655d0571c8018c9 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Writers/XmlWriterExtensions.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/CalculationGroupConfigurationTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/CalculationGroupConfigurationTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/CalculationGroupConfigurationTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,62 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Ringtoets.Common.IO.Configurations;
+
+namespace Ringtoets.Common.IO.Test.Configurations
+{
+ [TestFixture]
+ public class CalculationGroupConfigurationTest
+ {
+ [Test]
+ public void Constructor_ExpectedValues()
+ {
+ // Setup
+ var nestedItems = new List
+ {
+ new TestReadConfigurationItem(),
+ new CalculationGroupConfiguration("Nested calculation group", Enumerable.Empty())
+ };
+
+ // Call
+ var readCalculationGroup = new CalculationGroupConfiguration("Calculation group", nestedItems);
+
+ // Assert
+ Assert.IsInstanceOf(readCalculationGroup);
+ Assert.AreEqual("Calculation group", readCalculationGroup.Name);
+ Assert.AreSame(nestedItems, readCalculationGroup.Items);
+ }
+
+ private class TestReadConfigurationItem : IConfigurationItem
+ {
+ public string Name
+ {
+ get
+ {
+ return "Fixed name";
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/ConfigurationSchemaIdentifiersTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/ConfigurationSchemaIdentifiersTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/ConfigurationSchemaIdentifiersTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,44 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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 NUnit.Framework;
+using Ringtoets.Common.IO.Configurations;
+
+namespace Ringtoets.Common.IO.Test.Configurations
+{
+ [TestFixture]
+ public class ConfigurationSchemaIdentifiersTest
+ {
+ [Test]
+ public void ConfigurationSchemaIdentifiers_ExpectedValues()
+ {
+ Assert.AreEqual("configuratie", ConfigurationSchemaIdentifiers.ConfigurationElement);
+ Assert.AreEqual("berekening", ConfigurationSchemaIdentifiers.CalculationElement);
+ Assert.AreEqual("map", ConfigurationSchemaIdentifiers.FolderElement);
+ Assert.AreEqual("naam", ConfigurationSchemaIdentifiers.NameAttribute);
+ Assert.AreEqual("hrlocatie", ConfigurationSchemaIdentifiers.HydraulicBoundaryLocationElement);
+ Assert.AreEqual("stochasten", ConfigurationSchemaIdentifiers.StochastsElement);
+ Assert.AreEqual("stochast", ConfigurationSchemaIdentifiers.StochastElement);
+ Assert.AreEqual("verwachtingswaarde", ConfigurationSchemaIdentifiers.MeanElement);
+ Assert.AreEqual("standaardafwijking", ConfigurationSchemaIdentifiers.StandardDeviationElement);
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/CalculationConfigurationExporterTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/CalculationConfigurationExporterTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/CalculationConfigurationExporterTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,97 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Xml;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.Data.TestUtil;
+using Ringtoets.Common.IO.Configurations.Export;
+using Ringtoets.Common.IO.TestUtil;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Export
+{
+ [TestFixture]
+ public class CalculationConfigurationExporterTest
+ : CustomCalculationConfigurationExporterDesignGuidelinesTestFixture<
+ SimpleCalculationConfigurationExporter,
+ SimpleCalculationConfigurationWriter,
+ TestCalculation>
+ {
+ [Test]
+ public void Export_ValidData_ReturnTrueAndWritesFile()
+ {
+ // Setup
+ var calculation = new TestCalculation("Calculation A");
+ var calculation2 = new TestCalculation("Calculation B");
+
+ var calculationGroup2 = new CalculationGroup("Group B", false)
+ {
+ Children =
+ {
+ calculation2
+ }
+ };
+
+ var calculationGroup = new CalculationGroup("Group A", false)
+ {
+ Children =
+ {
+ calculation,
+ calculationGroup2
+ }
+ };
+
+ string testFileSubPath = Path.Combine(
+ nameof(CalculationConfigurationExporter),
+ "folderWithSubfolderAndCalculation.xml");
+ string expectedXmlFilePath = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ testFileSubPath);
+
+ // Call and Assert
+ WriteAndValidate(new[]
+ {
+ calculationGroup
+ }, expectedXmlFilePath);
+ }
+
+ protected override TestCalculation CreateCalculation()
+ {
+ return new TestCalculation("TestCalculation A");
+ }
+ }
+
+ public class SimpleCalculationConfigurationExporter : CalculationConfigurationExporter
+ {
+ public SimpleCalculationConfigurationExporter(IEnumerable configuration, string targetFilePath) : base(configuration, targetFilePath) { }
+ }
+
+ public class SimpleCalculationConfigurationWriter : CalculationConfigurationWriter
+ {
+ protected override void WriteCalculation(TestCalculation calculation, XmlWriter writer)
+ {
+ writer.WriteElementString("calculation", calculation.Name);
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/CalculationConfigurationWriterTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/CalculationConfigurationWriterTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/CalculationConfigurationWriterTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,467 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Xml;
+using Core.Common.Base.Data;
+using Core.Common.IO.Exceptions;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Rhino.Mocks;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.Data.DikeProfiles;
+using Ringtoets.Common.Data.Probabilistics;
+using Ringtoets.Common.Data.TestUtil;
+using Ringtoets.Common.IO.Configurations.Export;
+using Ringtoets.Common.IO.TestUtil;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Export
+{
+ [TestFixture]
+ public class CalculationConfigurationWriterTest
+ : CustomCalculationConfigurationWriterDesignGuidelinesTestFixture<
+ TestCalculationConfigurationWriter,
+ TestCalculation>
+ {
+ [Test]
+ public void WriteDistribution_WithoutDistributions_ArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithoutDistributions_ArgumentNullException));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ Assert.Throws(() => writer.PublicWriteDistributions(null, xmlWriter));
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+
+ Assert.IsEmpty(actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistribution_EmptyDistributions_NothingWrittenToFile()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_EmptyDistributions_NothingWrittenToFile));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ writer.PublicWriteDistributions(new Dictionary(), xmlWriter);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+
+ Assert.IsEmpty(actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistribution_WithDistributions_WritesEachDistributionAsElement()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDistributions_WritesEachDistributionAsElement));
+ string expectedXmlFilePath = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ Path.Combine(nameof(CalculationConfigurationWriter), "distributions.xml"));
+
+ var distributions = new Dictionary
+ {
+ {
+ "normal", new NormalDistribution
+ {
+ Mean = (RoundedDouble) 0.2,
+ StandardDeviation = (RoundedDouble) 0.1
+ }
+ },
+ {
+ "lognormal", new LogNormalDistribution
+ {
+ Mean = (RoundedDouble) 0.4,
+ StandardDeviation = (RoundedDouble) 0.3
+ }
+ }
+ };
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ writer.PublicWriteDistributions(distributions, xmlWriter);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = File.ReadAllText(expectedXmlFilePath);
+
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteVariationCoefficientDistribution_WithoutVariationCoefficientDistributions_ArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(
+ nameof(WriteVariationCoefficientDistribution_WithoutVariationCoefficientDistributions_ArgumentNullException));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ Assert.Throws(() => writer.PublicWriteDistributions(null, xmlWriter));
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+
+ Assert.IsEmpty(actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteVariationCoefficientDistribution_EmptyVariationCoefficientDistributions_NothingWrittenToFile()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(
+ nameof(WriteVariationCoefficientDistribution_EmptyVariationCoefficientDistributions_NothingWrittenToFile));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ writer.PublicWriteDistributions(new Dictionary(), xmlWriter);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+
+ Assert.IsEmpty(actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteVariationCoefficientDistribution_WithVariationCoefficientDistributions_WritesEachDistributionAsElement()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(
+ nameof(WriteVariationCoefficientDistribution_WithVariationCoefficientDistributions_WritesEachDistributionAsElement));
+ string expectedXmlFilePath = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ Path.Combine(nameof(CalculationConfigurationWriter), "variationCoefficientDistributions.xml"));
+
+ var distributions = new Dictionary
+ {
+ {
+ "normal", new VariationCoefficientNormalDistribution
+ {
+ Mean = (RoundedDouble) 0.2,
+ CoefficientOfVariation = (RoundedDouble) 0.1
+ }
+ },
+ {
+ "lognormal", new VariationCoefficientLogNormalDistribution
+ {
+ Mean = (RoundedDouble) 0.4,
+ CoefficientOfVariation = (RoundedDouble) 0.3
+ }
+ }
+ };
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ writer.PublicWriteVariationCoefficientDistributions(distributions, xmlWriter);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = File.ReadAllText(expectedXmlFilePath);
+
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteBreakWaterProperties_BreakWaterNull_NothingWrittenToFile()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(
+ $"{nameof(WriteBreakWaterProperties_WithBreakWater_WritesPropertiesToFile)}.xml");
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ writer.PublicWriteBreakWaterProperties(null, xmlWriter);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+
+ Assert.IsEmpty(actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ [TestCase(BreakWaterType.Wall, 26.3, "breakWaterWall.xml")]
+ [TestCase(BreakWaterType.Caisson, 1.5, "breakWaterCaisson.xml")]
+ [TestCase(BreakWaterType.Dam, -55.1, "breakWaterDam.xml")]
+ public void WriteBreakWaterProperties_WithBreakWater_WritesPropertiesToFile(
+ BreakWaterType type,
+ double height,
+ string expectedContentFilePath)
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(
+ $"{nameof(WriteBreakWaterProperties_WithBreakWater_WritesPropertiesToFile)} {type}");
+
+ string expectedXmlFilePath = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ Path.Combine(nameof(CalculationConfigurationWriter), expectedContentFilePath));
+
+ var breakWater = new BreakWater(type, (RoundedDouble) height);
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ var writer = new TestCalculationConfigurationWriter();
+
+ // Call
+ writer.PublicWriteBreakWaterProperties(breakWater, xmlWriter);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = File.ReadAllText(expectedXmlFilePath);
+
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void Write_CalculationOfTypeOtherThanGiven_ThrowsCriticalFileWriteExceptionWithInnerArgumentException()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var calculation = mocks.Stub();
+ mocks.ReplayAll();
+
+ string filePath = TestHelper.GetScratchPadPath("test.xml");
+
+ try
+ {
+ // Call
+ TestDelegate test = () => new TestCalculationConfigurationWriter().Write(new[]
+ {
+ calculation
+ }, filePath);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Exception innerException = exception.InnerException;
+ Assert.IsNotNull(innerException);
+ Assert.AreEqual($"Cannot write calculation of type '{calculation.GetType()}' using this writer.", innerException.Message);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ [TestCaseSource(nameof(GetCalculationConfigurations))]
+ public void Write_DifferentCalculationAndCalculationGroupConfigurations_ValidFile(IEnumerable configuration, string expectedFileContentsFileName)
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath("test.xml");
+ string expectedXmlFilePath = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ Path.Combine(nameof(CalculationConfigurationWriter), expectedFileContentsFileName));
+
+ try
+ {
+ // Call
+ new TestCalculationConfigurationWriter().Write(configuration, filePath);
+
+ // Assert
+ Assert.IsTrue(File.Exists(filePath));
+
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = File.ReadAllText(expectedXmlFilePath);
+
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ private static XmlWriter CreateXmlWriter(string filePath)
+ {
+ return XmlWriter.Create(filePath, new XmlWriterSettings
+ {
+ Indent = true,
+ ConformanceLevel = ConformanceLevel.Fragment
+ });
+ }
+
+ private static IEnumerable GetCalculationConfigurations()
+ {
+ var calculation1 = new TestCalculation("calculation1");
+ var calculation2 = new TestCalculation("calculation2");
+
+ var calculationGroup1 = new CalculationGroup("group1", false);
+ var calculationGroup2 = new CalculationGroup("group2", false)
+ {
+ Children =
+ {
+ calculation2,
+ calculationGroup1
+ }
+ };
+
+ yield return new TestCaseData(
+ new[]
+ {
+ calculationGroup1
+ },
+ "singleGroup.xml")
+ .SetName("Single group");
+ yield return new TestCaseData(
+ new[]
+ {
+ calculation1
+ },
+ "singleCalculation.xml")
+ .SetName("Single calculation");
+ yield return new TestCaseData(
+ new ICalculationBase[]
+ {
+ calculationGroup1,
+ calculation1
+ },
+ "calculationGroupAndCalculation.xml")
+ .SetName("Calculation group and calculation");
+ yield return new TestCaseData(
+ new ICalculationBase[]
+ {
+ calculation1,
+ calculationGroup2
+ },
+ "calculationAndGroupWithNesting.xml")
+ .SetName("Calculation and group with nesting");
+ }
+ }
+
+ public class TestCalculationConfigurationWriter : CalculationConfigurationWriter
+ {
+ public const string CalculationElementTag = "calculation";
+
+ public void PublicWriteDistributions(IDictionary distributions, XmlWriter writer)
+ {
+ WriteDistributions(distributions, writer);
+ }
+
+ public void PublicWriteVariationCoefficientDistributions(
+ IDictionary distributions,
+ XmlWriter writer)
+ {
+ WriteVariationCoefficientDistributions(distributions, writer);
+ }
+
+ public void PublicWriteBreakWaterProperties(BreakWater breakWater, XmlWriter writer)
+ {
+ WriteBreakWaterProperties(breakWater, writer);
+ }
+
+ protected override void WriteCalculation(TestCalculation calculation, XmlWriter writer)
+ {
+ writer.WriteElementString(CalculationElementTag, calculation.Name);
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/SchemaCalculationConfigurationExporterTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/SchemaCalculationConfigurationExporterTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/SchemaCalculationConfigurationExporterTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,65 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using NUnit.Framework;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.Data.TestUtil;
+using Ringtoets.Common.IO.Configurations.Export;
+using Ringtoets.Common.IO.TestUtil;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Export
+{
+ [TestFixture]
+ public class SchemaCalculationConfigurationExporterTest
+ : CustomSchemaCalculationConfigurationExporterDesignGuidelinesTestFixture<
+ SimpleSchemaCalculationConfigurationExporter,
+ TestSchemaCalculationConfigurationWriter,
+ TestCalculation,
+ TestConfigurationItem>
+ {
+ protected override TestCalculation CreateCalculation()
+ {
+ return new TestCalculation("some name");
+ }
+
+ protected override SimpleSchemaCalculationConfigurationExporter CallConfigurationFilePathConstructor(IEnumerable calculations, string filePath)
+ {
+ return new SimpleSchemaCalculationConfigurationExporter(calculations, filePath);
+ }
+ }
+
+ public class SimpleSchemaCalculationConfigurationExporter
+ : SchemaCalculationConfigurationExporter
+ {
+ public SimpleSchemaCalculationConfigurationExporter(IEnumerable calculations, string filePath) : base(calculations, filePath) { }
+
+ protected override TestSchemaCalculationConfigurationWriter CreateWriter(string filePath)
+ {
+ return new TestSchemaCalculationConfigurationWriter(filePath);
+ }
+
+ protected override TestConfigurationItem ToConfiguration(TestCalculation calculation)
+ {
+ return null;
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/SchemaCalculationConfigurationWriterTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/SchemaCalculationConfigurationWriterTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/SchemaCalculationConfigurationWriterTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,500 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Rhino.Mocks;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Export;
+using Ringtoets.Common.IO.Configurations.Helpers;
+using Ringtoets.Common.IO.TestUtil;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Export
+{
+ [TestFixture]
+ public class SchemaCalculationConfigurationWriterTest
+ : CustomSchemaCalculationConfigurationWriterDesignGuidelinesTestFixture<
+ TestSchemaCalculationConfigurationWriter,
+ TestConfigurationItem>
+ {
+ [Test]
+ [TestCaseSource(nameof(GetCalculationConfigurations))]
+ public void Write_DifferentCalculationAndCalculationGroupConfigurations_ValidFile(IEnumerable configuration, string expectedFileContentsFileName)
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath("test.xml");
+ string expectedXmlFilePath = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ Path.Combine(nameof(CalculationConfigurationWriter), expectedFileContentsFileName));
+
+ try
+ {
+ // Call
+ new TestSchemaCalculationConfigurationWriter(filePath).Write(configuration);
+
+ // Assert
+ Assert.IsTrue(File.Exists(filePath));
+
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = File.ReadAllText(expectedXmlFilePath);
+
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_MeanStandardDeviationStochastConfigurationWriterNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ null,
+ "some name",
+ (StochastConfiguration) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_MeanStandardDeviationStochastConfigurationDistributionNameNull_ThrowsArgumentNullException()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ xmlWriter,
+ null,
+ (StochastConfiguration) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("distributionName", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_MeanStandardDeviationStochastConfigurationNull_WriterNotCalled()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ xmlWriter,
+ "some name",
+ (StochastConfiguration) null);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_MeanStandardDeviationStochastConfigurationSet_WriterCalledWithExpectedParameters()
+ {
+ // Setup
+ const string name = "some name";
+ var configuration = new StochastConfiguration();
+
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ xmlWriter.Expect(w => w.WriteDistribution(name, configuration));
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ xmlWriter,
+ name,
+ configuration);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_StochastConfigurationWriterNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ null,
+ "some name",
+ (StochastConfiguration) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_StochastConfigurationDistributionNameNull_ThrowsArgumentNullException()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ xmlWriter,
+ null,
+ (StochastConfiguration) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("distributionName", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_StochastConfigurationNull_WriterNotCalled()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ xmlWriter,
+ "some name",
+ (StochastConfiguration) null);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteDistributionWhenAvailable_StochastConfigurationSet_WriterCalledWithExpectedParameters()
+ {
+ // Setup
+ const string name = "some name";
+ var configuration = new StochastConfiguration();
+
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ xmlWriter.Expect(w => w.WriteDistribution(name, configuration));
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteDistributionWhenAvailable(
+ xmlWriter,
+ name,
+ configuration);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_StringWriterNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ null,
+ "some name",
+ (string) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_StringElementNameNull_ThrowsArgumentNullException()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ xmlWriter,
+ null,
+ (string) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("elementName", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_StringNull_WriterNotCalled()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ xmlWriter,
+ "some name",
+ (string) null);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_StringSet_WriterCalledWithExpectedParameters()
+ {
+ // Setup
+ const string name = "some name";
+ const string value = "some value";
+
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ xmlWriter.Expect(w => w.WriteElementString(name, value));
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ xmlWriter,
+ name,
+ value);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_DoubleWriterNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ null,
+ "some name",
+ (double?) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_DoubleElementNameNull_ThrowsArgumentNullException()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ xmlWriter,
+ null,
+ (double?) null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("elementName", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_DoubleNull_WriterNotCalled()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ xmlWriter,
+ "some name",
+ (double?) null);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteElementWhenContentAvailable_DoubleSet_WriterCalledWithExpectedParameters()
+ {
+ // Setup
+ const string name = "some name";
+ const double value = 3.2;
+
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ xmlWriter.Expect(w => w.WriteElementString(name, XmlConvert.ToString(value)));
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteElementWhenContentAvailable(
+ xmlWriter,
+ name,
+ value);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteWaveReductionWhenAvailable_WriterNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ExposedSchemaCalculationConfigurationWriter.PublicWriteWaveReductionWhenAvailable(
+ null,
+ null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteWaveReductionWhenAvailable_WaveReductionConfigurationNull_WriterNotCalled()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteWaveReductionWhenAvailable(
+ xmlWriter,
+ null);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void WriteWaveReductionWhenAvailable_WaveReductionConfigurationSet_WriterCalledWithExpectedParameters()
+ {
+ // Setup
+ var configuration = new WaveReductionConfiguration();
+
+ var mocks = new MockRepository();
+ var xmlWriter = mocks.StrictMock();
+ xmlWriter.Expect(w => w.WriteWaveReduction(configuration));
+ mocks.ReplayAll();
+
+ // Call
+ ExposedSchemaCalculationConfigurationWriter.PublicWriteWaveReductionWhenAvailable(
+ xmlWriter,
+ configuration);
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ private static IEnumerable GetCalculationConfigurations()
+ {
+ var calculation1 = new TestConfigurationItem
+ {
+ Name = "calculation1"
+ };
+ var calculation2 = new TestConfigurationItem
+ {
+ Name = "calculation2"
+ };
+
+ var calculationGroup1 = new CalculationGroupConfiguration("group1", Enumerable.Empty());
+ var calculationGroup2 = new CalculationGroupConfiguration("group2", new IConfigurationItem[]
+ {
+ calculation2,
+ calculationGroup1
+ });
+
+ yield return new TestCaseData(
+ new[]
+ {
+ calculationGroup1
+ },
+ "singleGroup.xml")
+ .SetName("Single group");
+ yield return new TestCaseData(
+ new[]
+ {
+ calculation1
+ },
+ "singleCalculation.xml")
+ .SetName("Single calculation");
+ yield return new TestCaseData(
+ new IConfigurationItem[]
+ {
+ calculationGroup1,
+ calculation1
+ },
+ "calculationGroupAndCalculation.xml")
+ .SetName("Calculation group and calculation");
+ yield return new TestCaseData(
+ new IConfigurationItem[]
+ {
+ calculation1,
+ calculationGroup2
+ },
+ "calculationAndGroupWithNesting.xml")
+ .SetName("Calculation and group with nesting");
+ }
+
+ protected override TestSchemaCalculationConfigurationWriter CreateWriterInstance(string filePath)
+ {
+ return new TestSchemaCalculationConfigurationWriter(filePath);
+ }
+ }
+
+ public class ExposedSchemaCalculationConfigurationWriter : SchemaCalculationConfigurationWriter
+ {
+ public ExposedSchemaCalculationConfigurationWriter(string filePath) : base(filePath) { }
+
+ public static void PublicWriteDistributionWhenAvailable(XmlWriter writer, string distributionName, StochastConfiguration configuration)
+ {
+ WriteDistributionWhenAvailable(writer, distributionName, configuration);
+ }
+
+ public static void PublicWriteElementWhenContentAvailable(XmlWriter writer, string elementName, string elementContent)
+ {
+ WriteElementWhenContentAvailable(writer, elementName, elementContent);
+ }
+
+ public static void PublicWriteElementWhenContentAvailable(XmlWriter writer, string elementName, double? elementContent)
+ {
+ WriteElementWhenContentAvailable(writer, elementName, elementContent);
+ }
+
+ public static void PublicWriteWaveReductionWhenAvailable(XmlWriter writer, WaveReductionConfiguration configuration)
+ {
+ WriteWaveReductionWhenAvailable(writer, configuration);
+ }
+
+ protected override void WriteCalculation(TestConfigurationItem calculation, XmlWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/StructureCalculationConfigurationWriterTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/StructureCalculationConfigurationWriterTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Export/StructureCalculationConfigurationWriterTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,199 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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 System.Xml;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Export;
+using Ringtoets.Common.IO.Configurations.Helpers;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Export
+{
+ [TestFixture]
+ public class StructureCalculationConfigurationWriterTest
+ {
+ private static readonly string testDirectory = TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ nameof(StructureCalculationConfigurationWriter));
+
+ [Test]
+ public void Write_WithoutConfiguration_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath("test.xml");
+
+ var writer = new SimpleStructureCalculationConfigurationWriter(filePath, false);
+ {
+ // Call
+ TestDelegate test = () => writer.Write(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("configuration", exception.ParamName);
+ }
+ }
+
+ [Test]
+ public void Write_WithAllParametersSet_WritesCalculationWithAllParametersAndStochasts()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(Write_WithAllParametersSet_WritesCalculationWithAllParametersAndStochasts));
+ try
+ {
+ var writer = new SimpleStructureCalculationConfigurationWriter(filePath, true);
+
+ // Call
+ writer.Write(new[]
+ {
+ CreateStructureWithAllParametersSet("some other name")
+ });
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = GetTestFileContent("structureCalculationWithAllParametersSet.xml");
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void Write_WithoutParametersSet_WritesCalculationWithOnlyEmptyStochasts()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(Write_WithoutParametersSet_WritesCalculationWithOnlyEmptyStochasts));
+ try
+ {
+ var writer = new SimpleStructureCalculationConfigurationWriter(filePath, false);
+
+ // Call
+ writer.Write(new[]
+ {
+ new SimpleStructuresCalculationConfiguration("some name")
+ });
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = GetTestFileContent("structureCalculationWithoutParametersSet.xml");
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ private static SimpleStructuresCalculationConfiguration CreateStructureWithAllParametersSet(string name)
+ {
+ return new SimpleStructuresCalculationConfiguration(name)
+ {
+ AllowedLevelIncreaseStorage = new StochastConfiguration
+ {
+ Mean = 1.2,
+ StandardDeviation = 3.4
+ },
+ CriticalOvertoppingDischarge = new StochastConfiguration
+ {
+ Mean = 22.2,
+ VariationCoefficient = 2.1
+ },
+ FailureProbabilityStructureWithErosion = 2.1,
+ FlowWidthAtBottomProtection = new StochastConfiguration
+ {
+ Mean = 5.4,
+ StandardDeviation = 1.1
+ },
+ ForeshoreProfileName = "Voorland",
+ HydraulicBoundaryLocationName = "Randvoorwaardelocatie",
+ ModelFactorSuperCriticalFlow = new StochastConfiguration
+ {
+ Mean = 322.2,
+ StandardDeviation = 91.2
+ },
+ StorageStructureArea = new StochastConfiguration
+ {
+ Mean = 11.122,
+ VariationCoefficient = 32.111
+ },
+ StormDuration = new StochastConfiguration
+ {
+ Mean = 21.22,
+ VariationCoefficient = 1.2
+ },
+ StructureNormalOrientation = 5.6,
+ StructureName = "Kunstwerk",
+ WaveReduction = new WaveReductionConfiguration
+ {
+ BreakWaterType = ConfigurationBreakWaterType.Caisson,
+ UseBreakWater = false,
+ BreakWaterHeight = 111111.2,
+ UseForeshoreProfile = true
+ },
+ WidthFlowApertures = new StochastConfiguration
+ {
+ Mean = 121.3,
+ StandardDeviation = 222.1
+ }
+ };
+ }
+
+ private string GetTestFileContent(string testFile)
+ {
+ return File.ReadAllText(Path.Combine(testDirectory, testFile));
+ }
+
+ private class SimpleStructuresCalculationConfiguration : StructuresCalculationConfiguration
+ {
+ public SimpleStructuresCalculationConfiguration(string name) : base(name) { }
+ }
+
+ private class SimpleStructureCalculationConfigurationWriter : StructureCalculationConfigurationWriter
+ {
+ private readonly bool writeExtraParameterAndStochast;
+
+ public SimpleStructureCalculationConfigurationWriter(string filePath, bool writeExtraParameterAndStochast) : base(filePath)
+ {
+ this.writeExtraParameterAndStochast = writeExtraParameterAndStochast;
+ }
+
+ protected override void WriteSpecificStructureParameters(SimpleStructuresCalculationConfiguration configuration, XmlWriter writer)
+ {
+ if (writeExtraParameterAndStochast)
+ {
+ writer.WriteElementString("testName", "testValue");
+ }
+ }
+
+ protected override void WriteSpecificStochasts(SimpleStructuresCalculationConfiguration configuration, XmlWriter writer)
+ {
+ if (writeExtraParameterAndStochast)
+ {
+ writer.WriteDistribution("testStochastName", new StochastConfiguration());
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/ConfigurationBreakWaterTypeConverterTest.cs
===================================================================
diff -u -r335523a40d190e19b1061804de21c28f74140f52 -rfe7c27dc926b4087fd6ed9551655d0571c8018c9
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/ConfigurationBreakWaterTypeConverterTest.cs (.../ConfigurationBreakWaterTypeConverterTest.cs) (revision 335523a40d190e19b1061804de21c28f74140f52)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/ConfigurationBreakWaterTypeConverterTest.cs (.../ConfigurationBreakWaterTypeConverterTest.cs) (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -25,7 +25,6 @@
using Ringtoets.Common.Data.DikeProfiles;
using Ringtoets.Common.IO.Configurations;
using Ringtoets.Common.IO.Configurations.Helpers;
-using Ringtoets.Common.IO.Schema;
namespace Ringtoets.Common.IO.Test.Configurations.Helpers
{
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/XElementExtensionsTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/XElementExtensionsTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/XElementExtensionsTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,866 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Xml;
+using System.Xml.Linq;
+using Core.Common.Base.IO;
+using NUnit.Framework;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Helpers;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Helpers
+{
+ [TestFixture]
+ public class XElementExtensionsTest
+ {
+ private static IEnumerable XElements
+ {
+ get
+ {
+ yield return new TestCaseData(new XElement("Root", new XElement("descendant")));
+ yield return new TestCaseData(new XElement("Root", new XElement("Child", new XElement("descendant"))));
+ }
+ }
+
+ [Test]
+ public void GetDoubleValueFromDescendantElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement rootElement = null;
+
+ // Call
+ TestDelegate test = () => rootElement.GetDoubleValueFromDescendantElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetDoubleValueFromDescendantElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var rootElement = new XElement("Root");
+
+ // Call
+ TestDelegate test = () => rootElement.GetDoubleValueFromDescendantElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetDoubleValueFromDescendantElement_DescendantElementInvalidFormat_ThrowFormatException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ const string descendantElementValue = "drie";
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetDoubleValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void GetDoubleValueFromDescendantElement_DescendantElementOverflows_ThrowOverflowException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ string descendantElementValue = string.Format(CultureInfo.InvariantCulture, "1{0}", double.MaxValue);
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetDoubleValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ [TestCase(3)]
+ [TestCase(double.NaN)]
+ [TestCase(double.PositiveInfinity)]
+ [TestCase(double.NegativeInfinity)]
+ public void GetDoubleValueFromDescendantElement_ValidDescendantElement_ReturnValue(double descendantElementValue)
+ {
+ // Setup
+ const string descendantElementName = "number";
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ double? readValue = element.GetDoubleValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.AreEqual(descendantElementValue, readValue.Value);
+ }
+
+ [Test]
+ public void GetDoubleValueFromDescendantElement_InvalidDescendantElement_ReturnNull()
+ {
+ // Setup
+ var element = new XElement("Root", new XElement("number", (double) 3));
+
+ // Call
+ double? readValue = element.GetDoubleValueFromDescendantElement("invalidName");
+
+ // Assert
+ Assert.IsNull(readValue);
+ }
+
+ [Test]
+ public void GetIntegerValueFromDescendantElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement rootElement = null;
+
+ // Call
+ TestDelegate test = () => rootElement.GetIntegerValueFromDescendantElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetIntegerValueFromDescendantElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var rootElement = new XElement("Root");
+
+ // Call
+ TestDelegate test = () => rootElement.GetIntegerValueFromDescendantElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetIntegerValueFromDescendantElement_DescendantElementInvalidFormat_ThrowFormatException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ const string descendantElementValue = "drie";
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetIntegerValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void GetIntegerValueFromDescendantElement_DescendantElementOverflows_ThrowOverflowException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ string descendantElementValue = string.Format(CultureInfo.InvariantCulture, "1{0}", int.MaxValue);
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetIntegerValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void GetIntegerValueFromDescendantElement_ValidDescendantElement_ReturnValue()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ const int descendantElementValue = 3;
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ double? readValue = element.GetIntegerValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.AreEqual(descendantElementValue, readValue.Value);
+ }
+
+ [Test]
+ public void GetIntegerValueFromDescendantElement_InvalidDescendantElement_ReturnNull()
+ {
+ // Setup
+ var element = new XElement("Root", new XElement("number", (double) 3));
+
+ // Call
+ double? readValue = element.GetIntegerValueFromDescendantElement("invalidName");
+
+ // Assert
+ Assert.IsNull(readValue);
+ }
+
+ [Test]
+ public void GetStringValueFromDescendantElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement element = null;
+
+ // Call
+ TestDelegate test = () => element.GetStringValueFromDescendantElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetStringValueFromDescendantElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => new XElement("Test").GetStringValueFromDescendantElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetStringValueFromDescendantElement_ValidDescendantElement_ReturnValue()
+ {
+ // Setup
+ const string descendantElementName = "text";
+ const string descendantElementValue = "valueText";
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ string readValue = element.GetStringValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.AreEqual(descendantElementValue, readValue);
+ }
+
+ [Test]
+ public void GetStringValueFromDescendantElement_InvalidDescendantElement_ReturnNull()
+ {
+ // Setup
+ var element = new XElement("Root", new XElement("number", "valueText"));
+
+ // Call
+ string readValue = element.GetStringValueFromDescendantElement("invalidName");
+
+ // Assert
+ Assert.IsNull(readValue);
+ }
+
+ [Test]
+ public void GetBoolValueFromDescendantElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement element = null;
+
+ // Call
+ TestDelegate test = () => element.GetBoolValueFromDescendantElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetBoolValueFromDescendantElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var element = new XElement("Root");
+
+ // Call
+ TestDelegate test = () => element.GetBoolValueFromDescendantElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetBoolValueFromDescendantElement_DescendantElementIncorrectFormat_ThrowFormatException()
+ {
+ // Setup
+ const string descendantElementName = "booleanValue";
+ const string elementValue = "nope";
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ TestDelegate test = () => element.GetBoolValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ [TestCase(true)]
+ [TestCase(false)]
+ public void GetBoolValueFromDescendantElement_ValidDescendantElement_ReturnValue(bool booleanValue)
+ {
+ // Setup
+ const string descendantElementName = "booleanValue";
+ string elementValue = XmlConvert.ToString(booleanValue);
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ bool? readValue = element.GetBoolValueFromDescendantElement(descendantElementName);
+
+ // Assert
+ Assert.AreEqual(booleanValue, readValue);
+ }
+
+ [Test]
+ public void GetBoolValueFromDescendantElement_UnmatchedDescendantElement_ReturnNull()
+ {
+ // Setup
+ string elementValue = XmlConvert.ToString(true);
+
+ var element = new XElement("Root", new XElement("booleanValue", elementValue));
+
+ // Call
+ bool? readValue = element.GetBoolValueFromDescendantElement("unmatchingChildElementName");
+
+ // Assert
+ Assert.IsNull(readValue);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantStringElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement element = null;
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantStringElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantStringElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var element = new XElement("Root");
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantStringElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantStringElement_DescendantElementInvalidToConvert_ThrowException()
+ {
+ // Setup
+ const string descendantElementName = "value";
+ const string elementValue = "three";
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ TestDelegate call = () => element.GetConvertedValueFromDescendantStringElement(descendantElementName);
+
+ // Assert
+ Exception exception = Assert.Throws(call);
+ Assert.AreEqual($"{elementValue} is not a valid value for Double.", exception.Message);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantStringElement_DescendantElementNotSupported_ThrowNotSupportedException()
+ {
+ // Setup
+ const string descendantElementName = "value";
+ const string elementValue = "3";
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ TestDelegate call = () => element.GetConvertedValueFromDescendantStringElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(call);
+ }
+
+ [Test]
+ [TestCase(true)]
+ [TestCase(false)]
+ public void GetConvertedValueFromDescendantStringElement_ValidDescendantElement_ReturnValue(bool value)
+ {
+ // Setup
+ const string descendantElementName = "value";
+ string elementValue = XmlConvert.ToString(value);
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ object readValue = element.GetConvertedValueFromDescendantStringElement(descendantElementName);
+
+ // Assert
+ Assert.AreEqual(value, readValue);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantStringElement_UnmatchedDescendantElement_ReturnNull()
+ {
+ // Setup
+ string elementValue = XmlConvert.ToString(true);
+
+ var element = new XElement("Root", new XElement("value", elementValue));
+
+ // Call
+ object readValue = element.GetConvertedValueFromDescendantStringElement("unmatchingChildElementName");
+
+ // Assert
+ Assert.IsNull(readValue);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement element = null;
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantDoubleElement("0");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var element = new XElement("Root");
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantDoubleElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_ConvertFromThrowsException_ThrowException()
+ {
+ // Setup
+ const string descendantElementName = "value";
+ const double elementValue = 1;
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ TestDelegate call = () => element.GetConvertedValueFromDescendantDoubleElement(
+ descendantElementName);
+
+ // Assert
+ Exception exception = Assert.Throws(call);
+ Assert.AreEqual($"{elementValue} is not a valid value for the target type.", exception.Message);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_DescendantElementInvalidFormat_ThrowFormatException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ const string descendantElementValue = "drie";
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantDoubleElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_DescendantElementOverflows_ThrowOverflowException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ string descendantElementValue = string.Format(CultureInfo.InvariantCulture, "1{0}", double.MaxValue);
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantDoubleElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_DescendantElementNotSupportedByConverter_ThrowNotSupportedException()
+ {
+ // Setup
+ const string descendantElementName = "number";
+ const string descendantElementValue = "4";
+
+ var element = new XElement("Root", new XElement(descendantElementName, descendantElementValue));
+
+ // Call
+ TestDelegate test = () => element.GetConvertedValueFromDescendantDoubleElement(descendantElementName);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ [TestCase(0, false)]
+ [TestCase(-1, true)]
+ [TestCase(1, true)]
+ public void GetConvertedValueFromDescendantDoubleElement_ValidDescendantElement_ReturnValue(double value, bool expectedConvertedValue)
+ {
+ // Setup
+ const string descendantElementName = "value";
+ string elementValue = XmlConvert.ToString(value);
+
+ var element = new XElement("Root", new XElement(descendantElementName, elementValue));
+
+ // Call
+ object readValue = element.GetConvertedValueFromDescendantDoubleElement(descendantElementName);
+
+ // Assert
+ Assert.AreEqual(expectedConvertedValue, readValue);
+ }
+
+ [Test]
+ public void GetConvertedValueFromDescendantDoubleElement_UnmatchedDescendantElement_ReturnNull()
+ {
+ // Setup
+ string elementValue = XmlConvert.ToString(true);
+
+ var element = new XElement("Root", new XElement("value", elementValue));
+
+ // Call
+ object readValue = element.GetConvertedValueFromDescendantDoubleElement("unmatchingChildElementName");
+
+ // Assert
+ Assert.IsNull(readValue);
+ }
+
+ [Test]
+ public void GetStochastElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement element = null;
+
+ // Call
+ TestDelegate test = () => element.GetStochastElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetStochastElement_StochastNameNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var element = new XElement("Root");
+
+ // Call
+ TestDelegate test = () => element.GetStochastElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("stochastName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetStochastElement_RootElementWithoutStochastsElement_ReturnNull()
+ {
+ // Setup
+ var element = new XElement("Root");
+
+ // Call
+ XElement stochastElement = element.GetStochastElement("stochast_name");
+
+ // Assert
+ Assert.IsNull(stochastElement);
+ }
+
+ [Test]
+ public void GetStochastElement_RootElementWithEmptyStochastsElement_ReturnNull()
+ {
+ // Setup
+ var stochastsElements = new XElement(ConfigurationSchemaIdentifiers.StochastsElement);
+ var element = new XElement("Root", stochastsElements);
+
+ // Call
+ XElement stochastElement = element.GetStochastElement("stochast_name");
+
+ // Assert
+ Assert.IsNull(stochastElement);
+ }
+
+ [Test]
+ public void GetStochastElement_RootElementWithStochastsAndUnmatchedStochastElement_ReturnNull()
+ {
+ // Setup
+ var stochastA = new XElement(ConfigurationSchemaIdentifiers.StochastElement);
+ stochastA.SetAttributeValue(ConfigurationSchemaIdentifiers.NameAttribute, "A");
+
+ var stochastB = new XElement(ConfigurationSchemaIdentifiers.StochastElement);
+ stochastB.SetAttributeValue(ConfigurationSchemaIdentifiers.NameAttribute, "B");
+
+ var stochastsElements = new XElement(ConfigurationSchemaIdentifiers.StochastsElement);
+ stochastsElements.Add(stochastA);
+ stochastsElements.Add(stochastB);
+
+ var element = new XElement("Root", stochastsElements);
+
+ // Call
+ XElement stochastElement = element.GetStochastElement("stochast_name");
+
+ // Assert
+ Assert.IsNull(stochastElement);
+ }
+
+ [Test]
+ public void GetStochastElement_RootElementWithStochastsAndMatchedStochastElement_ReturnMatchedElement()
+ {
+ // Setup
+ const string stochastName = "stochast_name";
+ var stochastA = new XElement(ConfigurationSchemaIdentifiers.StochastElement);
+ stochastA.SetAttributeValue(ConfigurationSchemaIdentifiers.NameAttribute, "A");
+
+ var stochastElementToMatch = new XElement(ConfigurationSchemaIdentifiers.StochastElement);
+ stochastElementToMatch.SetAttributeValue(ConfigurationSchemaIdentifiers.NameAttribute, stochastName);
+
+ var stochastB = new XElement(ConfigurationSchemaIdentifiers.StochastElement);
+ stochastB.SetAttributeValue(ConfigurationSchemaIdentifiers.NameAttribute, "B");
+
+ var stochastsElements = new XElement(ConfigurationSchemaIdentifiers.StochastsElement);
+ stochastsElements.Add(stochastA);
+ stochastsElements.Add(stochastElementToMatch);
+ stochastsElements.Add(stochastB);
+
+ var element = new XElement("Root", stochastsElements);
+
+ // Call
+ XElement stochastElement = element.GetStochastElement(stochastName);
+
+ // Assert
+ Assert.AreSame(stochastElementToMatch, stochastElement);
+ }
+
+ [Test]
+ public void GetDescendantElement_ParentElementNull_ThrowArgumentNullException()
+ {
+ // Setup
+ XElement element = null;
+
+ // Call
+ TestDelegate test = () => element.GetDescendantElement("");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("parentElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetDescendantElement_DescendantElementNameNull_ThrowArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => new XElement("Test").GetDescendantElement(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("descendantElementName", exception.ParamName);
+ }
+
+ [Test]
+ [TestCaseSource(nameof(XElements))]
+ public void GetDescendantElement_ValidDescendantName_ReturnElement(XElement parentElement)
+ {
+ // Call
+ XElement element = parentElement.GetDescendantElement("descendant");
+
+ // Assert
+ Assert.IsNotNull(element);
+ Assert.AreEqual("descendant", element.Name.LocalName);
+ }
+
+ [Test]
+ public void GetDescendantElement_InvalidDescendantName_ReturnNull()
+ {
+ // Setup
+ var parentElement = new XElement("Root", new XElement("Child", new XElement("descendant")));
+
+ // Call
+ XElement element = parentElement.GetDescendantElement("something_else");
+
+ // Assert
+ Assert.IsNull(element);
+ }
+
+ [Test]
+ public void GetStochastParameters_CalculationElementNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ((XElement) null).GetStochastParameters("name");
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("calculationElement", exception.ParamName);
+ }
+
+ [Test]
+ public void GetStochastParameters_NameNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => new XElement("root").GetStochastParameters(null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("stochastName", exception.ParamName);
+ }
+
+ [Test]
+ public void GetStochastParameters_RootWithoutStochastsElement_ReturnsNull()
+ {
+ // Setup
+ var xElement = new XElement("root");
+
+ // Call
+ var stochast = xElement.GetStochastParameters("some name");
+
+ // Assert
+ Assert.IsNull(stochast);
+ }
+
+ [Test]
+ public void GetStochastParameters_EmptyStochastsElement_ReturnsNull()
+ {
+ // Setup
+ var xElement = new XElement("root", new XElement("stochasten"));
+
+ // Call
+ var stochast = xElement.GetStochastParameters("some name");
+
+ // Assert
+ Assert.IsNull(stochast);
+ }
+
+ [Test]
+ public void GetStochastParameters_StochastWithDifferentName_ReturnsNull()
+ {
+ // Setup
+ var stochastElement = new XElement("stochast");
+ stochastElement.SetAttributeValue("naam", "stochastA");
+ var xElement = new XElement("root", new XElement("stochasten", stochastElement));
+
+ // Call
+ var stochast = xElement.GetStochastParameters("stochastB");
+
+ // Assert
+ Assert.IsNull(stochast);
+ }
+
+ [Test]
+ public void GetStochastParameters_StochastWithSameName_ReturnsNewStochast()
+ {
+ // Setup
+ var stochastName = "stochastA";
+
+ var stochastElement = new XElement("stochast");
+ stochastElement.SetAttributeValue("naam", stochastName);
+ var xElement = new XElement("root", new XElement("stochasten", stochastElement));
+
+ // Call
+ var stochast = xElement.GetStochastParameters(stochastName);
+
+ // Assert
+ Assert.IsNull(stochast.Mean);
+ Assert.IsNull(stochast.StandardDeviation);
+ }
+
+ [Test]
+ public void GetStochastParameters_StochastWithParameters_ReturnsNewStochastWithParametersSet()
+ {
+ // Setup
+ var stochastName = "stochastA";
+ var mean = 1.2;
+ var standardDeviation = 3.5;
+
+ var stochastElement = new XElement("stochast");
+ stochastElement.SetAttributeValue("naam", stochastName);
+ stochastElement.Add(new XElement("verwachtingswaarde", mean));
+ stochastElement.Add(new XElement("standaardafwijking", standardDeviation));
+ stochastElement.Add(new XElement("variatiecoefficient", standardDeviation));
+ var xElement = new XElement("root", new XElement("stochasten", stochastElement));
+
+ // Call
+ var stochast = xElement.GetStochastParameters(stochastName);
+
+ // Assert
+ Assert.AreEqual(mean, stochast.Mean);
+ Assert.AreEqual(standardDeviation, stochast.StandardDeviation);
+ Assert.AreEqual(standardDeviation, stochast.VariationCoefficient);
+ }
+
+ private class DoubleToBooleanConverter : TypeConverter
+ {
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ var doubleValue = value as double?;
+ if (doubleValue != null)
+ {
+ if (Math.Abs(doubleValue.Value) < double.Epsilon)
+ {
+ return false;
+ }
+ return true;
+ }
+ return base.ConvertFrom(context, culture, value);
+ }
+ }
+
+ private class ConverterThrowsExceptionOnConvertFrom : TypeConverter
+ {
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ throw new Exception($"{value} is not a valid value for the target type.");
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/XmlWriterExtensionsTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/XmlWriterExtensionsTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Helpers/XmlWriterExtensionsTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,436 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Xml;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Helpers;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Helpers
+{
+ [TestFixture]
+ public class XmlWriterExtensionsTest
+ {
+ private static readonly string testDirectory = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, nameof(XmlWriterExtensions));
+
+ [Test]
+ public void WriteStartFolder_WithNameAndWriter_WritesFolderStart()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteStartFolder_WithNameAndWriter_WritesFolderStart));
+ const string name = "folder";
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ xmlWriter.WriteStartFolder(name);
+
+ // Assert
+ Assert.AreEqual(WriteState.Element, xmlWriter.WriteState);
+ }
+
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = GetTestFileContent("simpleFolder.xml");
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteStartFolder_WithoutWriter_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate testDelegate = () => ((XmlWriter) null).WriteStartFolder("name");
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteStartFolder_WithoutName_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ TestDelegate testDelegate = () => xmlWriter.WriteStartFolder(null);
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("name", exception.ParamName);
+ }
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistribution_StandardDeviationDistributionWithoutWriter_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate testDelegate = () => ((XmlWriter) null).WriteDistribution("name", new StochastConfiguration());
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteDistribution_StandardDeviationDistributionWithoutName_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ TestDelegate testDelegate = () => xmlWriter.WriteDistribution(null, new StochastConfiguration());
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("name", exception.ParamName);
+ }
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistribution_WithoutStandardDeviationDistribution_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ TestDelegate testDelegate = () => xmlWriter.WriteDistribution("name", (StochastConfiguration) null);
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("distribution", exception.ParamName);
+ }
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ [TestCaseSource(nameof(GetDistributions))]
+ public void WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters(StochastConfiguration distribution, string fileName)
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+ const string name = "distribution";
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ xmlWriter.WriteDistribution(name, distribution);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = GetTestFileContent(fileName);
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistribution_VariationCoefficientDistributionWithoutWriter_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate testDelegate = () => ((XmlWriter) null).WriteDistribution("name", new StochastConfiguration());
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteDistribution_VariationCoefficientDistributionWithoutName_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ TestDelegate testDelegate = () => xmlWriter.WriteDistribution(null, new StochastConfiguration());
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("name", exception.ParamName);
+ }
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteDistribution_WithoutVariationCoefficientDistribution_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ TestDelegate testDelegate = () => xmlWriter.WriteDistribution("name", (StochastConfiguration) null);
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("distribution", exception.ParamName);
+ }
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ [TestCaseSource(nameof(GetWaveReductions))]
+ public void WriteWaveReduction_WithoutDifferentSetParameters_WritesStochastWithSetParameters(WaveReductionConfiguration waveReduction, string fileName)
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(
+ $"{nameof(WriteWaveReduction_WithoutDifferentSetParameters_WritesStochastWithSetParameters)}.{fileName}");
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ xmlWriter.WriteWaveReduction(waveReduction);
+ }
+
+ // Assert
+ string actualXml = File.ReadAllText(filePath);
+ string expectedXml = GetTestFileContent(fileName);
+ Assert.AreEqual(expectedXml, actualXml);
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ [Test]
+ public void WriteWaveReduction_WithoutWriter_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate testDelegate = () => ((XmlWriter) null).WriteWaveReduction(new WaveReductionConfiguration());
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("writer", exception.ParamName);
+ }
+
+ [Test]
+ public void WriteWaveReduction_WithoutWaveReduction_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = TestHelper.GetScratchPadPath(nameof(WriteDistribution_WithDifferentSetParameters_WritesStochastWithSetParameters));
+
+ try
+ {
+ using (XmlWriter xmlWriter = CreateXmlWriter(filePath))
+ {
+ // Call
+ TestDelegate testDelegate = () => xmlWriter.WriteWaveReduction(null);
+
+ // Assert
+ var exception = Assert.Throws(testDelegate);
+ Assert.AreEqual("waveReduction", exception.ParamName);
+ }
+ }
+ finally
+ {
+ File.Delete(filePath);
+ }
+ }
+
+ public static IEnumerable GetDistributions()
+ {
+ yield return new TestCaseData(
+ new StochastConfiguration(),
+ "distributionEmpty.xml")
+ .SetName("Distribution with no parameters.");
+
+ yield return new TestCaseData(
+ new StochastConfiguration
+ {
+ Mean = 0.2
+ },
+ "distributionMean.xml")
+ .SetName("Distribution with mean.");
+
+ yield return new TestCaseData(
+ new StochastConfiguration
+ {
+ StandardDeviation = 0.1
+ },
+ "distributionStandardDeviation.xml")
+ .SetName("Distribution with standard deviation.");
+
+ yield return new TestCaseData(
+ new StochastConfiguration
+ {
+ Mean = 0.2,
+ StandardDeviation = 0.1
+ },
+ "distributionMeanStandardDeviation.xml")
+ .SetName("Distribution with mean and standard deviation.");
+
+ yield return new TestCaseData(
+ new StochastConfiguration
+ {
+ VariationCoefficient = 0.1
+ },
+ "distributionVariationCoefficient.xml")
+ .SetName("Distribution with variation coefficient.");
+
+ yield return new TestCaseData(
+ new StochastConfiguration
+ {
+ Mean = 0.2,
+ VariationCoefficient = 0.1
+ },
+ "distributionMeanVariationCoefficient.xml")
+ .SetName("Distribution with mean and variation coefficient.");
+ }
+
+ public static IEnumerable GetWaveReductions()
+ {
+ yield return new TestCaseData(
+ new WaveReductionConfiguration(),
+ "waveReductionWithoutParameters.xml")
+ .SetName("Wave reduction without any of its paramters set.");
+
+ yield return new TestCaseData(
+ new WaveReductionConfiguration
+ {
+ UseBreakWater = true,
+ BreakWaterType = ConfigurationBreakWaterType.Dam,
+ BreakWaterHeight = 2.33,
+ UseForeshoreProfile = false
+ },
+ "waveReduction.xml")
+ .SetName("Wave reduction with all its paramters set.");
+
+ yield return new TestCaseData(
+ new WaveReductionConfiguration
+ {
+ UseBreakWater = true,
+ BreakWaterType = ConfigurationBreakWaterType.Caisson,
+ UseForeshoreProfile = false
+ },
+ "waveReductionWithoutBreakWaterHeight.xml")
+ .SetName("Wave reduction without break water height set.");
+
+ yield return new TestCaseData(
+ new WaveReductionConfiguration
+ {
+ UseBreakWater = false,
+ BreakWaterHeight = 12.66,
+ UseForeshoreProfile = true
+ },
+ "waveReductionWithoutBreakWaterType.xml")
+ .SetName("Wave reduction without break water type set.");
+
+ yield return new TestCaseData(
+ new WaveReductionConfiguration
+ {
+ BreakWaterType = ConfigurationBreakWaterType.Wall,
+ BreakWaterHeight = 23.4,
+ UseForeshoreProfile = false
+ },
+ "waveReductionWithoutUseBreakWater.xml")
+ .SetName("Wave reduction without use break water set.");
+
+ yield return new TestCaseData(
+ new WaveReductionConfiguration
+ {
+ UseBreakWater = true,
+ BreakWaterType = ConfigurationBreakWaterType.Dam,
+ BreakWaterHeight = 0.2,
+ },
+ "waveReductionWithoutUseForeshoreProfile.xml")
+ .SetName("Wave reduction without use foreshore profile set.");
+ }
+
+ private string GetTestFileContent(string testFile)
+ {
+ return File.ReadAllText(Path.Combine(testDirectory, testFile));
+ }
+
+ private static XmlWriter CreateXmlWriter(string filePath)
+ {
+ return XmlWriter.Create(filePath, new XmlWriterSettings
+ {
+ Indent = true,
+ ConformanceLevel = ConformanceLevel.Fragment
+ });
+ }
+ }
+
+ public class SimpleStructuresCalculationConfiguration : StructuresCalculationConfiguration
+ {
+ public SimpleStructuresCalculationConfiguration(string name) : base(name) { }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Import/CalculationConfigurationImporterTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Import/CalculationConfigurationImporterTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Import/CalculationConfigurationImporterTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,1096 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using Core.Common.Base;
+using Core.Common.Base.Data;
+using Core.Common.Base.Geometry;
+using Core.Common.Base.IO;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Ringtoets.Common.Data;
+using Ringtoets.Common.Data.Calculation;
+using Ringtoets.Common.Data.DikeProfiles;
+using Ringtoets.Common.Data.Hydraulics;
+using Ringtoets.Common.Data.Probabilistics;
+using Ringtoets.Common.Data.TestUtil;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Import;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Import
+{
+ [TestFixture]
+ public class CalculationConfigurationImporterTest
+ {
+ private readonly string readerPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, nameof(CalculationConfigurationReader));
+
+ [Test]
+ public void Constructor_ExpectedValues()
+ {
+ // Call
+ var importer = new CalculationConfigurationImporter("",
+ new CalculationGroup());
+
+ // Assert
+ Assert.IsInstanceOf>(importer);
+ }
+
+ [Test]
+ public void Import_FilePathIsDirectory_CancelImportWithErrorMessage()
+ {
+ // Setup
+ string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.DirectorySeparatorChar.ToString());
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ new CalculationGroup());
+
+ // Call
+ var importSuccessful = true;
+ Action call = () => importSuccessful = importer.Import();
+
+ // Assert
+ string expectedMessage = $"Fout bij het lezen van bestand '{filePath}': bestandspad mag niet verwijzen naar een lege bestandsnaam. " + Environment.NewLine +
+ "Er is geen berekeningenconfiguratie geïmporteerd.";
+ TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
+ Assert.IsFalse(importSuccessful);
+ }
+
+ [Test]
+ public void Import_FileDoesNotExist_CancelImportWithErrorMessage()
+ {
+ // Setup
+ string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "I_dont_exist");
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ new CalculationGroup());
+
+ // Call
+ var importSuccessful = true;
+ Action call = () => importSuccessful = importer.Import();
+
+ // Assert
+ string expectedMessage = $"Fout bij het lezen van bestand '{filePath}': het bestand bestaat niet. " + Environment.NewLine +
+ "Er is geen berekeningenconfiguratie geïmporteerd.";
+ TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
+ Assert.IsFalse(importSuccessful);
+ }
+
+ [Test]
+ public void Import_InvalidFile_CancelImportWithErrorMessage()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "invalidFolderNoName.xml");
+ var importer = new CalculationConfigurationImporter(filePath,
+ new CalculationGroup());
+
+ // Call
+ var importSuccessful = true;
+ Action call = () => importSuccessful = importer.Import();
+
+ // Assert
+ TestHelper.AssertLogMessages(call, messages =>
+ {
+ string[] msgs = messages.ToArray();
+ Assert.AreEqual(1, msgs.Length);
+ StringAssert.StartsWith($"Fout bij het lezen van bestand '{filePath}': het XML-document dat de configuratie voor de berekeningen beschrijft is niet geldig.", msgs[0]);
+ });
+
+ Assert.IsFalse(importSuccessful);
+ }
+
+ [Test]
+ [TestCase("Inlezen")]
+ [TestCase("Valideren")]
+ public void Import_CancelingImport_CancelImportAndLog(string expectedProgressMessage)
+ {
+ // Setup
+ var calculationGroup = new CalculationGroup();
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ importer.SetProgressChanged((description, step, steps) =>
+ {
+ if (description.Contains(expectedProgressMessage))
+ {
+ importer.Cancel();
+ }
+ });
+
+ // Call
+ var importSuccessful = true;
+ Action call = () => importSuccessful = importer.Import();
+
+ // Assert
+ TestHelper.AssertLogMessageIsGenerated(call, "Berekeningenconfiguratie importeren afgebroken. Geen data ingelezen.", 1);
+ CollectionAssert.IsEmpty(calculationGroup.Children);
+ Assert.IsFalse(importSuccessful);
+ }
+
+ [Test]
+ public void GivenImport_WhenImporting_ThenExpectedProgressMessagesGenerated()
+ {
+ // Given
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+ var importer = new CalculationConfigurationImporter(filePath,
+ new CalculationGroup());
+
+ var expectedProgressMessages = new[]
+ {
+ new ExpectedProgressNotification
+ {
+ Text = "Inlezen berekeningenconfiguratie.",
+ CurrentStep = 1,
+ TotalNumberOfSteps = 3
+ },
+ new ExpectedProgressNotification
+ {
+ Text = "Valideren berekeningenconfiguratie.",
+ CurrentStep = 2,
+ TotalNumberOfSteps = 3
+ },
+ new ExpectedProgressNotification
+ {
+ Text = "Geïmporteerde data toevoegen aan het toetsspoor.",
+ CurrentStep = 3,
+ TotalNumberOfSteps = 3
+ }
+ };
+
+ var progressChangedCallCount = 0;
+ importer.SetProgressChanged((description, step, steps) =>
+ {
+ Assert.AreEqual(expectedProgressMessages[progressChangedCallCount].Text, description);
+ Assert.AreEqual(expectedProgressMessages[progressChangedCallCount].CurrentStep, step);
+ Assert.AreEqual(expectedProgressMessages[progressChangedCallCount].TotalNumberOfSteps, steps);
+ progressChangedCallCount++;
+ });
+
+ // When
+ importer.Import();
+
+ // Then
+ Assert.AreEqual(expectedProgressMessages.Length, progressChangedCallCount);
+ }
+
+ [Test]
+ public void Import_ValidConfigurationWithValidData_DataAddedToModel()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ // Call
+ bool successful = importer.Import();
+
+ // Assert
+ Assert.IsTrue(successful);
+ AssertCalculationGroup(GetExpectedNestedData(), calculationGroup);
+ }
+
+ [Test]
+ [TestCase(true, true, 1.2, ConfigurationBreakWaterType.Wall, BreakWaterType.Wall)]
+ [TestCase(false, false, 2.2, ConfigurationBreakWaterType.Caisson, BreakWaterType.Caisson)]
+ [TestCase(false, true, 11.332, ConfigurationBreakWaterType.Wall, BreakWaterType.Wall)]
+ [TestCase(true, false, 9.3, ConfigurationBreakWaterType.Dam, BreakWaterType.Dam)]
+ public void ReadWaveReduction_DifferentScenarios_CorrectParametersSet(bool useForeshoreProfile, bool useBreakWater, double height, ConfigurationBreakWaterType type, BreakWaterType expectedType)
+ {
+ // Setup
+ var testInput = new TestInputWithForeshoreProfileAndBreakWater(new BreakWater(BreakWaterType.Caisson, 0.0));
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ var waveReductionConfiguration = new WaveReductionConfiguration
+ {
+ UseForeshoreProfile = useForeshoreProfile,
+ UseBreakWater = useBreakWater,
+ BreakWaterHeight = height,
+ BreakWaterType = type
+ };
+
+ // Call
+ importer.PublicReadWaveReductionParameters(waveReductionConfiguration, testInput);
+
+ // Assert
+ Assert.AreEqual(testInput.UseForeshore, useForeshoreProfile);
+ Assert.AreEqual(testInput.UseBreakWater, useBreakWater);
+ Assert.AreEqual(testInput.BreakWater.Height, height, testInput.BreakWater.Height.GetAccuracy());
+ Assert.AreEqual(testInput.BreakWater.Type, expectedType);
+ }
+
+ [Test]
+ public void ReadWaveReduction_WithoutConfiguration_ParametersUnchanged()
+ {
+ // Setup
+ var random = new Random(21);
+ bool useForeshoreProfile = random.NextBoolean();
+ bool useBreakWater = random.NextBoolean();
+ double height = random.NextDouble();
+ var breakWaterType = random.NextEnumValue();
+
+ var testInput = new TestInputWithForeshoreProfileAndBreakWater(new BreakWater(breakWaterType, height))
+ {
+ UseBreakWater = useBreakWater,
+ UseForeshore = useForeshoreProfile
+ };
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ // Call
+ importer.PublicReadWaveReductionParameters(null, testInput);
+
+ // Assert
+ Assert.AreEqual(testInput.UseForeshore, useForeshoreProfile);
+ Assert.AreEqual(testInput.UseBreakWater, useBreakWater);
+ Assert.AreEqual(testInput.BreakWater.Height, height, testInput.BreakWater.Height.GetAccuracy());
+ Assert.AreEqual(testInput.BreakWater.Type, breakWaterType);
+ }
+
+ [Test]
+ public void ReadWaveReduction_WithConfigurationWithMissingParameter_MissingParameterUnchanged([Values(0, 1, 2, 3)] int parameterNotSet)
+ {
+ // Setup
+ const bool useForeshoreProfile = false;
+ const bool useBreakWater = false;
+ const double height = 2.55;
+ const BreakWaterType breakWaterType = BreakWaterType.Dam;
+
+ const bool newUseForeshoreProfile = true;
+ const bool newUseBreakWater = true;
+ const double newheight = 11.1;
+ const ConfigurationBreakWaterType newBreakWaterType = ConfigurationBreakWaterType.Wall;
+ const BreakWaterType expectedNewBreakWaterType = BreakWaterType.Wall;
+
+ var testInput = new TestInputWithForeshoreProfileAndBreakWater(new BreakWater(breakWaterType, height))
+ {
+ UseBreakWater = useBreakWater,
+ UseForeshore = useForeshoreProfile
+ };
+
+ var waveReductionConfiguration = new WaveReductionConfiguration();
+ if (parameterNotSet != 0)
+ {
+ waveReductionConfiguration.UseForeshoreProfile = newUseForeshoreProfile;
+ }
+ if (parameterNotSet != 1)
+ {
+ waveReductionConfiguration.UseBreakWater = newUseBreakWater;
+ }
+ if (parameterNotSet != 2)
+ {
+ waveReductionConfiguration.BreakWaterHeight = newheight;
+ }
+ if (parameterNotSet != 3)
+ {
+ waveReductionConfiguration.BreakWaterType = newBreakWaterType;
+ }
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ // Call
+ importer.PublicReadWaveReductionParameters(waveReductionConfiguration, testInput);
+
+ // Assert
+ Assert.AreEqual(testInput.UseForeshore, parameterNotSet == 0 ? useForeshoreProfile : newUseForeshoreProfile);
+ Assert.AreEqual(testInput.UseBreakWater, parameterNotSet == 1 ? useBreakWater : newUseBreakWater);
+ Assert.AreEqual(testInput.BreakWater.Height, parameterNotSet == 2 ? height : newheight, testInput.BreakWater.Height.GetAccuracy());
+ Assert.AreEqual(testInput.BreakWater.Type, parameterNotSet == 3 ? breakWaterType : expectedNewBreakWaterType);
+ }
+
+ [Test]
+ public void TryReadHydraulicBoundaryLocation_NoCalculationName_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ HydraulicBoundaryLocation location;
+
+ // Call
+ TestDelegate test = () => importer.PublicTryReadHydraulicBoundaryLocation(null, null, Enumerable.Empty(), out location);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("calculationName", exception.ParamName);
+ }
+
+ [Test]
+ public void TryReadHydraulicBoundaryLocation_NoHydraulicBoundaryLocations_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ HydraulicBoundaryLocation location;
+
+ // Call
+ TestDelegate test = () => importer.PublicTryReadHydraulicBoundaryLocation(null, "name", null, out location);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("hydraulicBoundaryLocations", exception.ParamName);
+ }
+
+ [Test]
+ public void TryReadHydraulicBoundaryLocation_NoHydraulicBoundaryLocationToFindHydraulicBoundaryLocationsEmpty_ReturnsTrue()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ HydraulicBoundaryLocation location;
+
+ // Call
+ bool valid = importer.PublicTryReadHydraulicBoundaryLocation(null, "name", Enumerable.Empty(), out location);
+
+ // Assert
+ Assert.IsTrue(valid);
+ Assert.IsNull(location);
+ }
+
+ [Test]
+ public void TryReadHydraulicBoundaryLocation_WithHydraulicBoundaryLocationToFindHydraulicBoundaryLocationsEmpty_LogsErrorReturnsFalse()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ HydraulicBoundaryLocation location = null;
+ var valid = true;
+
+ const string locationName = "someName";
+ const string calculationName = "name";
+
+ // Call
+ Action validate = () => valid = importer.PublicTryReadHydraulicBoundaryLocation(locationName, calculationName, Enumerable.Empty(), out location);
+
+ // Assert
+ string expectedMessage = $"De locatie met hydraulische randvoorwaarden '{locationName}' bestaat niet. Berekening '{calculationName}' is overgeslagen.";
+ TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedMessage, LogLevelConstant.Error));
+ Assert.IsFalse(valid);
+ Assert.IsNull(location);
+ }
+
+ [Test]
+ public void TryReadHydraulicBoundaryLocation_WithHydraulicBoundaryLocationToFindHydraulicBoundaryLocationsContainsLocation_ReturnsTrue()
+ {
+ // Setup
+ const string locationName = "someName";
+ const string calculationName = "name";
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ HydraulicBoundaryLocation expectedLocation = new TestHydraulicBoundaryLocation(locationName);
+ HydraulicBoundaryLocation location;
+
+ // Call
+ bool valid = importer.PublicTryReadHydraulicBoundaryLocation(locationName,
+ calculationName,
+ new[]
+ {
+ new TestHydraulicBoundaryLocation("otherNameA"),
+ expectedLocation,
+ new TestHydraulicBoundaryLocation("otherNameB")
+ },
+ out location);
+
+ // Assert
+ Assert.IsTrue(valid);
+ Assert.AreSame(expectedLocation, location);
+ }
+
+ [Test]
+ public void TryReadForeshoreProfile_NoCalculationName_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ ForeshoreProfile profile;
+
+ // Call
+ TestDelegate test = () => importer.PublicTryReadForeshoreProfile(null, null, Enumerable.Empty(), out profile);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("calculationName", exception.ParamName);
+ }
+
+ [Test]
+ public void TryReadForeshoreProfile_NoForeshoreProfiles_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ ForeshoreProfile profile;
+
+ // Call
+ TestDelegate test = () => importer.PublicTryReadForeshoreProfile(null, "name", null, out profile);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("foreshoreProfiles", exception.ParamName);
+ }
+
+ [Test]
+ public void TryReadForeshoreProfile_NoForeshoreProfileToFindForeshoreProfilesEmpty_ReturnsTrue()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ ForeshoreProfile profile;
+
+ // Call
+ bool valid = importer.PublicTryReadForeshoreProfile(null, "name", Enumerable.Empty(), out profile);
+
+ // Assert
+ Assert.IsTrue(valid);
+ Assert.IsNull(profile);
+ }
+
+ [Test]
+ public void TryReadForeshoreProfile_WithForeshoreProfileToFindForeshoreProfilesEmpty_LogsErrorReturnsFalse()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ ForeshoreProfile profile = null;
+ var valid = true;
+
+ const string profileName = "someName";
+ const string calculationName = "name";
+
+ // Call
+ Action validate = () => valid = importer.PublicTryReadForeshoreProfile(profileName, calculationName, Enumerable.Empty(), out profile);
+
+ // Assert
+ string expectedMessage = $"Het voorlandprofiel '{profileName}' bestaat niet. Berekening '{calculationName}' is overgeslagen.";
+ TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedMessage, LogLevelConstant.Error));
+ Assert.IsFalse(valid);
+ Assert.IsNull(profile);
+ }
+
+ [Test]
+ public void TryReadForeshoreProfile_WithForeshoreProfileToFindForeshoreProfilesContainsProfile_ReturnsTrue()
+ {
+ // Setup
+ const string profileName = "someName";
+ const string calculationName = "name";
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ ForeshoreProfile expectedProfile = new TestForeshoreProfile(profileName);
+ ForeshoreProfile profile;
+
+ // Call
+ bool valid = importer.PublicTryReadForeshoreProfile(profileName,
+ calculationName,
+ new[]
+ {
+ new TestForeshoreProfile("otherNameA"),
+ expectedProfile,
+ new TestForeshoreProfile("otherNameB")
+ },
+ out profile);
+
+ // Assert
+ Assert.IsTrue(valid);
+ Assert.AreSame(expectedProfile, profile);
+ }
+
+ [Test]
+ public void TryReadStructure_NoCalculationName_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ StructureBase structure;
+
+ // Call
+ TestDelegate test = () => importer.PublicTryReadStructure(null, null, Enumerable.Empty(), out structure);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("calculationName", exception.ParamName);
+ }
+
+ [Test]
+ public void TryReadStructure_NoStructures_ThrowsArgumentNullException()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ StructureBase structure;
+
+ // Call
+ TestDelegate test = () => importer.PublicTryReadStructure(null, "name", null, out structure);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("structures", exception.ParamName);
+ }
+
+ [Test]
+ public void TryReadStructure_NoStructureToFindStructuresEmpty_ReturnsTrue()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ StructureBase structure;
+
+ // Call
+ bool valid = importer.PublicTryReadStructure(null, "name", Enumerable.Empty(), out structure);
+
+ // Assert
+ Assert.IsTrue(valid);
+ Assert.IsNull(structure);
+ }
+
+ [Test]
+ public void TryReadStructure_WithStructureToFindStructuresEmpty_LogsErrorReturnsFalse()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ StructureBase profile = null;
+ var valid = true;
+
+ const string structureName = "someName";
+ const string calculationName = "name";
+
+ // Call
+ Action validate = () => valid = importer.PublicTryReadStructure(structureName, calculationName, Enumerable.Empty(), out profile);
+
+ // Assert
+ string expectedMessage = $"Het kunstwerk '{structureName}' bestaat niet. Berekening '{calculationName}' is overgeslagen.";
+ TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedMessage, LogLevelConstant.Error));
+ Assert.IsFalse(valid);
+ Assert.IsNull(profile);
+ }
+
+ [Test]
+ public void TryReadStructure_WithStructureToFindStructuresContainsStructure_ReturnsTrue()
+ {
+ // Setup
+ const string structureName = "someName";
+ const string calculationName = "name";
+
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+
+ var calculationGroup = new CalculationGroup();
+
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ var expectedProfile = new TestStructure(structureName);
+ StructureBase structure;
+
+ // Call
+ bool valid = importer.PublicTryReadStructure(structureName,
+ calculationName,
+ new[]
+ {
+ new TestStructure("otherNameA"),
+ expectedProfile,
+ new TestStructure("otherNameB")
+ },
+ out structure);
+
+ // Assert
+ Assert.IsTrue(valid);
+ Assert.AreSame(expectedProfile, structure);
+ }
+
+ [Test]
+ [TestCase(true, false)]
+ [TestCase(false, true)]
+ [TestCase(true, true)]
+ [TestCase(false, false)]
+ public void TryReadStandardDeviationStochast_ValidStochastConfiguration_ReturnsTrueParametersSet(bool setMean, bool setStandardDeviation)
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+ var calculationGroup = new CalculationGroup();
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ var configuration = new StochastConfiguration();
+
+ var random = new Random(21);
+ double mean = random.NextDouble();
+ double standardDeviation = random.NextDouble();
+ if (setMean)
+ {
+ configuration.Mean = mean;
+ }
+ if (setStandardDeviation)
+ {
+ configuration.StandardDeviation = standardDeviation;
+ }
+ var input = new TestInputWithStochasts();
+
+ // Call
+ bool valid = importer.PublicTryReadStandardDeviationStochast(
+ "some stochast name",
+ "some calculation name",
+ input,
+ configuration, i => i.Distribution,
+ (i, s) => i.Distribution = s);
+
+ // Assert
+ Assert.IsTrue(valid);
+ var defaultLogNormal = new LogNormalDistribution();
+ Assert.AreEqual(
+ setMean ? mean : defaultLogNormal.Mean,
+ input.Distribution.Mean,
+ input.Distribution.Mean.GetAccuracy());
+ Assert.AreEqual(
+ setStandardDeviation ? standardDeviation : defaultLogNormal.StandardDeviation,
+ input.Distribution.StandardDeviation,
+ input.Distribution.StandardDeviation.GetAccuracy());
+ }
+
+ [Test]
+ public void TryReadStandardDeviationStochast_StochastConfigurationWithStandardDeviation_LogsErrorReturnsFalse()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+ var calculationGroup = new CalculationGroup();
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ var configuration = new StochastConfiguration
+ {
+ VariationCoefficient = new Random(21).NextDouble()
+ };
+
+ var input = new TestInputWithStochasts();
+ var valid = true;
+ const string stochastName = "some stochast name";
+ const string calculationName = "some calculation name";
+
+ // Call
+ Action validate = () => valid = importer.PublicTryReadStandardDeviationStochast(
+ stochastName,
+ calculationName,
+ input, configuration,
+ i => i.Distribution,
+ (i, s) => i.Distribution = s);
+
+ // Assert
+ var expectedError = $"Indien voor parameter '{stochastName}' de spreiding wordt opgegeven, moet dit door middel van een standaardafwijking. " +
+ $"Voor berekening '{calculationName}' is een variatiecoëfficiënt gevonden. Berekening '{calculationName}' is overgeslagen.";
+ TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedError, LogLevelConstant.Error));
+ Assert.IsFalse(valid);
+ }
+
+ [Test]
+ [TestCase(true, false)]
+ [TestCase(false, true)]
+ [TestCase(true, true)]
+ [TestCase(false, false)]
+ public void TryReadVariationCoefficientStochast_ValidStochastConfiguration_ReturnsTrueParametersSet(bool setMean, bool setVariationCoefficient)
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+ var calculationGroup = new CalculationGroup();
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ var configuration = new StochastConfiguration();
+
+ var random = new Random(21);
+ double mean = random.NextDouble();
+ double variationCoefficient = random.NextDouble();
+ if (setMean)
+ {
+ configuration.Mean = mean;
+ }
+ if (setVariationCoefficient)
+ {
+ configuration.VariationCoefficient = variationCoefficient;
+ }
+ var input = new TestInputWithStochasts();
+
+ // Call
+ bool valid = importer.PublicTryReadVariationCoefficientStochast(
+ "some stochast name",
+ "some calculation name",
+ input, configuration,
+ i => i.VariationCoefficientDistribution,
+ (i, s) => i.VariationCoefficientDistribution = s);
+
+ // Assert
+ Assert.IsTrue(valid);
+ var defaultLogNormal = new VariationCoefficientLogNormalDistribution();
+ Assert.AreEqual(
+ setMean ? mean : defaultLogNormal.Mean,
+ input.VariationCoefficientDistribution.Mean,
+ input.VariationCoefficientDistribution.Mean.GetAccuracy());
+ Assert.AreEqual(
+ setVariationCoefficient ? variationCoefficient : defaultLogNormal.CoefficientOfVariation,
+ input.VariationCoefficientDistribution.CoefficientOfVariation,
+ input.VariationCoefficientDistribution.CoefficientOfVariation.GetAccuracy());
+ }
+
+ [Test]
+ public void TryReadVariationCoefficientStochast_StochastConfigurationWithStandardDeviation_LogsErrorReturnsFalse()
+ {
+ // Setup
+ string filePath = Path.Combine(readerPath, "validConfiguration.xml");
+ var calculationGroup = new CalculationGroup();
+ var importer = new CalculationConfigurationImporter(filePath,
+ calculationGroup);
+
+ var configuration = new StochastConfiguration
+ {
+ StandardDeviation = new Random(21).NextDouble()
+ };
+
+ var input = new TestInputWithStochasts();
+ var valid = true;
+ const string stochastName = "some stochast name";
+ const string calculationName = "some calculation name";
+
+ // Call
+ Action validate = () => valid = importer.PublicTryReadVariationCoefficientStochast(
+ stochastName,
+ calculationName,
+ input, configuration,
+ i => i.VariationCoefficientDistribution,
+ (i, s) => i.VariationCoefficientDistribution = s);
+
+ // Assert
+ var expectedError = $"Indien voor parameter '{stochastName}' de spreiding wordt opgegeven, moet dit door middel van een variatiecoëfficiënt. " +
+ $"Voor berekening '{calculationName}' is een standaardafwijking gevonden. Berekening '{calculationName}' is overgeslagen.";
+ TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedError, LogLevelConstant.Error));
+ Assert.IsFalse(valid);
+ }
+
+ private class CalculationConfigurationImporter : CalculationConfigurationImporter
+ {
+ public CalculationConfigurationImporter(string filePath, CalculationGroup importTarget)
+ : base(filePath, importTarget) { }
+
+ public void PublicReadWaveReductionParameters(WaveReductionConfiguration waveReduction, T input)
+ where T : IUseBreakWater, IUseForeshore
+ {
+ ReadWaveReductionParameters(waveReduction, input);
+ }
+
+ public bool PublicTryReadHydraulicBoundaryLocation(string locationName, string calculationName, IEnumerable hydraulicBoundaryLocations, out HydraulicBoundaryLocation location)
+ {
+ return TryReadHydraulicBoundaryLocation(locationName, calculationName, hydraulicBoundaryLocations, out location);
+ }
+
+ public bool PublicTryReadForeshoreProfile(string locationName, string calculationName, IEnumerable foreshoreProfiles, out ForeshoreProfile location)
+ {
+ return TryReadForeshoreProfile(locationName, calculationName, foreshoreProfiles, out location);
+ }
+
+ public bool PublicTryReadStructure(string locationName, string calculationName, IEnumerable structures, out StructureBase location)
+ {
+ return TryReadStructure(locationName, calculationName, structures, out location);
+ }
+
+ public bool PublicTryReadStandardDeviationStochast(
+ string stochastName,
+ string calculationName,
+ TestInputWithStochasts input,
+ StochastConfiguration stochastConfiguration,
+ Func getStochast,
+ Action setStochast)
+ where TDistribution : IDistribution
+ {
+ return TryReadStandardDeviationStochast(stochastName, calculationName, input, stochastConfiguration, getStochast, setStochast);
+ }
+
+ public bool PublicTryReadVariationCoefficientStochast(
+ string stochastName,
+ string calculationName,
+ TestInputWithStochasts input,
+ StochastConfiguration stochastConfiguration,
+ Func getStochast,
+ Action setStochast)
+ where TDistribution : IVariationCoefficientDistribution
+ {
+ return TryReadVariationCoefficientStochast(stochastName, calculationName, input, stochastConfiguration, getStochast, setStochast);
+ }
+
+ protected override CalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath)
+ {
+ return new CalculationConfigurationReader(xmlFilePath);
+ }
+
+ protected override ICalculation ParseReadCalculation(ReadCalculation readCalculation)
+ {
+ return new TestCalculation
+ {
+ Name = readCalculation.Name
+ };
+ }
+ }
+
+ private class CalculationConfigurationReader : CalculationConfigurationReader
+ {
+ private static readonly string mainSchemaDefinition =
+ File.ReadAllText(Path.Combine(TestHelper.GetTestDataPath(
+ TestDataPath.Ringtoets.Common.IO,
+ "CalculationConfigurationReader"),
+ "validConfigurationSchema.xsd"));
+
+ public CalculationConfigurationReader(string xmlFilePath)
+ : base(xmlFilePath, mainSchemaDefinition, new Dictionary()) { }
+
+ protected override ReadCalculation ParseCalculationElement(XElement calculationElement)
+ {
+ return new ReadCalculation(calculationElement.Attribute(ConfigurationSchemaIdentifiers.NameAttribute)?.Value);
+ }
+ }
+
+ private class ReadCalculation : IConfigurationItem
+ {
+ public ReadCalculation(string name)
+ {
+ Name = name;
+ }
+
+ public string Name { get; }
+ }
+
+ private class TestCalculation : Observable, ICalculation
+ {
+ public string Name { get; set; }
+ public bool HasOutput { get; }
+ public Comment Comments { get; }
+
+ public void ClearOutput()
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ private class ExpectedProgressNotification
+ {
+ public string Text { get; set; }
+ public int CurrentStep { get; set; }
+ public int TotalNumberOfSteps { get; set; }
+ }
+
+ private static CalculationGroup GetExpectedNestedData()
+ {
+ return new CalculationGroup("Root", false)
+ {
+ Children =
+ {
+ new CalculationGroup("Group 1", false)
+ {
+ Children =
+ {
+ new TestCalculation
+ {
+ Name = "Calculation 3"
+ }
+ }
+ },
+ new TestCalculation
+ {
+ Name = "Calculation 1"
+ },
+ new CalculationGroup("Group 2", false)
+ {
+ Children =
+ {
+ new CalculationGroup("Group 4", false)
+ {
+ Children =
+ {
+ new TestCalculation
+ {
+ Name = "Calculation 5"
+ }
+ }
+ },
+ new TestCalculation
+ {
+ Name = "Calculation 4"
+ }
+ }
+ },
+ new TestCalculation
+ {
+ Name = "Calculation 2"
+ },
+ new CalculationGroup("Group 3", false)
+ }
+ };
+ }
+
+ private static void AssertCalculationGroup(CalculationGroup expectedCalculationGroup, CalculationGroup actualCalculationGroup)
+ {
+ Assert.AreEqual(expectedCalculationGroup.Children.Count, actualCalculationGroup.Children.Count);
+ Assert.IsTrue(actualCalculationGroup.IsNameEditable);
+
+ for (var i = 0; i < expectedCalculationGroup.Children.Count; i++)
+ {
+ Assert.AreEqual(expectedCalculationGroup.Children[i].Name, actualCalculationGroup.Children[i].Name);
+ var innerCalculationgroup = expectedCalculationGroup.Children[i] as CalculationGroup;
+ var innerCalculation = expectedCalculationGroup.Children[i] as TestCalculation;
+
+ if (innerCalculationgroup != null)
+ {
+ AssertCalculationGroup(innerCalculationgroup, (CalculationGroup) actualCalculationGroup.Children[i]);
+ }
+
+ if (innerCalculation != null)
+ {
+ Assert.AreEqual(innerCalculation.Name, ((TestCalculation) actualCalculationGroup.Children[i]).Name);
+ }
+ }
+ }
+
+ private class TestStructure : StructureBase
+ {
+ public TestStructure(string name) : base(name, "id", new Point2D(0, 0), 2) { }
+ }
+
+ private class TestInputWithForeshoreProfileAndBreakWater : Observable, IUseBreakWater, IUseForeshore
+ {
+ public TestInputWithForeshoreProfileAndBreakWater(BreakWater breakWater)
+ {
+ BreakWater = breakWater;
+ }
+
+ public bool UseBreakWater { get; set; }
+ public BreakWater BreakWater { get; }
+ public bool UseForeshore { get; set; }
+
+ public RoundedPoint2DCollection ForeshoreGeometry
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+
+ private class TestInputWithStochasts : Observable, ICalculationInput
+ {
+ public TestInputWithStochasts()
+ {
+ Distribution = new LogNormalDistribution();
+ VariationCoefficientDistribution = new VariationCoefficientLogNormalDistribution();
+ }
+
+ public IDistribution Distribution { get; set; }
+ public IVariationCoefficientDistribution VariationCoefficientDistribution { get; set; }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Import/CalculationConfigurationReaderTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Import/CalculationConfigurationReaderTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Configurations/Import/CalculationConfigurationReaderTest.cs (revision fe7c27dc926b4087fd6ed9551655d0571c8018c9)
@@ -0,0 +1,369 @@
+// 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 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using Core.Common.Base.IO;
+using Core.Common.TestUtil;
+using NUnit.Framework;
+using Ringtoets.Common.IO.Configurations;
+using Ringtoets.Common.IO.Configurations.Import;
+
+namespace Ringtoets.Common.IO.Test.Configurations.Import
+{
+ [TestFixture]
+ public class CalculationConfigurationReaderTest
+ {
+ private readonly string validMainSchemaDefinition;
+
+ private readonly string testDirectoryPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
+ "CalculationConfigurationReader");
+
+ private static IEnumerable InvalidConfigurations
+ {
+ get
+ {
+ yield return new TestCaseData("invalidFolderNoName.xml",
+ "The required attribute 'naam' is missing.")
+ .SetName("invalidFolderNoName");
+ yield return new TestCaseData("invalidCalculationNoName.xml",
+ "The required attribute 'naam' is missing.")
+ .SetName("invalidCalculationNoName");
+ }
+ }
+
+ private static IEnumerable InvalidXml
+ {
+ get
+ {
+ yield return new TestCaseData(
+ "empty.xml",
+ "Root element is missing.")
+ .SetName("FileDoesNotContainValidXml_empty.xml");
+ yield return new TestCaseData(
+ "textContent.xml",
+ "Data at the root level is invalid. Line 1, position 1.")
+ .SetName("FileDoesNotContainValidXml_textContent.xml");
+ yield return new TestCaseData(
+ "invalidXmlContent.xml",
+ "The 'map' start tag on line 4 position 4 does not match the end tag of 'configuratie'. Line 5, position 3.")
+ .SetName("FileDoesNotContainValidXml_invalidXmlContent.xml");
+ yield return new TestCaseData(
+ "withoutQuotationMarks.xml",
+ "'Nieuw' is an unexpected token. The expected token is '\"' or '''. Line 3, position 20.")
+ .SetName("FileDoesNotContainValidXml_withoutQoutationMarks.xml");
+ }
+ }
+
+ [Test]
+ [TestCase("")]
+ [TestCase(" ")]
+ [TestCase(null)]
+ public void Constructor_NoFilePath_ThrowArgumentException(string invalidFilePath)
+ {
+ // Call
+ TestDelegate call = () => new CalculationConfigurationReader(invalidFilePath, validMainSchemaDefinition, new Dictionary());
+
+ // Assert
+ string expectedMessage = $"Fout bij het lezen van bestand '{invalidFilePath}': bestandspad mag niet leeg of ongedefinieerd zijn.";
+ TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage);
+ }
+
+ [Test]
+ public void Constructor_FilePathHasInvalidPathCharacter_ThrowArgumentException()
+ {
+ // Setup
+ char[] invalidPathChars = Path.GetInvalidPathChars();
+ string validFilePath = Path.Combine(testDirectoryPath, "validConfiguration.xml");
+ string invalidFilePath = validFilePath.Replace("Config", invalidPathChars[3].ToString());
+
+ // Call
+ TestDelegate call = () => new CalculationConfigurationReader(invalidFilePath, validMainSchemaDefinition, new Dictionary