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