// 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.Globalization; using System.Linq; using Core.Common.Base.Data; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Data.DikeProfiles; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.IO; using Ringtoets.Common.IO.Exceptions; using Ringtoets.Common.IO.FileImporters; using Ringtoets.Revetment.Data; using Ringtoets.Revetment.IO.Properties; using Ringtoets.Revetment.IO.Readers; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.Revetment.IO.Importers { /// /// Imports a wave conditions calculation configuration from an XML file and stores it on a /// . /// /// The type of the calculation to import. public class WaveConditionsCalculationConfigurationImporter : CalculationConfigurationImporter where T : IWaveConditionsCalculation, new() { private readonly IEnumerable hydraulicBoundaryLocations; private readonly IEnumerable foreshoreProfiles; /// /// Creates a new instance of . /// /// The path to the XML file to import from. /// The calculation group to update. /// The hydraulic boundary locations /// used to check if the imported objects contain the right location. /// The foreshore profiles used to check if /// the imported objects contain the right profile. /// Thrown when any parameter is /// null. public WaveConditionsCalculationConfigurationImporter(string xmlFilePath, CalculationGroup importTarget, IEnumerable hydraulicBoundaryLocations, IEnumerable foreshoreProfiles) : base(xmlFilePath, importTarget) { if (hydraulicBoundaryLocations == null) { throw new ArgumentNullException(nameof(hydraulicBoundaryLocations)); } if (foreshoreProfiles == null) { throw new ArgumentNullException(nameof(foreshoreProfiles)); } this.hydraulicBoundaryLocations = hydraulicBoundaryLocations; this.foreshoreProfiles = foreshoreProfiles; } protected override WaveConditionsCalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath) { return new WaveConditionsCalculationConfigurationReader(xmlFilePath); } protected override ICalculation ParseReadCalculation(ReadWaveConditionsCalculation readCalculation) { var waveConditionsCalculation = new T { Name = readCalculation.Name }; ReadHydraulicBoundaryLocation(readCalculation, waveConditionsCalculation); ReadBoundaries(readCalculation, waveConditionsCalculation); ReadStepSize(readCalculation, waveConditionsCalculation); ReadForeshoreProfile(readCalculation, waveConditionsCalculation); ReadOrientation(readCalculation, waveConditionsCalculation); ReadWaveReduction(readCalculation, waveConditionsCalculation); return waveConditionsCalculation; } /// /// Reads the hydraulic boundary location. /// /// The calculation read from the imported file. /// The calculation to configure. /// Thrown when the /// has a set which is not available in . private void ReadHydraulicBoundaryLocation(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { if (readCalculation.HydraulicBoundaryLocation != null) { HydraulicBoundaryLocation location = hydraulicBoundaryLocations .FirstOrDefault(l => l.Name == readCalculation.HydraulicBoundaryLocation); if (location == null) { throw new CriticalFileValidationException(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_ReadHydraulicBoundaryLocation_Hydraulic_boundary_location_0_does_not_exist, readCalculation.HydraulicBoundaryLocation)); } calculation.InputParameters.HydraulicBoundaryLocation = location; } } /// /// Reads the entry point and exit point. /// /// The calculation read from the imported file. /// The calculation to configure. /// Thrown when one of the boundaries is invalid. private static void ReadBoundaries(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { if (readCalculation.UpperBoundaryRevetment.HasValue) { var upperBoundaryRevetment = (double) readCalculation.UpperBoundaryRevetment; PerformActionHandlingAnyArgumentOutOfRangeException( () => calculation.InputParameters.UpperBoundaryRevetment = (RoundedDouble) upperBoundaryRevetment, string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ReadBoundaries_Upper_boundary_revetment_0_invalid, upperBoundaryRevetment)); } if (readCalculation.LowerBoundaryRevetment.HasValue) { var lowerBoundaryRevetment = (double) readCalculation.LowerBoundaryRevetment; PerformActionHandlingAnyArgumentOutOfRangeException( () => calculation.InputParameters.LowerBoundaryRevetment = (RoundedDouble) lowerBoundaryRevetment, string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ReadBoundaries_Lower_boundary_revetment_0_invalid, lowerBoundaryRevetment)); } if (readCalculation.UpperBoundaryWaterLevels.HasValue) { var upperBoundaryWaterLevels = (double) readCalculation.UpperBoundaryWaterLevels; PerformActionHandlingAnyArgumentOutOfRangeException( () => calculation.InputParameters.UpperBoundaryWaterLevels = (RoundedDouble) upperBoundaryWaterLevels, string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ReadBoundaries_Upper_boundary_waterlevels_0_invalid, upperBoundaryWaterLevels)); } if (readCalculation.LowerBoundaryWaterLevels.HasValue) { var lowerBoundaryWaterLevels = (double) readCalculation.LowerBoundaryWaterLevels; PerformActionHandlingAnyArgumentOutOfRangeException( () => calculation.InputParameters.LowerBoundaryWaterLevels = (RoundedDouble) lowerBoundaryWaterLevels, string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ReadBoundaries_Lower_boundary_waterlevels_0_invalid, lowerBoundaryWaterLevels)); } } private void ReadStepSize(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { if (readCalculation.StepSize != null) { var stepSize = (double) readCalculation.StepSize; calculation.InputParameters.StepSize = (WaveConditionsInputStepSize) new WaveConditionsInputStepSizeConverter().ConvertFrom(stepSize.ToString("0.0")); } } /// /// Reads the foreshore profile. /// /// The calculation read from the imported file. /// The calculation to configure. /// Thrown when the /// has a set which is not available in . private void ReadForeshoreProfile(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { if (readCalculation.ForeshoreProfile != null) { ForeshoreProfile foreshoreProfile = foreshoreProfiles.FirstOrDefault(fp => fp.Name == readCalculation.ForeshoreProfile); if (foreshoreProfile == null) { throw new CriticalFileValidationException(string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ReadForeshoreProfile_Foreshore_profile_0_does_not_exist, readCalculation.ForeshoreProfile)); } calculation.InputParameters.ForeshoreProfile = foreshoreProfile; } } /// /// Reads the orientation. /// /// The calculation read from the imported file. /// The calculation to configure. /// Thrown when the orientation is invalid. private static void ReadOrientation(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { if (readCalculation.Orientation.HasValue) { var orientation = (double) readCalculation.Orientation; PerformActionHandlingAnyArgumentOutOfRangeException( () => calculation.InputParameters.Orientation = (RoundedDouble) orientation, string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ReadOrientation_Orientation_0_invalid, orientation)); } } /// /// Reads the wave reduction parameters. /// /// The calculation read from the imported file. /// The calculation to configure. /// Thrown when there is an invalid /// wave reduction parameter defined. private static void ReadWaveReduction(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { ValidateWaveReduction(readCalculation, calculation); if (readCalculation.UseForeshore.HasValue) { calculation.InputParameters.UseForeshore = (bool) readCalculation.UseForeshore; } if (readCalculation.UseBreakWater.HasValue) { calculation.InputParameters.UseBreakWater = (bool) readCalculation.UseBreakWater; } if (readCalculation.BreakWaterType != null) { calculation.InputParameters.BreakWater.Type = (BreakWaterType) new BreakWaterTypeConverter().ConvertFrom(readCalculation.BreakWaterType); } if (readCalculation.BreakWaterHeight.HasValue) { calculation.InputParameters.BreakWater.Height = (RoundedDouble) readCalculation.BreakWaterHeight; } } /// /// Validation to check if the defined wave reduction parameters are valid. /// /// The calculation read from the imported file. /// The calculation to configure. /// Thrown when there is an /// invalid wave reduction parameter defined. private static void ValidateWaveReduction(ReadWaveConditionsCalculation readCalculation, IWaveConditionsCalculation calculation) { if (calculation.InputParameters.ForeshoreProfile == null) { if (readCalculation.UseBreakWater.HasValue || readCalculation.UseForeshore.HasValue || readCalculation.BreakWaterHeight != null || readCalculation.BreakWaterType != null) { throw new CriticalFileValidationException(Resources.WaveConditionsCalculationConfigurationImporter_ValidateWaveReduction_No_foreshore_profile_provided); } } else if (!calculation.InputParameters.ForeshoreGeometry.Any()) { if (readCalculation.UseForeshore.HasValue) { throw new CriticalFileValidationException(string.Format(Resources.WaveConditionsCalculationConfigurationImporter_ValidateWaveReduction_Foreshore_profile_0_has_no_geometry_and_cannot_be_used, readCalculation.ForeshoreProfile)); } } } } }