// 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 System.Linq;
using Core.Common.Base;
using Core.Common.Gui.Commands;
using Core.Common.Util.Extensions;
using log4net;
using Ringtoets.ClosingStructures.Data;
using Ringtoets.Common.Data.AssessmentSection;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.FailureMechanism;
using Ringtoets.Common.Data.Hydraulics;
using Ringtoets.Common.Data.Structures;
using Ringtoets.GrassCoverErosionInwards.Data;
using Ringtoets.GrassCoverErosionOutwards.Data;
using Ringtoets.HeightStructures.Data;
using Ringtoets.Integration.Data;
using Ringtoets.Integration.Data.Merge;
using Ringtoets.Integration.Plugin.Properties;
using Ringtoets.MacroStabilityInwards.Data;
using Ringtoets.Piping.Data;
using Ringtoets.Revetment.Data;
using Ringtoets.StabilityPointStructures.Data;
using Ringtoets.StabilityStoneCover.Data;
using Ringtoets.WaveImpactAsphaltCover.Data;
namespace Ringtoets.Integration.Plugin.Merge
{
///
/// Class responsible for handling the merge of data.
///
public class AssessmentSectionMergeHandler : IAssessmentSectionMergeHandler
{
private static readonly ILog log = LogManager.GetLogger(typeof(AssessmentSectionMergeHandler));
private readonly IViewCommands viewCommands;
///
/// Creates a new instance of .
///
/// The view commands used to close views for the target
/// .
/// Thrown when
/// is null.
public AssessmentSectionMergeHandler(IViewCommands viewCommands)
{
if (viewCommands == null)
{
throw new ArgumentNullException(nameof(viewCommands));
}
this.viewCommands = viewCommands;
}
public void PerformMerge(AssessmentSection targetAssessmentSection, AssessmentSectionMergeData mergeData)
{
if (targetAssessmentSection == null)
{
throw new ArgumentNullException(nameof(targetAssessmentSection));
}
if (mergeData == null)
{
throw new ArgumentNullException(nameof(mergeData));
}
BeforeMerge(targetAssessmentSection);
var changedObjects = new List
{
targetAssessmentSection
};
changedObjects.AddRange(MergeHydraulicBoundaryLocations(targetAssessmentSection, mergeData.AssessmentSection));
MergeFailureMechanisms(targetAssessmentSection, mergeData);
AfterMerge(changedObjects);
}
private void BeforeMerge(AssessmentSection assessmentSection)
{
viewCommands.RemoveAllViewsForItem(assessmentSection);
}
private static void AfterMerge(IEnumerable changedObjects)
{
changedObjects.ForEachElementDo(co => co.NotifyObservers());
}
#region HydraulicBoundaryLocationCalculations
private static IEnumerable MergeHydraulicBoundaryLocations(IAssessmentSection targetAssessmentSection, IAssessmentSection sourceAssessmentSection)
{
var changedObjects = new List();
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaterLevelCalculationsForFactorizedSignalingNorm,
sourceAssessmentSection.WaterLevelCalculationsForFactorizedSignalingNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaterLevelCalculationsForSignalingNorm,
sourceAssessmentSection.WaterLevelCalculationsForSignalingNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaterLevelCalculationsForLowerLimitNorm,
sourceAssessmentSection.WaterLevelCalculationsForLowerLimitNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaterLevelCalculationsForFactorizedLowerLimitNorm,
sourceAssessmentSection.WaterLevelCalculationsForFactorizedLowerLimitNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaveHeightCalculationsForFactorizedSignalingNorm,
sourceAssessmentSection.WaveHeightCalculationsForFactorizedSignalingNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaveHeightCalculationsForSignalingNorm,
sourceAssessmentSection.WaveHeightCalculationsForSignalingNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaveHeightCalculationsForLowerLimitNorm,
sourceAssessmentSection.WaveHeightCalculationsForLowerLimitNorm));
changedObjects.AddRange(MergeHydraulicBoundaryLocationCalculations(targetAssessmentSection.WaveHeightCalculationsForFactorizedLowerLimitNorm,
sourceAssessmentSection.WaveHeightCalculationsForFactorizedLowerLimitNorm));
log.Info(Resources.AssessmentSectionMergeHandler_MergeHydraulicBoundaryLocations_HydraulicBoundaryLocations_merged);
return changedObjects;
}
private static IEnumerable MergeHydraulicBoundaryLocationCalculations(IEnumerable targetCalculations,
IEnumerable sourceCalculations)
{
for (var i = 0; i < targetCalculations.Count(); i++)
{
HydraulicBoundaryLocationCalculation targetCalculation = targetCalculations.ElementAt(i);
HydraulicBoundaryLocationCalculation sourceCalculation = sourceCalculations.ElementAt(i);
if (ShouldMerge(targetCalculation, sourceCalculation))
{
targetCalculation.InputParameters.ShouldIllustrationPointsBeCalculated = sourceCalculation.InputParameters.ShouldIllustrationPointsBeCalculated;
targetCalculation.Output = sourceCalculation.Output;
yield return targetCalculation;
}
}
}
private static bool ShouldMerge(HydraulicBoundaryLocationCalculation targetCalculation, HydraulicBoundaryLocationCalculation sourceCalculation)
{
bool targetCalculationHasOutput = targetCalculation.HasOutput;
bool sourceCalculationHasOutput = sourceCalculation.HasOutput;
if (!targetCalculationHasOutput && !sourceCalculationHasOutput
|| targetCalculationHasOutput && !sourceCalculationHasOutput
|| targetCalculationHasOutput && !targetCalculation.Output.HasGeneralResult && !sourceCalculation.Output.HasGeneralResult
|| targetCalculationHasOutput && targetCalculation.Output.HasGeneralResult && sourceCalculation.Output.HasGeneralResult
|| targetCalculationHasOutput && targetCalculation.Output.HasGeneralResult && !sourceCalculation.Output.HasGeneralResult)
{
return false;
}
return true;
}
#endregion
#region FailureMechanisms
private static void MergeFailureMechanisms(AssessmentSection targetAssessmentSection, AssessmentSectionMergeData mergeData)
{
ObservableList hydraulicBoundaryLocations = targetAssessmentSection.HydraulicBoundaryDatabase.Locations;
AssessmentSection sourceAssessmentSection = mergeData.AssessmentSection;
if (mergeData.MergePiping)
{
targetAssessmentSection.Piping = sourceAssessmentSection.Piping;
UpdateCalculationHydraulicBoundaryLocationReferences(
targetAssessmentSection.Piping, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.Piping);
}
if (mergeData.MergeGrassCoverErosionInwards)
{
targetAssessmentSection.GrassCoverErosionInwards = sourceAssessmentSection.GrassCoverErosionInwards;
UpdateCalculationHydraulicBoundaryLocationReferences(
targetAssessmentSection.GrassCoverErosionInwards, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.GrassCoverErosionInwards);
}
if (mergeData.MergeMacroStabilityInwards)
{
targetAssessmentSection.MacroStabilityInwards = sourceAssessmentSection.MacroStabilityInwards;
UpdateCalculationHydraulicBoundaryLocationReferences(
targetAssessmentSection.MacroStabilityInwards, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.MacroStabilityInwards);
}
if (mergeData.MergeMacroStabilityOutwards)
{
targetAssessmentSection.MacroStabilityOutwards = sourceAssessmentSection.MacroStabilityOutwards;
LogMergeMessage(targetAssessmentSection.MacroStabilityOutwards);
}
if (mergeData.MergeMicrostability)
{
targetAssessmentSection.Microstability = sourceAssessmentSection.Microstability;
LogMergeMessage(targetAssessmentSection.Microstability);
}
if (mergeData.MergeStabilityStoneCover)
{
targetAssessmentSection.StabilityStoneCover = sourceAssessmentSection.StabilityStoneCover;
UpdateCalculationHydraulicBoundaryLocationReferences(
targetAssessmentSection.StabilityStoneCover, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.StabilityStoneCover);
}
if (mergeData.MergeWaveImpactAsphaltCover)
{
targetAssessmentSection.WaveImpactAsphaltCover = sourceAssessmentSection.WaveImpactAsphaltCover;
UpdateCalculationHydraulicBoundaryLocationReferences(
targetAssessmentSection.WaveImpactAsphaltCover, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.WaveImpactAsphaltCover);
}
if (mergeData.MergeWaterPressureAsphaltCover)
{
targetAssessmentSection.WaterPressureAsphaltCover = sourceAssessmentSection.WaterPressureAsphaltCover;
LogMergeMessage(targetAssessmentSection.WaterPressureAsphaltCover);
}
if (mergeData.MergeGrassCoverErosionOutwards)
{
targetAssessmentSection.GrassCoverErosionOutwards = sourceAssessmentSection.GrassCoverErosionOutwards;
UpdateLocationCalculationHydraulicBoundaryLocationReferences(targetAssessmentSection.GrassCoverErosionOutwards, hydraulicBoundaryLocations);
UpdateCalculationHydraulicBoundaryLocationReferences(
targetAssessmentSection.GrassCoverErosionOutwards, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.GrassCoverErosionOutwards);
}
if (mergeData.MergeGrassCoverSlipOffOutwards)
{
targetAssessmentSection.GrassCoverSlipOffOutwards = sourceAssessmentSection.GrassCoverSlipOffOutwards;
LogMergeMessage(targetAssessmentSection.GrassCoverSlipOffOutwards);
}
if (mergeData.MergeGrassCoverSlipOffInwards)
{
targetAssessmentSection.GrassCoverSlipOffInwards = sourceAssessmentSection.GrassCoverSlipOffInwards;
LogMergeMessage(targetAssessmentSection.GrassCoverSlipOffInwards);
}
if (mergeData.MergeHeightStructures)
{
targetAssessmentSection.HeightStructures = sourceAssessmentSection.HeightStructures;
UpdateCalculationHydraulicBoundaryLocationReferences, HeightStructuresInput>(
targetAssessmentSection.HeightStructures, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.HeightStructures);
}
if (mergeData.MergeClosingStructures)
{
targetAssessmentSection.ClosingStructures = sourceAssessmentSection.ClosingStructures;
UpdateCalculationHydraulicBoundaryLocationReferences, ClosingStructuresInput>(
targetAssessmentSection.ClosingStructures, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.ClosingStructures);
}
if (mergeData.MergePipingStructure)
{
targetAssessmentSection.PipingStructure = sourceAssessmentSection.PipingStructure;
LogMergeMessage(targetAssessmentSection.PipingStructure);
}
if (mergeData.MergeStabilityPointStructures)
{
targetAssessmentSection.StabilityPointStructures = sourceAssessmentSection.StabilityPointStructures;
UpdateCalculationHydraulicBoundaryLocationReferences, StabilityPointStructuresInput>(
targetAssessmentSection.StabilityPointStructures, hydraulicBoundaryLocations);
LogMergeMessage(targetAssessmentSection.StabilityPointStructures);
}
if (mergeData.MergeStrengthStabilityLengthwiseConstruction)
{
targetAssessmentSection.StrengthStabilityLengthwiseConstruction = sourceAssessmentSection.StrengthStabilityLengthwiseConstruction;
LogMergeMessage(targetAssessmentSection.StrengthStabilityLengthwiseConstruction);
}
if (mergeData.MergeDuneErosion)
{
targetAssessmentSection.DuneErosion = sourceAssessmentSection.DuneErosion;
LogMergeMessage(targetAssessmentSection.DuneErosion);
}
if (mergeData.MergeTechnicalInnovation)
{
targetAssessmentSection.TechnicalInnovation = sourceAssessmentSection.TechnicalInnovation;
LogMergeMessage(targetAssessmentSection.TechnicalInnovation);
}
}
private static void LogMergeMessage(IFailureMechanism failureMechanism)
{
log.InfoFormat(Resources.AssessmentSectionMergeHandler_TryMergeFailureMechanism_FailureMechanism_0_replaced, failureMechanism.Name);
}
private static void UpdateCalculationHydraulicBoundaryLocationReferences(
TFailureMechanism failureMechanism, IEnumerable locations)
where TFailureMechanism : IFailureMechanism
where TCalculation : ICalculation
where TCalculationInput : class, ICalculationInputWithHydraulicBoundaryLocation
{
foreach (TCalculation calculation in failureMechanism.Calculations.Cast())
{
if (calculation.InputParameters.HydraulicBoundaryLocation != null)
{
calculation.InputParameters.HydraulicBoundaryLocation = GetHydraulicBoundaryLocation(calculation.InputParameters.HydraulicBoundaryLocation,
locations);
}
}
}
private static HydraulicBoundaryLocation GetHydraulicBoundaryLocation(HydraulicBoundaryLocation location, IEnumerable locations)
{
return locations.Single(l => l.Name == location.Name && l.Id == location.Id && l.Location.Equals(location.Location));
}
private static void UpdateLocationCalculationHydraulicBoundaryLocationReferences(GrassCoverErosionOutwardsFailureMechanism targetFailureMechanism,
IEnumerable locations)
{
HydraulicBoundaryLocationCalculation[] oldWaterLevelForMechanismSpecificFactorizedSignalingNorm = targetFailureMechanism.WaterLevelCalculationsForMechanismSpecificFactorizedSignalingNorm.ToArray();
HydraulicBoundaryLocationCalculation[] oldWaterLevelForMechanismSpecificSignalingNorm = targetFailureMechanism.WaterLevelCalculationsForMechanismSpecificSignalingNorm.ToArray();
HydraulicBoundaryLocationCalculation[] oldWaterLevelForMechanismSpecificLowerLimitNorm = targetFailureMechanism.WaterLevelCalculationsForMechanismSpecificLowerLimitNorm.ToArray();
HydraulicBoundaryLocationCalculation[] oldWaveHeightForMechanismSpecificFactorizedSignalingNorm = targetFailureMechanism.WaveHeightCalculationsForMechanismSpecificFactorizedSignalingNorm.ToArray();
HydraulicBoundaryLocationCalculation[] oldWaveHeightForMechanismSpecificSignalingNorm = targetFailureMechanism.WaveHeightCalculationsForMechanismSpecificSignalingNorm.ToArray();
HydraulicBoundaryLocationCalculation[] oldWaveHeightForMechanismSpecificLowerLimitNorm = targetFailureMechanism.WaveHeightCalculationsForMechanismSpecificLowerLimitNorm.ToArray();
targetFailureMechanism.SetHydraulicBoundaryLocationCalculations(locations);
ReplaceHydraulicBoundaryLocationCalculationData(oldWaterLevelForMechanismSpecificFactorizedSignalingNorm, targetFailureMechanism.WaterLevelCalculationsForMechanismSpecificFactorizedSignalingNorm);
ReplaceHydraulicBoundaryLocationCalculationData(oldWaterLevelForMechanismSpecificSignalingNorm, targetFailureMechanism.WaterLevelCalculationsForMechanismSpecificSignalingNorm);
ReplaceHydraulicBoundaryLocationCalculationData(oldWaterLevelForMechanismSpecificLowerLimitNorm, targetFailureMechanism.WaterLevelCalculationsForMechanismSpecificLowerLimitNorm);
ReplaceHydraulicBoundaryLocationCalculationData(oldWaveHeightForMechanismSpecificFactorizedSignalingNorm, targetFailureMechanism.WaveHeightCalculationsForMechanismSpecificFactorizedSignalingNorm);
ReplaceHydraulicBoundaryLocationCalculationData(oldWaveHeightForMechanismSpecificSignalingNorm, targetFailureMechanism.WaveHeightCalculationsForMechanismSpecificSignalingNorm);
ReplaceHydraulicBoundaryLocationCalculationData(oldWaveHeightForMechanismSpecificLowerLimitNorm, targetFailureMechanism.WaveHeightCalculationsForMechanismSpecificLowerLimitNorm);
}
private static void ReplaceHydraulicBoundaryLocationCalculationData(IEnumerable oldCalculations,
IEnumerable newCalculations)
{
for (var i = 0; i < newCalculations.Count(); i++)
{
HydraulicBoundaryLocationCalculation newCalculation = newCalculations.ElementAt(i);
HydraulicBoundaryLocationCalculation oldCalculation = oldCalculations.ElementAt(i);
newCalculation.InputParameters.ShouldIllustrationPointsBeCalculated = oldCalculation.InputParameters.ShouldIllustrationPointsBeCalculated;
newCalculation.Output = oldCalculation.Output;
}
}
#endregion
}
}