// 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.Data;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.DikeProfiles;
using Ringtoets.Common.Data.Hydraulics;
using Ringtoets.Common.Data.Structures;
using Ringtoets.Common.IO.Configurations;
using Ringtoets.Common.IO.Configurations.Helpers;
using Ringtoets.Common.IO.Configurations.Import;
using Ringtoets.StabilityPointStructures.Data;
using Ringtoets.StabilityPointStructures.IO.Configurations.Helpers;
using Ringtoets.StabilityPointStructures.IO.Properties;
using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources;
namespace Ringtoets.StabilityPointStructures.IO.Configurations
{
///
/// Class for importing a configuration of
/// from an XML file and storing it on a .
///
public class StabilityPointStructuresCalculationConfigurationImporter
: CalculationConfigurationImporter<
StabilityPointStructuresCalculationConfigurationReader,
StabilityPointStructuresCalculationConfiguration>
{
private readonly IEnumerable availableHydraulicBoundaryLocations;
private readonly IEnumerable availableForeshoreProfiles;
private readonly IEnumerable availableStructures;
///
/// Create 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 foreshore profile.
/// The structures used to check if
/// the imported objects contain the right structure.
/// Thrown when any input parameter is null.
public StabilityPointStructuresCalculationConfigurationImporter(
string xmlFilePath,
CalculationGroup importTarget,
IEnumerable hydraulicBoundaryLocations,
IEnumerable foreshoreProfiles,
IEnumerable structures)
: base(xmlFilePath, importTarget)
{
if (hydraulicBoundaryLocations == null)
{
throw new ArgumentNullException(nameof(hydraulicBoundaryLocations));
}
if (foreshoreProfiles == null)
{
throw new ArgumentNullException(nameof(foreshoreProfiles));
}
if (structures == null)
{
throw new ArgumentNullException(nameof(structures));
}
availableHydraulicBoundaryLocations = hydraulicBoundaryLocations;
availableForeshoreProfiles = foreshoreProfiles;
availableStructures = structures;
}
protected override StabilityPointStructuresCalculationConfigurationReader CreateCalculationConfigurationReader(
string xmlFilePath)
{
return new StabilityPointStructuresCalculationConfigurationReader(xmlFilePath);
}
protected override ICalculation ParseReadCalculation(StabilityPointStructuresCalculationConfiguration readCalculation)
{
var calculation = new StructuresCalculation
{
Name = readCalculation.Name
};
if (TrySetStructure(readCalculation.StructureName, calculation)
&& TrySetHydraulicBoundaryLocation(readCalculation.HydraulicBoundaryLocationName, calculation)
&& TrySetForeshoreProfile(readCalculation.ForeshoreProfileName, calculation)
&& TrySetEvaluationLevel(readCalculation, calculation)
&& TrySetFailureProbabilityRepairClosure(readCalculation, calculation)
&& TrySetFailureProbabilityStructureWithErosion(readCalculation, calculation)
&& TrySetInflowModelType(readCalculation, calculation)
&& TrySetLevellingCount(readCalculation, calculation)
&& TrySetLoadSchematizationType(readCalculation, calculation)
&& TrySetProbabilityCollisionSecondaryStructure(readCalculation, calculation)
&& TrySetStochasts(readCalculation, calculation)
&& TrySetStructureNormalOrientation(readCalculation, calculation)
&& TrySetVerticalDistance(readCalculation, calculation)
&& readCalculation.WaveReduction.ValidateWaveReduction(calculation.InputParameters.ForeshoreProfile, calculation.Name, Log))
{
SetFactorStormDurationOpenStructure(readCalculation, calculation);
SetVolumicWeightWater(readCalculation, calculation);
SetWaveReductionParameters(readCalculation.WaveReduction, calculation.InputParameters);
return calculation;
}
return null;
}
///
/// Sets the evaluation level.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the evaluation level is invalid or when there is an
/// evaluation level but no structure defined, true otherwise.
private bool TrySetEvaluationLevel(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.EvaluationLevel.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
Resources.CalculationConfigurationImporter_EvaluationLevel_DisplayName),
calculation.Name);
return false;
}
calculation.InputParameters.EvaluationLevel = (RoundedDouble) readCalculation.EvaluationLevel.Value;
}
return true;
}
private bool TrySetStochasts(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
var assigner = new StabilityPointStructuresCalculationStochastAssigner(
readCalculation,
calculation);
return assigner.Assign();
}
///
/// Sets the structure normal orientation.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the structure normal orientation is invalid or when there
/// is a structure normal orientation but no structure defined, true otherwise.
private bool TrySetStructureNormalOrientation(StructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.StructureNormalOrientation.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
RingtoetsCommonIOResources.CalculationConfigurationImporter_Orientation_DisplayName),
calculation.Name);
return false;
}
double orientation = readCalculation.StructureNormalOrientation.Value;
try
{
calculation.InputParameters.StructureNormalOrientation = (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;
}
///
/// Sets the failure probability repair closure.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the failure probability repair closure is invalid or when there
/// is a failure probability repair closure but no structure defined, true otherwise.
private bool TrySetFailureProbabilityRepairClosure(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (!readCalculation.FailureProbabilityRepairClosure.HasValue)
{
return true;
}
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
Resources.CalculationConfigurationImporter_FailureProbabilityRepairClosure_DisplayName),
calculation.Name);
return false;
}
double failureProbabilityRepairClosure = readCalculation.FailureProbabilityRepairClosure.Value;
try
{
calculation.InputParameters.FailureProbabilityRepairClosure = (RoundedDouble) failureProbabilityRepairClosure;
}
catch (ArgumentOutOfRangeException e)
{
Log.LogOutOfRangeException(string.Format(RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid,
failureProbabilityRepairClosure,
Resources.CalculationConfigurationImporter_FailureProbabilityRepairClosure_DisplayName),
calculation.Name,
e);
return false;
}
return true;
}
///
/// Sets the failure probability structure with erosion.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the orientation is invalid or when there is a failure probability
/// structure with erosion but no structure defined, true otherwise.
private bool TrySetFailureProbabilityStructureWithErosion(StructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.FailureProbabilityStructureWithErosion.HasValue)
{
double failureProbability = readCalculation.FailureProbabilityStructureWithErosion.Value;
try
{
calculation.InputParameters.FailureProbabilityStructureWithErosion = (RoundedDouble) failureProbability;
}
catch (ArgumentOutOfRangeException e)
{
Log.LogOutOfRangeException(string.Format(
RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid,
failureProbability,
RingtoetsCommonIOResources.CalculationConfigurationImporter_FailureProbabilityStructureWithErosion_DisplayName),
calculation.Name,
e);
return false;
}
}
return true;
}
///
/// Sets the probability collision secondary structure.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the probability collision secondary structure is invalid or
/// when there is a probability collision secondary structure but no structure defined,
/// true otherwise.
private bool TrySetProbabilityCollisionSecondaryStructure(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.ProbabilityCollisionSecondaryStructure.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
Resources.CalculationConfigurationImporter_ProbabilityCollisionSecondaryStructure_DisplayName),
calculation.Name);
return false;
}
double failureProbability = readCalculation.ProbabilityCollisionSecondaryStructure.Value;
try
{
calculation.InputParameters.ProbabilityCollisionSecondaryStructure = (RoundedDouble) failureProbability;
}
catch (ArgumentOutOfRangeException e)
{
Log.LogOutOfRangeException(string.Format(
RingtoetsCommonIOResources.TryReadParameter_Value_0_ParameterName_1_is_invalid,
failureProbability,
Resources.CalculationConfigurationImporter_ProbabilityCollisionSecondaryStructure_DisplayName),
calculation.Name,
e);
return false;
}
}
return true;
}
///
/// Sets the factor storm duration open structure.
///
/// The calculation read from the imported file.
/// The calculation to configure.
private void SetFactorStormDurationOpenStructure(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.FactorStormDurationOpenStructure.HasValue)
{
calculation.InputParameters.FactorStormDurationOpenStructure = (RoundedDouble) readCalculation.FactorStormDurationOpenStructure.Value;
}
}
///
/// Sets the volumic weight water.
///
/// The calculation read from the imported file.
/// The calculation to configure.
private void SetVolumicWeightWater(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.VolumicWeightWater.HasValue)
{
calculation.InputParameters.VolumicWeightWater = (RoundedDouble) readCalculation.VolumicWeightWater.Value;
}
}
///
/// Sets the inflow model type.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the inflow model type is invalid or when there is a
/// inflow model type but no structure defined, true otherwise.
private bool TrySetInflowModelType(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.InflowModelType.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
RingtoetsCommonIOResources.CalculationConfigurationImporter_InflowModelType_DisplayName),
calculation.Name);
return false;
}
calculation.InputParameters.InflowModelType = (StabilityPointStructureInflowModelType)
new ConfigurationStabilityPointStructuresInflowModelTypeConverter()
.ConvertTo(readCalculation.InflowModelType.Value, typeof(StabilityPointStructureInflowModelType));
}
return true;
}
///
/// Sets the load schematization type.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the load schematization type is invalid or when there is a
/// load schematization type but no structure defined, true otherwise.
private bool TrySetLoadSchematizationType(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.LoadSchematizationType.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
Resources.CalculationConfigurationImporter_LoadSchematizationType_DisplayName),
calculation.Name);
return false;
}
calculation.InputParameters.LoadSchematizationType = (LoadSchematizationType)
new ConfigurationStabilityPointStructuresLoadSchematizationTypeConverter()
.ConvertTo(readCalculation.LoadSchematizationType.Value, typeof(LoadSchematizationType));
}
return true;
}
///
/// Sets the levelling count.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the levelling count is invalid or when there is a
/// levelling count but no structure defined, true otherwise.
private bool TrySetLevellingCount(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.LevellingCount.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
Resources.CalculationConfigurationImporter_LevellingCount_DisplayName),
calculation.Name);
return false;
}
calculation.InputParameters.LevellingCount = readCalculation.LevellingCount.Value;
}
return true;
}
///
/// Sets the vertical distance.
///
/// The calculation read from the imported file.
/// The calculation to configure.
/// false when the vertical distance is invalid or when there is a
/// vertical distance but no structure defined, true otherwise.
private bool TrySetVerticalDistance(StabilityPointStructuresCalculationConfiguration readCalculation,
StructuresCalculation calculation)
{
if (readCalculation.VerticalDistance.HasValue)
{
if (calculation.InputParameters.Structure == null)
{
Log.LogCalculationConversionError(string.Format(RingtoetsCommonIOResources.CalculationConfigurationImporter_TryParameter_No_Structure_to_assign_Parameter_0_,
Resources.CalculationConfigurationImporter_VerticalDistance_DisplayName),
calculation.Name);
return false;
}
calculation.InputParameters.VerticalDistance = (RoundedDouble) readCalculation.VerticalDistance.Value;
}
return true;
}
private bool TrySetHydraulicBoundaryLocation(string locationName, StructuresCalculation calculation)
{
HydraulicBoundaryLocation location;
if (TryReadHydraulicBoundaryLocation(locationName, calculation.Name, availableHydraulicBoundaryLocations, out location))
{
calculation.InputParameters.HydraulicBoundaryLocation = location;
return true;
}
return false;
}
private bool TrySetStructure(string structureName, StructuresCalculation calculation)
{
StabilityPointStructure structure;
if (TryReadStructure(structureName, calculation.Name, availableStructures, out structure))
{
calculation.InputParameters.Structure = structure;
return true;
}
return false;
}
private bool TrySetForeshoreProfile(string foreshoreProfileName, StructuresCalculation calculation)
{
ForeshoreProfile foreshoreProfile;
if (TryReadForeshoreProfile(foreshoreProfileName, calculation.Name, availableForeshoreProfiles, out foreshoreProfile))
{
calculation.InputParameters.ForeshoreProfile = foreshoreProfile;
return true;
}
return false;
}
}
}