Index: Ringtoets/Common/src/Ringtoets.Common.IO/FileImporters/CalculationConfigurationImporter.cs =================================================================== diff -u -re50b6ad32d33acb630c391bce2a6d359cc7e2b28 -r82af27f82c4dc2248e03c0e22bbe46b5e01e88bb --- Ringtoets/Common/src/Ringtoets.Common.IO/FileImporters/CalculationConfigurationImporter.cs (.../CalculationConfigurationImporter.cs) (revision e50b6ad32d33acb630c391bce2a6d359cc7e2b28) +++ Ringtoets/Common/src/Ringtoets.Common.IO/FileImporters/CalculationConfigurationImporter.cs (.../CalculationConfigurationImporter.cs) (revision 82af27f82c4dc2248e03c0e22bbe46b5e01e88bb) @@ -25,7 +25,10 @@ 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.IO.Configurations; using Ringtoets.Common.IO.Properties; using Ringtoets.Common.IO.Readers; @@ -127,6 +130,185 @@ message, calculationName); } + /// + /// Validate the defined wave reduction parameters in combination with a given foreshore profile. + /// + /// Configuration possibly containing wave reduction parameters. + /// The foreshore profile currently assigned to the calculation. + /// The name of the calculation which is being validated. + /// false when there is an invalid wave reduction parameter defined, true otherwise. + /// Thrown when is null. + protected bool ValidateWaveReduction(WaveReductionConfiguration waveReduction, ForeshoreProfile foreshoreProfile, string calculationName) + { + if (calculationName == null) + { + throw new ArgumentNullException(nameof(calculationName)); + } + + if (foreshoreProfile == null) + { + if (HasParametersDefined(waveReduction)) + { + LogReadCalculationConversionError( + Resources.CalculationConfigurationImporter_ValidateWaveReduction_No_foreshore_profile_provided, + calculationName); + + return false; + } + } + else if (!foreshoreProfile.Geometry.Any() && waveReduction.UseForeshoreProfile == true) + { + LogReadCalculationConversionError( + string.Format( + Resources.ReadForeshoreProfile_ForeshoreProfile_0_has_no_geometry_and_cannot_be_used, + foreshoreProfile.Name), + calculationName); + + return false; + } + return true; + } + + /// + /// 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) + { + var location = hydraulicBoundaryLocations.FirstOrDefault(l => l.Name == locationName); + + if (location == null) + { + LogReadCalculationConversionError( + 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 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) + { + LogReadCalculationConversionError( + 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) + { + var foreshoreProfile = foreshoreProfiles.FirstOrDefault(fp => fp.Name == foreshoreProfileName); + + if (foreshoreProfile == null) + { + LogReadCalculationConversionError( + string.Format( + Resources.CalculationConfigurationImporter_ReadForeshoreProfile_ForeshoreProfile_0_does_not_exist, + foreshoreProfileName), + calculationName); + + return false; + } + + foundForeshoreProfile = foreshoreProfile; + } + + return true; + } + private ReadResult ReadConfiguration() { try @@ -199,5 +381,14 @@ ImportTarget.Children.Add(parsedCalculationItem); } } + + private static bool HasParametersDefined(WaveReductionConfiguration waveReduction) + { + return waveReduction != null + && (waveReduction.UseBreakWater.HasValue + || waveReduction.UseForeshoreProfile.HasValue + || waveReduction.BreakWaterHeight.HasValue + || waveReduction.BreakWaterType.HasValue); + } } } \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/FileImporters/CalculationConfigurationImporterTest.cs =================================================================== diff -u -rcc1268d7cb906524d4cabcd4cbd9ae16676cf059 -r82af27f82c4dc2248e03c0e22bbe46b5e01e88bb --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/FileImporters/CalculationConfigurationImporterTest.cs (.../CalculationConfigurationImporterTest.cs) (revision cc1268d7cb906524d4cabcd4cbd9ae16676cf059) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/FileImporters/CalculationConfigurationImporterTest.cs (.../CalculationConfigurationImporterTest.cs) (revision 82af27f82c4dc2248e03c0e22bbe46b5e01e88bb) @@ -25,11 +25,15 @@ using System.Linq; using System.Xml.Linq; using Core.Common.Base; +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.TestUtil; using Ringtoets.Common.IO.Configurations; using Ringtoets.Common.IO.FileImporters; using Ringtoets.Common.IO.Readers; @@ -205,6 +209,557 @@ AssertCalculationGroup(GetExpectedNestedData(), calculationGroup); } + [Test] + public void ValidateWaveReduction_NoCalculationName_ThrowsArgumentNullException() + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + // Call + TestDelegate test = () => importer.PublicValidateWaveReduction(null, null, null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("calculationName", exception.ParamName); + } + + [Test] + public void ValidateWaveReduction_NoForeshoreProfileNoParameters_ReturnsTrue() + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + const string calculationName = "calculation"; + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + // Call + var valid = importer.PublicValidateWaveReduction(null, null, calculationName); + + // Assert + Assert.IsTrue(valid); + } + + [Test] + public void ValidateWaveReduction_NoForeshoreProfileWaveReductionWithoutParameters_ReturnsTrue() + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + const string calculationName = "calculation"; + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + // Call + var valid = importer.PublicValidateWaveReduction(new WaveReductionConfiguration(), null, calculationName); + + // Assert + Assert.IsTrue(valid); + } + + [Test] + public void ValidateWaveReduction_NoForeshoreProfileWaveReductionWithParameter_LogsErrorReturnsFalse([Values(0, 1, 2, 3)] int propertyToSet) + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + const string calculationName = "calculation"; + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + var waveReductionConfiguration = new WaveReductionConfiguration(); + var random = new Random(21); + + switch (propertyToSet) + { + case 0: + waveReductionConfiguration.BreakWaterType = random.NextEnumValue(); + break; + case 1: + waveReductionConfiguration.BreakWaterHeight = random.NextDouble(); + break; + case 2: + waveReductionConfiguration.UseBreakWater = random.NextBoolean(); + break; + case 3: + waveReductionConfiguration.UseForeshoreProfile = random.NextBoolean(); + break; + } + ; + + var valid = true; + + // Call + Action validate = () => valid = importer.PublicValidateWaveReduction(waveReductionConfiguration, null, calculationName); + + // Assert + var expectedMessage = $"Er is geen voorlandprofiel opgegeven om golfreductie parameters aan toe te voegen. Berekening '{calculationName}' is overgeslagen."; + TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedMessage, LogLevelConstant.Error)); + Assert.IsFalse(valid); + } + + [Test] + public void ValidateWaveReduction_ForeshoreProfileWithGeometryForeshoreProfileUsed_ReturnsTrue() + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + const string calculationName = "calculation"; + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + var waveReductionConfiguration = new WaveReductionConfiguration + { + UseForeshoreProfile = true + }; + + // Call + bool valid = importer.PublicValidateWaveReduction( + waveReductionConfiguration, + new TestForeshoreProfile("voorland", new[] + { + new Point2D(0, 2) + }), + calculationName); + + // Assert + Assert.IsTrue(valid); + } + + [Test] + public void ValidateWaveReduction_ForeshoreProfileWithoutGeometryForeshoreProfileUsed_LogsErrorReturnsFalse() + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + const string calculationName = "calculation"; + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + var waveReductionConfiguration = new WaveReductionConfiguration + { + UseForeshoreProfile = true + }; + + var valid = true; + var profileName = "voorland"; + + // Call + Action validate = () => valid = importer.PublicValidateWaveReduction(waveReductionConfiguration, new TestForeshoreProfile(profileName), calculationName); + + // Assert + var expectedMessage = $"Het opgegeven voorlandprofiel '{profileName}' heeft geen voorlandgeometrie en kan daarom niet gebruikt worden. Berekening '{calculationName}' is overgeslagen."; + TestHelper.AssertLogMessageWithLevelIsGenerated(validate, Tuple.Create(expectedMessage, LogLevelConstant.Error)); + Assert.IsFalse(valid); + } + + [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 + var 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; + bool valid = true; + + const string locationName = "someName"; + const string calculationName = "name"; + + // Call + Action validate = () => valid = importer.PublicTryReadHydraulicBoundaryLocation(locationName, calculationName, Enumerable.Empty(), out location); + + // Assert + var 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 + var 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; + bool valid = true; + + const string profileName = "someName"; + const string calculationName = "name"; + + // Call + Action validate = () => valid = importer.PublicTryReadForeshoreProfile(profileName, calculationName, Enumerable.Empty(), out profile); + + // Assert + var 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 + var 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; + bool valid = true; + + const string structureName = "someName"; + const string calculationName = "name"; + + // Call + Action validate = () => valid = importer.PublicTryReadStructure(structureName, calculationName, Enumerable.Empty(), out profile); + + // Assert + var 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); + + TestStructure 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] + public void LogOutOfRangeException_Always_LogMessage() + { + // Setup + string filePath = Path.Combine(readerPath, "validConfiguration.xml"); + + var calculationGroup = new CalculationGroup(); + + var importer = new CalculationConfigurationImporter(filePath, + calculationGroup); + + const string message = "an error"; + const string calculationName = "calculationA"; + const string innerMessage = "Inner message"; + ArgumentOutOfRangeException exception = new ArgumentOutOfRangeException(null, innerMessage); + + // Call + Action log = () => importer.PublicLogOutOfRangeException(message, calculationName, exception); + + // Assert + TestHelper.AssertLogMessageWithLevelIsGenerated(log, Tuple.Create($"{message} {innerMessage} Berekening '{calculationName}' is overgeslagen.", LogLevelConstant.Error)); + } + private class CalculationConfigurationImporter : CalculationConfigurationImporter { public CalculationConfigurationImporter(string filePath, CalculationGroup importTarget) @@ -222,6 +777,31 @@ Name = readCalculation.Name }; } + + public void PublicLogOutOfRangeException(string errorMessage, string calculationName, ArgumentOutOfRangeException e) + { + LogOutOfRangeException(errorMessage, calculationName, e); + } + + public bool PublicValidateWaveReduction(WaveReductionConfiguration waveReduction, ForeshoreProfile foreshoreProfile, string calculationName) + { + return ValidateWaveReduction(waveReduction, foreshoreProfile, calculationName); + } + + 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); + } } private class CalculationConfigurationReader : CalculationConfigurationReader @@ -256,6 +836,7 @@ public string Name { get; set; } public bool HasOutput { get; } public Comment Comments { get; } + public void ClearOutput() { throw new NotImplementedException(); @@ -340,5 +921,10 @@ } } } + + private class TestStructure : StructureBase + { + public TestStructure(string name) : base(name, "id", new Point2D(0, 0), 2) { } + } } } \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Writers/CalculationConfigurationWriterTest.cs =================================================================== diff -u -r91e6f4f761a8efdc9c847c99cdca18f514a67ed1 -r82af27f82c4dc2248e03c0e22bbe46b5e01e88bb --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Writers/CalculationConfigurationWriterTest.cs (.../CalculationConfigurationWriterTest.cs) (revision 91e6f4f761a8efdc9c847c99cdca18f514a67ed1) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Writers/CalculationConfigurationWriterTest.cs (.../CalculationConfigurationWriterTest.cs) (revision 82af27f82c4dc2248e03c0e22bbe46b5e01e88bb) @@ -291,7 +291,7 @@ { // Setup string filePath = TestHelper.GetScratchPadPath( - $"{nameof(WriteBreakWaterProperties_WithBreakWater_WritesPropertiesToFile)}.xml"); + $"{nameof(WriteBreakWaterProperties_WithBreakWater_WritesPropertiesToFile)} {type}"); string expectedXmlFilePath = TestHelper.GetTestDataPath( TestDataPath.Ringtoets.Common.IO, Index: Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationImporter.cs =================================================================== diff -u -r512bebcd5570951b18657513c56843d9e2f8e969 -r82af27f82c4dc2248e03c0e22bbe46b5e01e88bb --- Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationImporter.cs (.../HeightStructuresCalculationConfigurationImporter.cs) (revision 512bebcd5570951b18657513c56843d9e2f8e969) +++ Ringtoets/HeightStructures/src/Ringtoets.HeightStructures.IO/HeightStructuresCalculationConfigurationImporter.cs (.../HeightStructuresCalculationConfigurationImporter.cs) (revision 82af27f82c4dc2248e03c0e22bbe46b5e01e88bb) @@ -33,7 +33,6 @@ using Ringtoets.Common.IO.FileImporters; using Ringtoets.Common.IO.Schema; using Ringtoets.HeightStructures.Data; -using Ringtoets.HeightStructures.IO.Properties; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.HeightStructures.IO @@ -58,8 +57,8 @@ /// used to check if the imported objects contain the right location. /// The foreshore profiles used to check if /// the imported objects contain the right foreshore profile. - /// The dike profiles used to check if - /// the imported objects contain the right profile. + /// The structures used to check if + /// the imported objects contain the right structure. /// Thrown when any parameter is null. public HeightStructuresCalculationConfigurationImporter( string xmlFilePath, @@ -93,18 +92,18 @@ protected override ICalculation ParseReadCalculation(HeightStructuresCalculationConfiguration readCalculation) { - var calculation = new StructuresCalculation() + var calculation = new StructuresCalculation { Name = readCalculation.Name }; - if (TryReadStructure(readCalculation, calculation) + if (TryReadStructure(readCalculation.StructureName, calculation) + && TryReadHydraulicBoundaryLocation(readCalculation.HydraulicBoundaryLocationName, calculation) + && TryReadForeshoreProfile(readCalculation.ForeshoreProfileName, calculation) && TryReadStochasts(readCalculation, calculation) - && TryReadHydraulicBoundaryLocation(readCalculation, calculation) - && TryReadDikeProfile(readCalculation, calculation) && TryReadOrientation(readCalculation, calculation) && TryReadFailureProbabilityStructureWithErosion(readCalculation, calculation) - && TryReadWaveReduction(readCalculation, calculation)) + && TryReadWaveReduction(readCalculation.WaveReduction, calculation)) { return calculation; } @@ -338,175 +337,81 @@ return true; } - /// - /// Reads the hydraulic boundary location. - /// - /// The calculation read from the imported file. - /// The calculation to configure. - /// false when the has a - /// set which is not available in , true otherwise. - private bool TryReadHydraulicBoundaryLocation(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + private bool TryReadHydraulicBoundaryLocation(string locationName, StructuresCalculation calculation) { - if (readCalculation.HydraulicBoundaryLocationName != null) - { - HydraulicBoundaryLocation location = availableHydraulicBoundaryLocations - .FirstOrDefault(l => l.Name == readCalculation.HydraulicBoundaryLocationName); + HydraulicBoundaryLocation location; - if (location == null) - { - LogReadCalculationConversionError( - string.Format( - RingtoetsCommonIOResources.CalculationConfigurationImporter_ReadHydraulicBoundaryLocation_HydraulicBoundaryLocation_0_does_not_exist, - readCalculation.HydraulicBoundaryLocationName), - calculation.Name); - - return false; - } - + if (TryReadHydraulicBoundaryLocation(locationName, calculation.Name, availableHydraulicBoundaryLocations, out location)) + { calculation.InputParameters.HydraulicBoundaryLocation = location; + return true; } - return true; + return false; } - /// - /// Reads the hydraulic boundary location. - /// - /// The calculation read from the imported file. - /// The calculation to configure. - /// false when the has a - /// set which is not available in , true otherwise. - private bool TryReadStructure(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + private bool TryReadStructure(string structureName, StructuresCalculation calculation) { - if (readCalculation.StructureName != null) - { - HeightStructure structure = availableStructures - .FirstOrDefault(l => l.Name == readCalculation.StructureName); + HeightStructure structure; - if (structure == null) - { - LogReadCalculationConversionError( - string.Format( - RingtoetsCommonIOResources.CalculationConfigurationImporter_ReadStructure_Structure_0_does_not_exist, - readCalculation.StructureName), - calculation.Name); - - return false; - } - + if (TryReadStructure(structureName, calculation.Name, availableStructures, out structure)) + { calculation.InputParameters.Structure = structure; + return true; } - return true; + return false; } - /// - /// Reads the dike profile. - /// - /// The calculation read from the imported file. - /// The calculation to configure. - /// false when the has a - /// set which is not available in , true otherwise. - private bool TryReadDikeProfile(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + private bool TryReadForeshoreProfile(string foreshoreProfileName, StructuresCalculation calculation) { - if (readCalculation.ForeshoreProfileName != null) - { - ForeshoreProfile foreshoreProfile = availableForeshoreProfiles.FirstOrDefault(fp => fp.Name == readCalculation.ForeshoreProfileName); + ForeshoreProfile foreshoreProfile; - if (foreshoreProfile == null) - { - LogReadCalculationConversionError( - string.Format( - RingtoetsCommonIOResources.CalculationConfigurationImporter_ReadForeshoreProfile_ForeshoreProfile_0_does_not_exist, - readCalculation.ForeshoreProfileName), - calculation.Name); - - return false; - } - + if (TryReadForeshoreProfile(foreshoreProfileName, calculation.Name, availableForeshoreProfiles, out foreshoreProfile)) + { calculation.InputParameters.ForeshoreProfile = foreshoreProfile; + return true; } - return true; + return false; } /// /// Reads the wave reduction parameters. /// - /// The calculation read from the imported file. + /// /// The calculation to configure. /// false when there is an invalid wave reduction parameter defined, true otherwise. - private bool TryReadWaveReduction(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) + private bool TryReadWaveReduction(WaveReductionConfiguration waveReduction, StructuresCalculation calculation) { - if (!ValidateWaveReduction(readCalculation, calculation)) + if (!ValidateWaveReduction(waveReduction, calculation.InputParameters.ForeshoreProfile, calculation.Name)) { return false; } - WaveReductionConfiguration waveReduction = readCalculation.WaveReduction; - if (waveReduction == null) + if (waveReduction != null) { - return true; - } + if (waveReduction.UseForeshoreProfile.HasValue) + { + calculation.InputParameters.UseForeshore = waveReduction.UseForeshoreProfile.Value; + } - if (waveReduction.UseForeshoreProfile.HasValue) - { - calculation.InputParameters.UseForeshore = waveReduction.UseForeshoreProfile.Value; - } - - if (waveReduction.UseBreakWater.HasValue) - { - calculation.InputParameters.UseBreakWater = waveReduction.UseBreakWater.Value; - } - - if (waveReduction.BreakWaterType.HasValue) - { - calculation.InputParameters.BreakWater.Type = (BreakWaterType) new ConfigurationBreakWaterTypeConverter().ConvertTo(waveReduction.BreakWaterType.Value, typeof(BreakWaterType)); - } - - if (waveReduction.BreakWaterHeight.HasValue) - { - calculation.InputParameters.BreakWater.Height = (RoundedDouble) waveReduction.BreakWaterHeight.Value; - } - - return true; - } - - /// - /// Validation to check if the defined wave reduction parameters are valid. - /// - /// The calculation read from the imported file. - /// The calculation to configure. - /// false when there is an invalid wave reduction parameter defined, true otherwise. - private bool ValidateWaveReduction(StructuresCalculationConfiguration readCalculation, StructuresCalculation calculation) - { - if (calculation.InputParameters.ForeshoreProfile == null) - { - if (readCalculation.WaveReduction != null - && (readCalculation.WaveReduction.UseBreakWater.HasValue - || readCalculation.WaveReduction.UseForeshoreProfile.HasValue - || readCalculation.WaveReduction.BreakWaterHeight.HasValue - || readCalculation.WaveReduction.BreakWaterType.HasValue)) + if (waveReduction.UseBreakWater.HasValue) { - LogReadCalculationConversionError( - RingtoetsCommonIOResources.CalculationConfigurationImporter_ValidateWaveReduction_No_foreshore_profile_provided, - calculation.Name); + calculation.InputParameters.UseBreakWater = waveReduction.UseBreakWater.Value; + } - return false; + if (waveReduction.BreakWaterType.HasValue) + { + calculation.InputParameters.BreakWater.Type = (BreakWaterType) new ConfigurationBreakWaterTypeConverter().ConvertTo(waveReduction.BreakWaterType.Value, typeof(BreakWaterType)); } - } - else if (!calculation.InputParameters.ForeshoreGeometry.Any()) - { - if (readCalculation.WaveReduction.UseForeshoreProfile.HasValue && readCalculation.WaveReduction.UseForeshoreProfile.Value) + + if (waveReduction.BreakWaterHeight.HasValue) { - LogReadCalculationConversionError( - string.Format( - RingtoetsCommonIOResources.ReadForeshoreProfile_ForeshoreProfile_0_has_no_geometry_and_cannot_be_used, - readCalculation.ForeshoreProfileName), - calculation.Name); - return false; + calculation.InputParameters.BreakWater.Height = (RoundedDouble) waveReduction.BreakWaterHeight.Value; } } + return true; } }