// Copyright (C) Stichting Deltares 2018. 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.IO; using System.Linq; using Core.Common.Base.IO; using Core.Common.IO.Exceptions; using Core.Common.IO.Readers; using Core.Common.Util.Builders; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.IO.HydraRing; using Ringtoets.HydraRing.IO.HydraulicBoundaryDatabase; using Ringtoets.HydraRing.IO.HydraulicLocationConfigurationDatabase; using Ringtoets.Integration.IO.Handlers; using Ringtoets.Integration.IO.Properties; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.Integration.IO.Importers { /// /// Importer for hydraulic boundary database files and corresponding configuration files. /// public class HydraulicBoundaryDatabaseImporter : FileImporterBase { private const int numberOfSteps = 4; private readonly IHydraulicBoundaryDatabaseUpdateHandler updateHandler; /// /// Creates a new instance of . /// /// The import target. /// The object responsible for updating the . /// The path of the hydraulic boundary database file to import from. /// Thrown when any parameter is null. public HydraulicBoundaryDatabaseImporter(HydraulicBoundaryDatabase importTarget, IHydraulicBoundaryDatabaseUpdateHandler updateHandler, string filePath) : base(filePath, importTarget) { if (updateHandler == null) { throw new ArgumentNullException(nameof(updateHandler)); } this.updateHandler = updateHandler; } protected override bool OnImport() { ReadResult readHydraulicBoundaryDatabaseResult = ReadHydraulicBoundaryDatabase(); if (readHydraulicBoundaryDatabaseResult.CriticalErrorOccurred || Canceled) { return false; } ReadHydraulicBoundaryDatabase readHydraulicBoundaryDatabase = readHydraulicBoundaryDatabaseResult.Items.Single(); bool clearDependentData = IsClearingDependentDataRequired(readHydraulicBoundaryDatabase); if (Canceled) { return false; } ReadResult readHydraulicLocationConfigurationDatabaseResult = ReadHydraulicLocationConfigurationDatabase( readHydraulicBoundaryDatabase.TrackId); if (readHydraulicLocationConfigurationDatabaseResult.CriticalErrorOccurred || Canceled) { return false; } if (!OpenSettingsFileToValidate() || Canceled) { return false; } AddHydraulicBoundaryDatabaseToDataModel(readHydraulicBoundaryDatabaseResult.Items.Single(), readHydraulicLocationConfigurationDatabaseResult.Items.Single()); return true; } protected override void LogImportCanceledMessage() { Log.Info(Resources.HydraulicBoundaryDatabaseImporter_ProgressText_Import_canceled_No_data_changed); } private bool IsClearingDependentDataRequired(ReadHydraulicBoundaryDatabase readHydraulicBoundaryDatabase) { var clearDependentData = false; if (updateHandler.IsConfirmationRequired(readHydraulicBoundaryDatabase)) { if (!updateHandler.InquireConfirmation()) { Cancel(); } else { clearDependentData = true; } } return clearDependentData; } private ReadResult ReadHydraulicBoundaryDatabase() { NotifyProgress(Resources.HydraulicBoundaryDatabaseImporter_ProgressText_Reading_HRD_file, 1, numberOfSteps); try { using (var reader = new HydraulicBoundaryDatabaseReader(FilePath)) { return new ReadResult(false) { Items = new[] { reader.Read() } }; } } catch (Exception e) when (e is CriticalFileReadException || e is LineParseException) { return HandleCriticalFileReadError(e); } } private ReadResult ReadHydraulicLocationConfigurationDatabase(long trackId) { NotifyProgress(Resources.HydraulicBoundaryDatabaseImporter_ProgressText_Reading_HLCD_file, 2, numberOfSteps); string hlcdFilePath = Path.Combine(Path.GetDirectoryName(FilePath), "hlcd.sqlite"); try { using (var reader = new HydraulicLocationConfigurationDatabaseReader(hlcdFilePath)) { return ReadHydraulicLocationConfigurationDatabase(trackId, reader); } } catch (CriticalFileReadException) { return HandleCriticalFileReadError(Resources.HydraulicBoundaryDatabaseImporter_HLCD_sqlite_Not_Found); } } private ReadResult ReadHydraulicLocationConfigurationDatabase(long trackId, HydraulicLocationConfigurationDatabaseReader reader) { try { return new ReadResult(false) { Items = new[] { reader.Read(trackId) } }; } catch (Exception e) when (e is CriticalFileReadException || e is LineParseException) { return HandleCriticalFileReadError(e); } } private bool OpenSettingsFileToValidate() { NotifyProgress(Resources.HydraulicBoundaryDatabaseImporter_ProgressText_Reading_HRD_settings_file, 3, numberOfSteps); string settingsFilePath = HydraulicBoundaryDatabaseHelper.GetHydraulicBoundarySettingsDatabase(FilePath); try { using (new HydraRingSettingsDatabaseReader(settingsFilePath)) {} return true; } catch (CriticalFileReadException e) { HandleCriticalFileReadError(string.Format(Resources.HydraulicBoundaryDatabaseImporter_Cannot_open_hydraulic_calculation_settings_file_0_, e.Message)); return false; } } private void AddHydraulicBoundaryDatabaseToDataModel(ReadHydraulicBoundaryDatabase readHydraulicBoundaryDatabase, ReadHydraulicLocationConfigurationDatabase readHydraulicLocationConfigurationDatabase) { NotifyProgress(RingtoetsCommonIOResources.Importer_ProgressText_Adding_imported_data_to_AssessmentSection, 4, numberOfSteps); updateHandler.Update(ImportTarget, readHydraulicBoundaryDatabase, readHydraulicLocationConfigurationDatabase); } private ReadResult HandleCriticalFileReadError(Exception e) { string errorMessage = string.Format(Resources.HydraulicBoundaryDatabaseImporter_HandleCriticalFileReadError_Error_0_No_HydraulicBoundaryDatabase_imported, e.Message); Log.Error(errorMessage); return new ReadResult(true); } private ReadResult HandleCriticalFileReadError(string message) { HandleCriticalFileReadError(message); return new ReadResult(true); } private void HandleCriticalFileReadError(string message) { string errorMessage = BuildErrorMessage(message); Log.Error(errorMessage); } private string BuildErrorMessage(string message) { return new FileReaderErrorMessageBuilder(FilePath).Build( string.Format(Resources.HydraulicBoundaryDatabaseImporter_HandleCriticalFileReadError_Error_0_No_HydraulicBoundaryDatabase_imported, message)); } } }