PIbd-13_Ladyagin_P.D._Simple/AirplaneWithRadar/ProjectAirplaneWithRadar/CollectionGenericObjects/StorageCollection.cs
2024-06-09 18:11:19 +04:00

227 lines
9.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Data;
using System.IO;
using System.Text;
using ProjectAirplaneWithRadar.Drawnings;
using ProjectAirplaneWithRadar.Exceptions;
namespace ProjectAirplaneWithRadar.CollectionGenericObjects
{
/// <summary>
/// Класс-хранилище коллекций
/// </summary>
/// <typeparam name="T"></typeparam>
public class StorageCollection<T>
where T : DrawningAirplane
{
/// <summary>
/// Словарь (хранилище) с коллекциями
/// </summary>
readonly Dictionary<CollectionInfo, ICollectionGenericObjects<T>> _storages;
/// <summary>
/// Возвращение списка названий коллекций
/// </summary>
public List<CollectionInfo> Keys => _storages.Keys.ToList();
/// <summary>
/// Ключевое слово, с которого должен начинаться файл
/// </summary>
private readonly string _collectionKey = "CollectionsStorage";
/// <summary>
/// Разделитель для записи ключа и значения элемента словаря
/// </summary>
private readonly string _separatorForKeyValue = "|";
/// <summary>
/// Разделитель для записей коллекции данных в файл
/// </summary>
private readonly string _separatorItems = ";";
/// <summary>
/// Конструктор
/// </summary>
public StorageCollection()
{
_storages = new Dictionary<CollectionInfo, ICollectionGenericObjects<T>>();
}
/// <summary>
/// Добавление коллекции в хранилище
/// </summary>
/// <param name="name">Название коллекции</param>
/// <param name="collectionType">тип коллекции</param>
public void AddCollection(string name, CollectionType collectionType)
{
CollectionInfo collectionInfo = new CollectionInfo(name, collectionType, string.Empty);
if (collectionInfo.Name == null || _storages.ContainsKey(collectionInfo))
return;
switch (collectionInfo.CollectionType)
{
case CollectionType.None:
return;
case CollectionType.Massive:
_storages.Add(collectionInfo, new MassiveGenericObjects<T> { });
return;
case CollectionType.List:
_storages.Add(collectionInfo, new ListGenericObjects<T> { });
return;
}
}
/// <summary>
/// Удаление коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
public void DelCollection(string name)
{
CollectionInfo collectionInfo = new CollectionInfo(name, CollectionType.None, string.Empty);
if (collectionInfo.Name == null || !_storages.ContainsKey(collectionInfo))
return;
_storages.Remove(collectionInfo);
}
/// <summary>
/// Доступ к коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
/// <returns></returns>
public ICollectionGenericObjects<T>? this[string name]
{
get
{
CollectionInfo collectionInfo = new CollectionInfo(name, CollectionType.None, "");
if (collectionInfo == null || !_storages.ContainsKey(collectionInfo))
return null;
return _storages[collectionInfo];
}
}
/// <summary>
/// Сохранение информации по самолетам в хранилище в файл
/// </summary>
/// <param name="filename">Путь и имя файла</param>
/// <returns>true - сохранение прошло успешно, false - ошибка при сохранении данных</returns>
public void SaveData(string filename)
{
if(_storages.Count == 0)
throw new NullReferenceException("В хранилище отсутствуют коллекции для сохранения");
if (File.Exists(filename))
File.Delete(filename);
using (StreamWriter sw = new(filename))
{
sw.Write(_collectionKey);
foreach (KeyValuePair<CollectionInfo, ICollectionGenericObjects<T>> value in _storages)
{
sw.Write(Environment.NewLine);
if (value.Value.Count == 0)
{
continue;
}
sw.Write(value.Key);
sw.Write(_separatorForKeyValue);
sw.Write(value.Value.MaxCount);
sw.Write(_separatorForKeyValue);
foreach (T? item in value.Value.GetItems())
{
string data = item?.GetDataForSave() ?? string.Empty;
if (string.IsNullOrEmpty(data))
{
continue;
}
sw.Write(data);
sw.Write(_separatorItems);
}
}
}
}
/// <summary>
/// Загрузка информации по самолетам в хранилище из файла
/// </summary>
/// <param name="filename">Путь и имя файла</param>
/// <returns>true - загрузка прошла успешно, false - ошибка при загрузке данных</returns>
public void LoadData(string filename)
{
if (!File.Exists(filename))
{
throw new FileNotFoundException("Файл не существует");
}
using (StreamReader sr = new(filename))
{
string str = sr.ReadLine();
if (str == null || str.Length == 0)
{
throw new FileFormatException("В файле нет данных");
}
if (!str.Equals(_collectionKey))
{
throw new FileFormatException("В файле неверные данные");
}
_storages.Clear();
while (!sr.EndOfStream)
{
string[] record = sr.ReadLine().Split(_separatorForKeyValue, StringSplitOptions.RemoveEmptyEntries);
if (record.Length != 3)
{
continue;
}
CollectionInfo? collectionInfo = CollectionInfo.GetCollectionInfo(record[0]) ??
throw new Exception("Не удалось определить информацию коллекции:" + record[0]);
ICollectionGenericObjects<T>? collection = StorageCollection<T>.CreateCollection(collectionInfo.CollectionType) ??
throw new Exception("Не удалось определить тип коллекции:" + record[1]);
collection.MaxCount = Convert.ToInt32(record[1]);
string[] set = record[2].Split(_separatorItems, StringSplitOptions.RemoveEmptyEntries);
foreach (string elem in set)
{
if (elem?.CreateDrawningAirplane() is T airplane)
{
try
{
if (collection.Insert(airplane) == -1)
throw new InvalidOperationException("Объект не удалось добавить в коллекцию: " + record[3]);
}
catch (CollectionOverflowException ex)
{
throw new OverflowException("Коллекция переполнена", ex);
}
}
}
_storages.Add(collectionInfo, collection);
}
}
}
/// <summary>
/// Создание коллекции по типу
/// </summary>
/// <param name="collectionType"></param>
/// <returns></returns>
private static ICollectionGenericObjects<T>? CreateCollection(CollectionType collectionType)
{
return collectionType switch
{
CollectionType.Massive => new MassiveGenericObjects<T>(),
CollectionType.List => new ListGenericObjects<T>(),
_ => null,
};
}
}
}