Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateData.cs =================================================================== diff -u -r0970881ada96a68e26a4453b25b3d7b6bd64479d -r4454d09ddf61ff3eeef0432bdb6bbe7cdea12824 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateData.cs (.../StochasticSoilModelUpdateData.cs) (revision 0970881ada96a68e26a4453b25b3d7b6bd64479d) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateData.cs (.../StochasticSoilModelUpdateData.cs) (revision 4454d09ddf61ff3eeef0432bdb6bbe7cdea12824) @@ -23,8 +23,6 @@ using System.Collections.Generic; using System.Linq; using Core.Common.Base; -using log4net; -using Ringtoets.Common.Service; using Ringtoets.Piping.Data; using Ringtoets.Piping.Service; @@ -35,7 +33,6 @@ /// public class StochasticSoilModelUpdateData : IStochasticSoilModelUpdateStrategy { - private readonly ILog log = LogManager.GetLogger(typeof(StochasticSoilModelUpdateData)); private readonly PipingFailureMechanism failureMechanism; /// @@ -85,37 +82,68 @@ throw new ArgumentNullException(nameof(targetCollection)); } - var removedModels = targetCollection.ToList(); - var updatedOrAddedModels = new List(); - var affectedObjects = new List { targetCollection }; + return ModifyModelCollection(readStochasticSoilModels, targetCollection, sourceFilePath); + } - foreach (var readModel in readStochasticSoilModels) + private IEnumerable ModifyModelCollection(IEnumerable readStochasticSoilModels, StochasticSoilModelCollection targetCollection, string sourceFilePath) + { + var affectedObjects = new List { - var existingModel = targetCollection.SingleOrDefault(existing => existing.Name.Equals(readModel.Name)); - if (existingModel != null) - { - affectedObjects.AddRange(UpdateStochasticSoilModel(existingModel, readModel)); + targetCollection + }; - removedModels.Remove(existingModel); - updatedOrAddedModels.Add(existingModel); - } - else - { - removedModels.Remove(readModel); - updatedOrAddedModels.Add(readModel); - } - } + var readModelList = readStochasticSoilModels.ToList(); + var addedModels = GetAddedReadModels(targetCollection, readModelList).ToList(); + var updatedModels = GetUpdatedExistingModels(targetCollection, readModelList).ToList(); + var removedModels = GetRemovedExistingModels(targetCollection, readModelList).ToList(); + + affectedObjects.AddRange(UpdateModels(updatedModels, readModelList)); + affectedObjects.AddRange(RemoveModels(removedModels)); + + targetCollection.Clear(); + targetCollection.AddRange(addedModels.Union(updatedModels), sourceFilePath); + + return affectedObjects; + } + + private static IEnumerable GetAddedReadModels(IEnumerable existingCollection, IEnumerable readStochasticSoilModels) + { + return readStochasticSoilModels.Except(existingCollection, new SoilModelNameEqualityComparer()); + } + + private static IEnumerable GetUpdatedExistingModels(IEnumerable existingCollection, IEnumerable readStochasticSoilModels) + { + return existingCollection.Intersect(readStochasticSoilModels, new SoilModelNameEqualityComparer()); + } + + private static IEnumerable GetRemovedExistingModels(IEnumerable existingCollection, IEnumerable readStochasticSoilModels) + { + return existingCollection.Except(readStochasticSoilModels, new SoilModelNameEqualityComparer()); + } + + private IEnumerable RemoveModels(IEnumerable removedModels) + { + var affectedObjects = new List(); + foreach (var model in removedModels) { - affectedObjects.AddRange(RemoveStochasticSoilModel(model)); + affectedObjects.AddRange(ClearStochasticSoilModelDependentData(model)); } - targetCollection.Clear(); - targetCollection.AddRange(updatedOrAddedModels, sourceFilePath); + return affectedObjects; + } + private IEnumerable UpdateModels(IList updatedModels, IList readModels) + { + var affectedObjects = new List(); + foreach (StochasticSoilModel updatedModel in updatedModels) + { + StochasticSoilModel readModel = readModels.Single(r => r.Name.Equals(updatedModel.Name)); + affectedObjects.AddRange(UpdateStochasticSoilModel(updatedModel, readModel)); + } return affectedObjects; } - private IEnumerable RemoveStochasticSoilModel(StochasticSoilModel removedModel) + private IEnumerable ClearStochasticSoilModelDependentData(StochasticSoilModel removedModel) { return PipingDataSynchronizationService.RemoveStochasticSoilModel(failureMechanism, removedModel); } @@ -131,16 +159,25 @@ } foreach (StochasticSoilProfile updatedProfile in difference.UpdatedProfiles) { - IEnumerable pipingInputs = failureMechanism.Calculations - .Cast() - .Where(c => ReferenceEquals(c.InputParameters.StochasticSoilProfile, updatedProfile)); - foreach (PipingCalculation calculation in pipingInputs) - { - affectedObjects.AddRange(RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(calculation)); - affectedObjects.Add(calculation.InputParameters); - } + affectedObjects.AddRange(PipingDataSynchronizationService.UpdateStochasticSoilProfileForInput(failureMechanism, updatedProfile)); } return affectedObjects; } + + /// + /// Class for comparing by just the name. + /// + private class SoilModelNameEqualityComparer : IEqualityComparer + { + public bool Equals(StochasticSoilModel x, StochasticSoilModel y) + { + return x.Name == y.Name; + } + + public int GetHashCode(StochasticSoilModel obj) + { + return obj.Name.GetHashCode(); + } + } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingDataSynchronizationService.cs =================================================================== diff -u -r89d34600d1408c8b1f4240020e841ba64cc26622 -r4454d09ddf61ff3eeef0432bdb6bbe7cdea12824 --- Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingDataSynchronizationService.cs (.../PipingDataSynchronizationService.cs) (revision 89d34600d1408c8b1f4240020e841ba64cc26622) +++ Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingDataSynchronizationService.cs (.../PipingDataSynchronizationService.cs) (revision 4454d09ddf61ff3eeef0432bdb6bbe7cdea12824) @@ -243,12 +243,7 @@ var changedObservables = new List(); - IEnumerable pipingCalculationScenarios = - failureMechanism.Calculations - .Cast() - .Where(pcs => ReferenceEquals(pcs.InputParameters.StochasticSoilProfile, soilProfile)); - - foreach (PipingCalculation pipingCalculationScenario in pipingCalculationScenarios) + foreach (PipingCalculation pipingCalculationScenario in GetCalculationsWithSoilProfileAssigned(failureMechanism, soilProfile)) { changedObservables.AddRange(RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(pipingCalculationScenario)); changedObservables.AddRange(ClearStochasticSoilProfile(pipingCalculationScenario.InputParameters)); @@ -257,6 +252,47 @@ return changedObservables; } + /// + /// Clears data dependent on a given , either directly or indirectly, + /// from calculations in the . + /// + /// The failure mechanism containing . + /// The soil profile residing in + /// that should be removed. + /// All observable objects affected by this method. + /// Thrown when + /// or is null. + public static IEnumerable UpdateStochasticSoilProfileForInput(PipingFailureMechanism failureMechanism, StochasticSoilProfile soilProfile) + { + if (failureMechanism == null) + { + throw new ArgumentNullException(nameof(failureMechanism)); + } + if (soilProfile == null) + { + throw new ArgumentNullException(nameof(soilProfile)); + } + + var changedObservables = new List(); + + foreach (PipingCalculation calculation in GetCalculationsWithSoilProfileAssigned(failureMechanism, soilProfile)) + { + changedObservables.AddRange(RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(calculation)); + changedObservables.Add(calculation.InputParameters); + } + + return changedObservables; + } + + private static IEnumerable GetCalculationsWithSoilProfileAssigned(PipingFailureMechanism failureMechanism, StochasticSoilProfile soilProfile) + { + IEnumerable pipingCalculationScenarios = + failureMechanism.Calculations + .Cast() + .Where(pcs => ReferenceEquals(pcs.InputParameters.StochasticSoilProfile, soilProfile)); + return pipingCalculationScenarios; + } + private static IEnumerable ClearSurfaceLine(PipingInput input) { input.SurfaceLine = null; Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs =================================================================== diff -u -r0970881ada96a68e26a4453b25b3d7b6bd64479d -r4454d09ddf61ff3eeef0432bdb6bbe7cdea12824 --- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs (.../StochasticSoilModelUpdateDataTest.cs) (revision 0970881ada96a68e26a4453b25b3d7b6bd64479d) +++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs (.../StochasticSoilModelUpdateDataTest.cs) (revision 4454d09ddf61ff3eeef0432bdb6bbe7cdea12824) @@ -101,21 +101,21 @@ } [Test] - public void UpdateModelWithImportedData_CurrentModelsWithSameNameAndImportedModelWithSameName_ThrowsInvalidOperationException() + public void UpdateModelWithImportedData_WithCurrentModelsAndImportedMultipleModelsWithSameName_ThrowsInvalidOperationException() { // Setup var nonUniqueName = "non-unique name"; var targetCollection = new StochasticSoilModelCollection(); targetCollection.AddRange(new[] { - new TestStochasticSoilModel(nonUniqueName), new TestStochasticSoilModel(nonUniqueName) }, sourceFilePath); var strategy = new StochasticSoilModelUpdateData(new PipingFailureMechanism()); var importedStochasticSoilModels = new[] { + new TestStochasticSoilModel(nonUniqueName), new TestStochasticSoilModel(nonUniqueName) }; @@ -132,8 +132,8 @@ // Setup var importedStochasticSoilModels = new[] { - new TestStochasticSoilModel(), - new TestStochasticSoilModel() + new TestStochasticSoilModel("A"), + new TestStochasticSoilModel("B") }; var strategy = new StochasticSoilModelUpdateData(new PipingFailureMechanism()); var targetCollection = new StochasticSoilModelCollection();