// 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;
}
}
}