Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelImporter.cs =================================================================== diff -u -r673bf2f4f4de6006444aae3a10183f9442eb0f23 -r0970881ada96a68e26a4453b25b3d7b6bd64479d --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelImporter.cs (.../StochasticSoilModelImporter.cs) (revision 673bf2f4f4de6006444aae3a10183f9442eb0f23) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelImporter.cs (.../StochasticSoilModelImporter.cs) (revision 0970881ada96a68e26a4453b25b3d7b6bd64479d) @@ -64,6 +64,19 @@ this.modelUpdateStrategy = modelUpdateStrategy; } + public override void DoPostImportUpdates() + { + if (Canceled) + { + return; + } + + foreach (var observable in UpdatedInstances) + { + observable.NotifyObservers(); + } + } + protected override bool OnImport() { var importSoilProfileResult = ReadSoilProfiles(); @@ -87,37 +100,20 @@ UpdatedInstances = modelUpdateStrategy.UpdateModelWithImportedData( GetValidStochasticSoilModels(importStochasticSoilModelResult), - FilePath, + FilePath, ImportTarget); return true; } - private IEnumerable UpdatedInstances { get; set; } - - private IEnumerable GetValidStochasticSoilModels(ReadResult importStochasticSoilModelResult) - { - var currentStep = 1; - var importedModels = importStochasticSoilModelResult.ImportedItems.ToArray(); - foreach (var importedModel in importedModels) - { - NotifyProgress(RingtoestCommonIOResources.Importer_ProgressText_Adding_imported_data_to_DataModel, currentStep, importedModels.Length); - if (ValidateStochasticSoilModel(importedModel)) - { - yield return importedModel; - } - currentStep++; - } - } - /// /// Validate the definition of a . /// /// The to validate. /// false when the stochastic soil model does not contain any stochastic soil profiles /// or when a stochastic soil profile does not have a definition for a soil profile; true /// otherwise. - protected bool ValidateStochasticSoilModel(StochasticSoilModel stochasticSoilModel) + private bool ValidateStochasticSoilModel(StochasticSoilModel stochasticSoilModel) { if (!stochasticSoilModel.StochasticSoilProfiles.Any()) { @@ -139,6 +135,28 @@ return true; } + protected override void LogImportCanceledMessage() + { + log.Info(Resources.PipingSoilProfilesImporter_Import_Import_canceled); + } + + private IEnumerable UpdatedInstances { get; set; } + + private IEnumerable GetValidStochasticSoilModels(ReadResult importStochasticSoilModelResult) + { + var currentStep = 1; + var importedModels = importStochasticSoilModelResult.ImportedItems.ToArray(); + foreach (var importedModel in importedModels) + { + NotifyProgress(RingtoestCommonIOResources.Importer_ProgressText_Adding_imported_data_to_DataModel, currentStep, importedModels.Length); + if (ValidateStochasticSoilModel(importedModel)) + { + yield return importedModel; + } + currentStep++; + } + } + private static bool IsSumOfAllProbabilitiesEqualToOne(StochasticSoilModel stochasticSoilModel) { double sumOfAllScenarioProbabilities = stochasticSoilModel.StochasticSoilProfiles @@ -147,11 +165,6 @@ return Math.Abs(sumOfAllScenarioProbabilities - 1.0) < 1e-6; } - protected override void LogImportCanceledMessage() - { - log.Info(Resources.PipingSoilProfilesImporter_Import_Import_canceled); - } - private void AddSoilProfilesToStochasticSoilModels(ICollection soilProfiles, ICollection stochasticSoilModels) { foreach (var stochasticSoilModel in stochasticSoilModels) @@ -183,7 +196,7 @@ private void HandleException(Exception e) { - var message = String.Format(Resources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped, + var message = string.Format(Resources.PipingSoilProfilesImporter_CriticalErrorMessage_0_File_Skipped, e.Message); log.Error(message); } @@ -226,7 +239,7 @@ } catch (StochasticSoilProfileReadException e) { - var message = String.Format(Resources.PipingSoilProfilesImporter_GetStochasticSoilModelReadResult_Error_0_stochastic_soil_model_skipped, e.Message); + var message = string.Format(Resources.PipingSoilProfilesImporter_GetStochasticSoilModelReadResult_Error_0_stochastic_soil_model_skipped, e.Message); log.Error(message); } } @@ -295,18 +308,5 @@ } #endregion - - public override void DoPostImportUpdates() - { - if (Canceled) - { - return; - } - - foreach (var observable in UpdatedInstances) - { - observable.NotifyObservers(); - } - } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateData.cs =================================================================== diff -u -r563b2c1126e515380a0ec7e2215bf07637445588 -r0970881ada96a68e26a4453b25b3d7b6bd64479d --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateData.cs (.../StochasticSoilModelUpdateData.cs) (revision 563b2c1126e515380a0ec7e2215bf07637445588) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/StochasticSoilModelUpdateData.cs (.../StochasticSoilModelUpdateData.cs) (revision 0970881ada96a68e26a4453b25b3d7b6bd64479d) @@ -24,6 +24,7 @@ using System.Linq; using Core.Common.Base; using log4net; +using Ringtoets.Common.Service; using Ringtoets.Piping.Data; using Ringtoets.Piping.Service; @@ -130,10 +131,14 @@ } foreach (StochasticSoilProfile updatedProfile in difference.UpdatedProfiles) { - affectedObjects.AddRange(failureMechanism.Calculations - .Cast() - .Select(c => c.InputParameters) - .Where(i => ReferenceEquals(i.StochasticSoilProfile, updatedProfile))); + 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); + } } return affectedObjects; } Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj =================================================================== diff -u -r673bf2f4f4de6006444aae3a10183f9442eb0f23 -r0970881ada96a68e26a4453b25b3d7b6bd64479d --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision 673bf2f4f4de6006444aae3a10183f9442eb0f23) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision 0970881ada96a68e26a4453b25b3d7b6bd64479d) @@ -127,6 +127,11 @@ Ringtoets.Common.IO False + + {D951D6DA-FE83-4920-9FDB-63BF96480B54} + Ringtoets.Common.Service + False + {7cd038e1-e111-4969-aced-22c5bd2974e1} Ringtoets.Piping.Forms Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs =================================================================== diff -u -r89d34600d1408c8b1f4240020e841ba64cc26622 -r0970881ada96a68e26a4453b25b3d7b6bd64479d --- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs (.../StochasticSoilModelUpdateDataTest.cs) (revision 89d34600d1408c8b1f4240020e841ba64cc26622) +++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/StochasticSoilModelUpdateDataTest.cs (.../StochasticSoilModelUpdateDataTest.cs) (revision 0970881ada96a68e26a4453b25b3d7b6bd64479d) @@ -22,16 +22,21 @@ using System; using System.Collections.Generic; using System.Linq; +using Core.Common.Base; using NUnit.Framework; using Ringtoets.Piping.Data; using Ringtoets.Piping.Data.TestUtil; +using Ringtoets.Piping.KernelWrapper.TestUtil; using Ringtoets.Piping.Plugin.FileImporter; +using Ringtoets.Piping.Primitives; namespace Ringtoets.Piping.Plugin.Test.FileImporter { [TestFixture] public class StochasticSoilModelUpdateDataTest { + private const string sourceFilePath = "path"; + [Test] public void Constructor_WithoutCalculations_CreatesNewInstance() { @@ -96,11 +101,10 @@ } [Test] - public void UpdateModelWithImportedData_MultipleCurrentModelsWithSameNameAndImportedDataContainsModelWithSameName_ThrowsInvalidOperationException() + public void UpdateModelWithImportedData_CurrentModelsWithSameNameAndImportedModelWithSameName_ThrowsInvalidOperationException() { // Setup var nonUniqueName = "non-unique name"; - var sourceFilePath = "path"; var targetCollection = new StochasticSoilModelCollection(); targetCollection.AddRange(new[] @@ -123,7 +127,7 @@ } [Test] - public void UpdateModelWithImportedData_CurrentModelsEmptyModelsImported_NewModelsAdded() + public void UpdateModelWithImportedData_WithoutCurrentModelAndModelsImported_NewModelsAdded() { // Setup var importedStochasticSoilModels = new[] @@ -142,10 +146,9 @@ } [Test] - public void UpdateModelWithImportedData_CurrentModelsContainsModelsImportedDataEmpty_ModelsRemoved() + public void UpdateModelWithImportedData_WithCurrentModelsAndImportedDataEmpty_ModelsRemoved() { // Setup - var sourceFilePath = "path"; var targetCollection = new StochasticSoilModelCollection(); targetCollection.AddRange(new[] { @@ -163,11 +166,9 @@ } [Test] - public void UpdateModelWithImportedData_CurrentModelsContainsModelsImportedDataContainsModelWithOtherName_ModelReplaced() + public void UpdateModelWithImportedData_WithCurrentModelAndImportedModelWithOtherName_ModelReplaced() { // Setup - var sourceFilePath = "path"; - var readModel = new TestStochasticSoilModel("read"); var existingModel = new TestStochasticSoilModel("existing"); var targetCollection = new StochasticSoilModelCollection(); @@ -177,6 +178,7 @@ }, sourceFilePath); var strategy = new StochasticSoilModelUpdateData(new PipingFailureMechanism()); + var readModel = new TestStochasticSoilModel("read"); // Call strategy.UpdateModelWithImportedData(new[] { readModel }, sourceFilePath, targetCollection); @@ -186,12 +188,34 @@ } [Test] - public void UpdateModelWithImportedData_CurrentModelsContainsModelsImportedDataContainsModelWithSameName_ModelUpdated() + public void UpdateModelWithImportedData_WithCurrentModelAndImportedModelWithSameName_ModelUpdated() { // Setup - var sourceFilePath = "path"; var modelsName = "same model"; + var existingModel = new TestStochasticSoilModel(modelsName); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + var strategy = new StochasticSoilModelUpdateData(new PipingFailureMechanism()); var readModel = new TestStochasticSoilModel(modelsName); + + // Call + strategy.UpdateModelWithImportedData(new[] { readModel }, sourceFilePath, targetCollection); + + // Assert + Assert.AreEqual(1, targetCollection.Count); + Assert.AreSame(existingModel, targetCollection.First()); + } + + [Test] + public void UpdateModelWithImportedData_UpdateCurrentModelWithImportedModelWithOtherProfiles_ProfilesAdded() + { + // Setup + var modelsName = "same model"; var existingModel = new TestStochasticSoilModel(modelsName); var targetCollection = new StochasticSoilModelCollection(); @@ -201,12 +225,124 @@ }, sourceFilePath); var strategy = new StochasticSoilModelUpdateData(new PipingFailureMechanism()); + var readModel = CreateSimpleModel(modelsName, "new profile A", "new profile B"); // Call strategy.UpdateModelWithImportedData(new[] { readModel }, sourceFilePath, targetCollection); // Assert Assert.AreSame(existingModel, targetCollection.First()); + Assert.AreEqual(2, targetCollection.First().StochasticSoilProfiles.Count); } + + [Test] + public void UpdateModelWithImportedData_ProfilesAssignedToCalculationsWithOneImportedModelProfileRemoved_OneProfileRemovedOtherUpdatedCalculationsUpdatedAccordingly() + { + // Setup + var modelsName = "same model"; + var existingModel = new TestStochasticSoilModel(modelsName); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + var firstExistingProfile = existingModel.StochasticSoilProfiles.First(); + var readModel = CreateSimpleModel(modelsName, firstExistingProfile.SoilProfile.Name); + + var calculationWithUpdatedProfile = new PipingCalculationScenario(new GeneralPipingInput()); + calculationWithUpdatedProfile.InputParameters.StochasticSoilModel = existingModel; + calculationWithUpdatedProfile.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[0]; + calculationWithUpdatedProfile.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var calculationWithDeletedProfile = new PipingCalculationScenario(new GeneralPipingInput()); + calculationWithDeletedProfile.InputParameters.StochasticSoilModel = existingModel; + calculationWithDeletedProfile.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles[1]; + calculationWithDeletedProfile.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var failureMechanism = new PipingFailureMechanism(); + failureMechanism.CalculationsGroup.Children.Add(calculationWithDeletedProfile); + failureMechanism.CalculationsGroup.Children.Add(calculationWithUpdatedProfile); + + var strategy = new StochasticSoilModelUpdateData(failureMechanism); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData( + new[] { readModel }, + sourceFilePath, + targetCollection).ToArray(); + + // Assert + var firstSoilModel = targetCollection.First(); + Assert.AreSame(existingModel, firstSoilModel); + Assert.AreEqual(1, firstSoilModel.StochasticSoilProfiles.Count); + Assert.AreSame(firstExistingProfile, firstSoilModel.StochasticSoilProfiles.First()); + + Assert.IsFalse(calculationWithUpdatedProfile.HasOutput); + CollectionAssert.Contains(affectedObjects, calculationWithUpdatedProfile); + CollectionAssert.Contains(affectedObjects, calculationWithUpdatedProfile.InputParameters); + + Assert.IsFalse(calculationWithDeletedProfile.HasOutput); + Assert.IsNull(calculationWithDeletedProfile.InputParameters.StochasticSoilProfile); + CollectionAssert.Contains(affectedObjects, calculationWithUpdatedProfile); + CollectionAssert.Contains(affectedObjects, calculationWithUpdatedProfile.InputParameters); + + } + + [Test] + public void UpdateModelWithImportedData_CalculationWithOutputAssignedRemovedSoilModelAndProfile_CalculationUpdatedAndCalculationAndInputReturned() + { + // Setup + var existingModel = new TestStochasticSoilModel(); + var calculation = new PipingCalculationScenario(new GeneralPipingInput()); + calculation.InputParameters.StochasticSoilModel = existingModel; + calculation.InputParameters.StochasticSoilProfile = existingModel.StochasticSoilProfiles.First(); + calculation.Output = new PipingOutput(new PipingOutput.ConstructionProperties()); + + var failureMechanism = new PipingFailureMechanism(); + failureMechanism.CalculationsGroup.Children.Add(calculation); + + var strategy = new StochasticSoilModelUpdateData(failureMechanism); + + var targetCollection = new StochasticSoilModelCollection(); + targetCollection.AddRange(new[] + { + existingModel, + }, sourceFilePath); + + // Call + IEnumerable affectedObjects = strategy.UpdateModelWithImportedData( + new List(), + sourceFilePath, + targetCollection).ToArray(); + + // Assert + Assert.IsFalse(calculation.HasOutput); + Assert.IsNull(calculation.InputParameters.StochasticSoilModel); + Assert.IsNull(calculation.InputParameters.StochasticSoilProfile); + CollectionAssert.Contains(affectedObjects, calculation); + CollectionAssert.Contains(affectedObjects, calculation.InputParameters); + } + + /// + /// Creates a simple model with names for the model and profiles in the model set as specified. + /// + /// Name of the created model. + /// List of names for the profiles to be added to the model. + /// A new . + private StochasticSoilModel CreateSimpleModel(string modelName, params string[] profileNames) + { + var model = new StochasticSoilModel(-1, modelName, "segment name"); + foreach (var profileName in profileNames) + { + model.StochasticSoilProfiles.Add( + new StochasticSoilProfile(1.0 / profileNames.Length, SoilProfileType.SoilProfile1D, -1) + { + SoilProfile = new TestPipingSoilProfile(profileName) + }); + } + return model; + } } } \ No newline at end of file