// Copyright (C) Stichting Deltares 2017. 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.Data; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Data.DikeProfiles; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.IO.Configurations.Helpers; using Ringtoets.Common.IO.Configurations.Import; using Ringtoets.Revetment.Data; using Ringtoets.Revetment.IO.Properties; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.Revetment.IO.Configurations { /// /// 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 : ICalculation, new() { private readonly IEnumerable availableHydraulicBoundaryLocations; private readonly IEnumerable availableForeshoreProfiles; /// /// 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)); } availableHydraulicBoundaryLocations = hydraulicBoundaryLocations; availableForeshoreProfiles = foreshoreProfiles; } protected override AssessmentSectionCategoryWaveConditionsCalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath) { return new AssessmentSectionCategoryWaveConditionsCalculationConfigurationReader(xmlFilePath); } protected override ICalculation ParseReadCalculation(AssessmentSectionCategoryWaveConditionsCalculationConfiguration calculationConfiguration) { var waveConditionsCalculation = new T { Name = calculationConfiguration.Name }; SetStepSize(calculationConfiguration, waveConditionsCalculation); if (TrySetHydraulicBoundaryLocation(calculationConfiguration.HydraulicBoundaryLocationName, waveConditionsCalculation) && TrySetBoundaries(calculationConfiguration, waveConditionsCalculation) && TrySetForeshoreProfile(calculationConfiguration.ForeshoreProfileId, waveConditionsCalculation) && TrySetOrientation(calculationConfiguration, waveConditionsCalculation) && calculationConfiguration.WaveReduction.ValidateWaveReduction(waveConditionsCalculation.InputParameters.ForeshoreProfile, waveConditionsCalculation.Name, Log)) { SetWaveReductionParameters(calculationConfiguration.WaveReduction, waveConditionsCalculation.InputParameters); return waveConditionsCalculation; } return null; } /// /// Assigns the boundaries of the calculation. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when one of the boundaries is invalid, true otherwise. private bool TrySetBoundaries(WaveConditionsCalculationConfiguration calculationConfiguration, ICalculation calculation) { WaveConditionsInput input = calculation.InputParameters; return TryReadParameter(calculationConfiguration.UpperBoundaryRevetment, v => input.UpperBoundaryRevetment = v, Resources.WaveConditionsCalculationConfigurationImporter_UpperBoundaryRevetment_DisplayName, calculation.Name) && TryReadParameter(calculationConfiguration.LowerBoundaryRevetment, v => input.LowerBoundaryRevetment = v, Resources.WaveConditionsCalculationConfigurationImporter_LowerBoundaryRevetment_DisplayName, calculation.Name) && TryReadParameter(calculationConfiguration.UpperBoundaryWaterLevels, v => input.UpperBoundaryWaterLevels = v, Resources.WaveConditionsCalculationConfigurationImporter_UpperBoundaryWaterLevels_DisplayName, calculation.Name) && TryReadParameter(calculationConfiguration.LowerBoundaryWaterLevels, v => input.LowerBoundaryWaterLevels = v, Resources.WaveConditionsCalculationConfigurationImporter_LowerBoundaryWaterLevels_DisplayName, calculation.Name); } private bool TryReadParameter(double? readValue, Action setAsRoundedDouble, string parameterName, string calculationName) { if (readValue.HasValue) { try { setAsRoundedDouble((RoundedDouble) readValue.Value); } catch (ArgumentOutOfRangeException e) { Log.LogOutOfRangeException(string.Format( RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, readValue.Value, parameterName), calculationName, e); return false; } } return true; } private static void SetStepSize(WaveConditionsCalculationConfiguration calculationConfiguration, ICalculation calculation) { if (calculationConfiguration.StepSize.HasValue) { calculation.InputParameters.StepSize = (WaveConditionsInputStepSize) calculationConfiguration.StepSize.Value; } } private bool TrySetHydraulicBoundaryLocation(string locationName, ICalculation calculation) { HydraulicBoundaryLocation location; if (TryReadHydraulicBoundaryLocation(locationName, calculation.Name, availableHydraulicBoundaryLocations, out location)) { calculation.InputParameters.HydraulicBoundaryLocation = location; return true; } return false; } private bool TrySetForeshoreProfile(string foreshoreProfileName, ICalculation calculation) { ForeshoreProfile foreshoreProfile; if (TryReadForeshoreProfile(foreshoreProfileName, calculation.Name, availableForeshoreProfiles, out foreshoreProfile)) { calculation.InputParameters.ForeshoreProfile = foreshoreProfile; return true; } return false; } /// /// Assigns the orientation. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the orientation is invalid, true otherwise. private bool TrySetOrientation(WaveConditionsCalculationConfiguration calculationConfiguration, ICalculation calculation) { if (calculationConfiguration.Orientation.HasValue) { double orientation = calculationConfiguration.Orientation.Value; try { calculation.InputParameters.Orientation = (RoundedDouble) orientation; } catch (ArgumentOutOfRangeException e) { Log.LogOutOfRangeException(string.Format( RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid, orientation, RingtoetsCommonIOResources.CalculationConfigurationImporter_Orientation_DisplayName), calculation.Name, e); return false; } } return true; } } }