// 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.IO; using Core.Common.Base.IO; using Core.Common.IO.Exceptions; using Core.Common.Util.Builders; using log4net; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.IO.HydraRing; using Ringtoets.Common.IO.Properties; using Ringtoets.HydraRing.IO.HydraulicBoundaryDatabase; using Ringtoets.HydraRing.IO.HydraulicLocationConfigurationDatabase; namespace Ringtoets.Common.IO.FileImporters { /// /// Importer for hydraulic boundary database files and corresponding configuration files. /// public class HydraulicBoundaryDatabaseImporter : IDisposable { private readonly ILog log = LogManager.GetLogger(typeof(HydraulicBoundaryDatabaseImporter)); private HydraulicBoundaryDatabaseReader hydraulicBoundaryDatabaseReader; private HydraulicLocationConfigurationDatabaseReader hydraulicLocationConfigurationDatabaseReader; /// /// Creates a new instance of . /// /// The to set the imported data to. /// The path of the hydraulic boundary database file to import from. /// true if the import was successful, false otherwise. /// Thrown when is null. /// Thrown when: /// /// The given file at cannot be read. /// The file 'HLCD.sqlite' in the same folder as cannot be read. /// The file 'config.sqlite' in the same folder as cannot be read. /// /// public bool Import(IAssessmentSection assessmentSection, string filePath) { if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } ValidateAndConnectTo(filePath); HydraulicBoundaryDatabase hydraulicBoundaryDatabase = assessmentSection.HydraulicBoundaryDatabase; if (!IsImportRequired(hydraulicBoundaryDatabase)) { bool isNotificationRequired = hydraulicBoundaryDatabase.FilePath != filePath; hydraulicBoundaryDatabase.FilePath = filePath; if (isNotificationRequired) { assessmentSection.NotifyObservers(); } } else { ReadHydraulicBoundaryDatabase readHydraulicBoundaryDatabase = ReadHydraulicBoundaryDatabase(); if (readHydraulicBoundaryDatabase == null) { return false; } hydraulicBoundaryDatabase.FilePath = filePath; hydraulicBoundaryDatabase.Version = readHydraulicBoundaryDatabase.Version; hydraulicBoundaryDatabase.Locations.Clear(); hydraulicBoundaryDatabase.Locations.AddRange(readHydraulicBoundaryDatabase.Locations); if (readHydraulicBoundaryDatabase.CanUsePreprocessor) { hydraulicBoundaryDatabase.CanUsePreprocessor = true; hydraulicBoundaryDatabase.UsePreprocessor = true; hydraulicBoundaryDatabase.PreprocessorDirectory = Path.GetDirectoryName(filePath); } else { hydraulicBoundaryDatabase.CanUsePreprocessor = false; } assessmentSection.NotifyObservers(); log.Info(Resources.HydraulicBoundaryDatabaseImporter_Import_All_hydraulic_locations_read); } return true; } public void Dispose() { if (hydraulicBoundaryDatabaseReader != null) { hydraulicBoundaryDatabaseReader.Dispose(); hydraulicBoundaryDatabaseReader = null; } if (hydraulicLocationConfigurationDatabaseReader != null) { hydraulicLocationConfigurationDatabaseReader.Dispose(); hydraulicLocationConfigurationDatabaseReader = null; } } /// /// Validates the hydraulic boundary database file and opens a connection. /// /// The path to the file to read. /// Thrown when: /// /// The given file at cannot be read. /// The file 'HLCD.sqlite' in the same folder as cannot be read. /// The file 'config.sqlite' in the same folder as cannot be read. /// /// private void ValidateAndConnectTo(string filePath) { hydraulicBoundaryDatabaseReader = new HydraulicBoundaryDatabaseReader(filePath); string hlcdFilePath = Path.Combine(Path.GetDirectoryName(filePath), "hlcd.sqlite"); try { hydraulicLocationConfigurationDatabaseReader = new HydraulicLocationConfigurationDatabaseReader(hlcdFilePath); } catch (CriticalFileReadException) { string message = new FileReaderErrorMessageBuilder(filePath).Build(Resources.HydraulicBoundaryDatabaseImporter_HLCD_sqlite_Not_Found); throw new CriticalFileReadException(message); } string settingsFilePath = HydraulicBoundaryDatabaseHelper.GetHydraulicBoundarySettingsDatabase(filePath); try { using (new HydraRingSettingsDatabaseReader(settingsFilePath)) {} } catch (CriticalFileReadException e) { string errorMessage = string.Format(Resources.HydraulicBoundaryDatabaseImporter_Cannot_open_hydraulic_calculation_settings_file_0_, e.Message); throw new CriticalFileReadException(new FileReaderErrorMessageBuilder(filePath).Build(errorMessage)); } } private bool IsImportRequired(HydraulicBoundaryDatabase hydraulicBoundaryDatabase) { return hydraulicBoundaryDatabase == null || hydraulicBoundaryDatabaseReader.GetVersion() != hydraulicBoundaryDatabase.Version; } private ReadHydraulicBoundaryDatabase ReadHydraulicBoundaryDatabase() { long trackId = GetTrackId(); if (trackId == 0) { return null; } try { string version = hydraulicBoundaryDatabaseReader.GetVersion(); bool canUsePreprocessor = hydraulicLocationConfigurationDatabaseReader.GetCanUsePreprocessorByTrackId(trackId); var hydraulicBoundaryLocations = new List(); Dictionary locationIdsDictionary = hydraulicLocationConfigurationDatabaseReader.GetLocationIdsByTrackId(trackId); var filter = new HydraulicBoundaryLocationFilter(HydraulicBoundaryDatabaseHelper.GetHydraulicBoundarySettingsDatabase(hydraulicBoundaryDatabaseReader.Path)); hydraulicBoundaryDatabaseReader.PrepareReadLocation(); while (hydraulicBoundaryDatabaseReader.HasNext) { ReadHydraulicBoundaryLocation location = hydraulicBoundaryDatabaseReader.ReadLocation(); long locationId; locationIdsDictionary.TryGetValue(location.Id, out locationId); if (filter.ShouldInclude(locationId)) { hydraulicBoundaryLocations.Add(new HydraulicBoundaryLocation(locationId, location.Name, location.CoordinateX, location.CoordinateY)); } } return new ReadHydraulicBoundaryDatabase(version, hydraulicBoundaryLocations, canUsePreprocessor); } catch (Exception e) when (e is LineParseException || e is CriticalFileReadException) { log.Error(e.Message, e); return null; } } private long GetTrackId() { try { return hydraulicBoundaryDatabaseReader.GetTrackId(); } catch (Exception e) when (e is LineParseException || e is CriticalFileReadException) { log.Error(e.Message, e); return 0; } } } }