diff --git a/ProjectLiner/ProjectLiner/Exceptions/CollectionOverflowException.cs b/ProjectLiner/ProjectLiner/Exceptions/CollectionOverflowException.cs new file mode 100644 index 0000000..e83b5a4 --- /dev/null +++ b/ProjectLiner/ProjectLiner/Exceptions/CollectionOverflowException.cs @@ -0,0 +1,17 @@ +using System.Runtime.Serialization; + +namespace ProjectLiner.Exceptions; + +internal class CollectionOverflowException : ApplicationException +{ + public CollectionOverflowException(int count) : + base("Collection overflow. Count: " + count) + { } + public CollectionOverflowException() : base() { } + public CollectionOverflowException(string message) : base(message) { } + public CollectionOverflowException(string message, Exception exception) : + base(message, exception) + { } + protected CollectionOverflowException(SerializationInfo info, + StreamingContext context) : base(info, context) { } +} diff --git a/ProjectLiner/ProjectLiner/Exceptions/ObjectNotFoundException.cs b/ProjectLiner/ProjectLiner/Exceptions/ObjectNotFoundException.cs new file mode 100644 index 0000000..c4a6cf7 --- /dev/null +++ b/ProjectLiner/ProjectLiner/Exceptions/ObjectNotFoundException.cs @@ -0,0 +1,16 @@ +using System.Runtime.Serialization; + +namespace ProjectLiner.Exceptions; + +internal class ObjectNotFoundException : ApplicationException +{ + public ObjectNotFoundException(int i) : base("Object not found. Index: " + i) + { } + public ObjectNotFoundException() : base() { } + public ObjectNotFoundException(string message) : base(message) { } + public ObjectNotFoundException(string message, Exception exception) : + base(message, exception) + { } + protected ObjectNotFoundException(SerializationInfo info, StreamingContext + context) : base(info, context) { } +} diff --git a/ProjectLiner/ProjectLiner/Exceptions/PosOutOfCollectionRangeException.cs b/ProjectLiner/ProjectLiner/Exceptions/PosOutOfCollectionRangeException.cs new file mode 100644 index 0000000..110a37a --- /dev/null +++ b/ProjectLiner/ProjectLiner/Exceptions/PosOutOfCollectionRangeException.cs @@ -0,0 +1,16 @@ +using System.Runtime.Serialization; + +namespace ProjectLiner.Exceptions; + +internal class PosOutOfCollectionRangeException : ApplicationException +{ + public PosOutOfCollectionRangeException(int i) : + base("Pos out of collection range. Index: " + i) + { } + public PosOutOfCollectionRangeException() : base() { } + public PosOutOfCollectionRangeException(string message) : base(message) { } + public PosOutOfCollectionRangeException(string message, Exception + exception) : base(message, exception) { } + protected PosOutOfCollectionRangeException(SerializationInfo info, + StreamingContext context) : base(info, context) { } +} diff --git a/ProjectLiner/ProjectLiner/FormShipCollection.cs b/ProjectLiner/ProjectLiner/FormShipCollection.cs index 486d38c..75f4dce 100644 --- a/ProjectLiner/ProjectLiner/FormShipCollection.cs +++ b/ProjectLiner/ProjectLiner/FormShipCollection.cs @@ -1,6 +1,9 @@ -using ProjectLiner.CollectionGenericObjects; +using System.Linq.Expressions; +using Microsoft.Extensions.Logging; +using ProjectLiner.CollectionGenericObjects; using ProjectLiner.Drawnings; using ProjectLiner.Entities; +using ProjectLiner.Exceptions; using ProjectLiner.GenericObjectsCollection; namespace ProjectLiner; @@ -9,11 +12,13 @@ public partial class FormShipCollection : Form { private readonly CollectionStorage _collectionStorage; private AbstractCompany? _company = null; - public FormShipCollection() + private readonly ILogger _logger; + public FormShipCollection(ILogger logger) { InitializeComponent(); _collectionStorage = new CollectionStorage(); panelCompanyTools.Enabled = false; + _logger = logger; } private void ComboBoxCompanySelector_SelectedIndexChanged(object sender, @@ -34,14 +39,19 @@ public partial class FormShipCollection : Form { return; } - if (_company + liner) + try { - MessageBox.Show("Object was added"); - pictureBox.Image = _company.Show(); + if (_company + liner) + { + pictureBox.Image = _company.Show(); + MessageBox.Show("Liner added successfully"); + _logger.LogInformation("Liner added successfully at {Time}", DateTime.Now); + } } - else + catch (CollectionOverflowException ex) { - MessageBox.Show("Couldn't add object"); + MessageBox.Show("" + ex.Message); + _logger.LogWarning("Failed to add liner: {Message} at {Time}", ex.Message, DateTime.Now); } } private void ButtonRemoveShip_Click(object sender, EventArgs e) @@ -52,19 +62,31 @@ public partial class FormShipCollection : Form return; } if (MessageBox.Show("Remove object?", "Removing...", - MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) { return; } int pos = Convert.ToInt32(maskedTextBoxPosition.Text); - if (_company - pos) + try { - MessageBox.Show("Object was removed"); - pictureBox.Image = _company.Show(); + if (_company - pos) + { + MessageBox.Show("Object was removed"); + pictureBox.Image = _company.Show(); + _logger.LogInformation("Liner removed successfully at position {pos} at {Time}", + pos, DateTime.Now); + } } - else + catch (ObjectNotFoundException ex) + { + MessageBox.Show("" + ex.Message); + _logger.LogWarning("Failed to remove liner: Object not found at postion {pos}", + pos); + } + catch (PosOutOfCollectionRangeException ex) { MessageBox.Show("Couldn't remove object"); + _logger.LogWarning("Failed to remove liner: {Message}", ex.Message); } } private void ButtonSubmitForTesting_Click(object sender, EventArgs e) @@ -77,7 +99,19 @@ public partial class FormShipCollection : Form int counter = 100; while (liner == null) { - liner = _company.GetRandomObject(); + try + { + liner = _company.GetRandomObject(); + _logger.LogInformation("Object was submitted for testing at position {pos}", counter); + } + catch (ObjectNotFoundException) + { + _logger.LogWarning("Object not found at position {pos}", counter); + } + catch (PosOutOfCollectionRangeException) + { + _logger.LogWarning("Position out of range at {pos}", counter); + } counter--; if (counter <= 0) { @@ -110,6 +144,7 @@ public partial class FormShipCollection : Form { MessageBox.Show("Please fill all fields", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogInformation("Failed to add collection: Please fill all fields"); return; } CollectionType collectionType = CollectionType.None; @@ -123,6 +158,8 @@ public partial class FormShipCollection : Form } _collectionStorage.AddCollection(textBoxCollectionName.Text, collectionType); + _logger.LogInformation("Collection of type {type} with name {name} added successfully", + collectionType, textBoxCollectionName.Text); RefreshListBoxItems(); } @@ -134,6 +171,7 @@ public partial class FormShipCollection : Form { MessageBox.Show("Collection is not selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogInformation("Failed to remove collection: Collection is not selected"); return; } @@ -145,6 +183,7 @@ public partial class FormShipCollection : Form RefreshListBoxItems(); MessageBox.Show("Collection removed successfully", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.LogInformation("Collection {name} removed successfully", collectionName); } } @@ -167,6 +206,7 @@ public partial class FormShipCollection : Form listBoxCollections.SelectedItem == null) { MessageBox.Show("Collection is not selected"); + _logger.LogInformation("Failed to create company: Collection is not selected"); return; } IGenericObjectsCollection? collection = @@ -174,6 +214,7 @@ public partial class FormShipCollection : Form if (collection == null) { MessageBox.Show("Collection is not found"); + _logger.LogInformation("Failed to create company: Collection is not found"); return; } switch (comboBoxCompanySelector.Text) @@ -184,6 +225,7 @@ public partial class FormShipCollection : Form break; } panelCompanyTools.Enabled = true; + _logger.LogInformation($"Company was created: {comboBoxCompanySelector.Text}"); RefreshListBoxItems(); } @@ -191,15 +233,18 @@ public partial class FormShipCollection : Form { if (saveFileDialog.ShowDialog() == DialogResult.OK) { - if (_collectionStorage.SaveData(saveFileDialog.FileName)) + try { + _collectionStorage.SaveData(saveFileDialog.FileName); MessageBox.Show("Data saved successfully", "Success", - MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.LogInformation("Saved in {filename}", saveFileDialog.FileName); } - else + catch (Exception ex) { - MessageBox.Show("Data wasn't saved", "Error", + MessageBox.Show(ex.Message + "Data wasn't saved", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogError("Error saving data: {Message}", ex.Message); } } } @@ -208,16 +253,19 @@ public partial class FormShipCollection : Form { if (openFileDialog.ShowDialog() == DialogResult.OK) { - if (_collectionStorage.LoadData(openFileDialog.FileName)) + try { + _collectionStorage.LoadData(openFileDialog.FileName); MessageBox.Show("Data loaded successfully", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); + _logger.LogInformation("Loaded from {filename}", openFileDialog.FileName); RefreshListBoxItems(); } - else + catch (Exception ex) { - MessageBox.Show("Data wasn't loaded", "Error", + MessageBox.Show(ex.Message + "Data wasn't loaded", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + _logger.LogError("Error loading data: {Message}", ex.Message); } } RefreshListBoxItems(); diff --git a/ProjectLiner/ProjectLiner/GenericObjectsCollection/AbstractCompany.cs b/ProjectLiner/ProjectLiner/GenericObjectsCollection/AbstractCompany.cs index b23df5f..1e34680 100644 --- a/ProjectLiner/ProjectLiner/GenericObjectsCollection/AbstractCompany.cs +++ b/ProjectLiner/ProjectLiner/GenericObjectsCollection/AbstractCompany.cs @@ -1,4 +1,6 @@ -using ProjectLiner.Drawnings; +using System; +using ProjectLiner.Drawnings; +using ProjectLiner.Exceptions; namespace ProjectLiner.GenericObjectsCollection; @@ -6,11 +8,12 @@ public abstract class AbstractCompany { protected readonly int _placeSizeWidth = 210; protected readonly int _placeSizeHeight = 80; + protected readonly int _placeSpacing = 20; protected readonly int _pictureWidth; protected readonly int _pictureHeight; protected IGenericObjectsCollection? _collection = null; - private int GetMaxCount => _pictureWidth * _pictureHeight / - (_placeSizeWidth * _placeSizeHeight); + private int GetMaxCount => _pictureWidth / _placeSizeWidth + * _pictureHeight / _placeSizeHeight; public AbstractCompany(int picWidth, int picHeight, IGenericObjectsCollection collection) { @@ -21,11 +24,31 @@ public abstract class AbstractCompany } public static bool operator +(AbstractCompany company, DrawingBaseLiner liner) { - return company._collection?.Insert(liner) ?? false; + try + { + company._collection?.Insert(liner); + return true; + } + catch (CollectionOverflowException) + { + throw; + } } public static bool operator -(AbstractCompany company, int position) { - return company._collection?.Remove(position) ?? false; + try + { + company._collection?.Remove(position); + return true; + } + catch (PosOutOfCollectionRangeException) + { + throw; + } + catch (ObjectNotFoundException) + { + throw; + } } public DrawingBaseLiner? GetRandomObject() @@ -38,11 +61,23 @@ public abstract class AbstractCompany Bitmap bitmap = new(_pictureWidth, _pictureHeight); Graphics graphics = Graphics.FromImage(bitmap); DrawBackgound(graphics); - SetObjectsPosition(); - for (int i = 0; i < (_collection?.Count ?? 0); ++i) + try + { + SetObjectsPosition(); + for (int i = 0; i < (_collection?.Count ?? 0); ++i) + { + try + { + DrawingBaseLiner? obj = _collection?.Get(i); + obj?.DrawTransport(graphics); + } + catch (ObjectNotFoundException) + { + } + } + } + catch (ObjectNotFoundException) { - DrawingBaseLiner? obj = _collection?.Get(i); - obj?.DrawTransport(graphics); } return bitmap; } diff --git a/ProjectLiner/ProjectLiner/GenericObjectsCollection/CollectionStorage.cs b/ProjectLiner/ProjectLiner/GenericObjectsCollection/CollectionStorage.cs index f5a3f16..8a0349b 100644 --- a/ProjectLiner/ProjectLiner/GenericObjectsCollection/CollectionStorage.cs +++ b/ProjectLiner/ProjectLiner/GenericObjectsCollection/CollectionStorage.cs @@ -1,5 +1,6 @@ using System.Text; using ProjectLiner.Drawnings; +using ProjectLiner.Exceptions; namespace ProjectLiner.GenericObjectsCollection; @@ -49,11 +50,11 @@ public class CollectionStorage private readonly string _separatorForKeyValue = "|"; private readonly string _separatorItems = ";"; - public bool SaveData(string filename) + public void SaveData(string filename) { if (_storages.Count == 0) { - return false; + throw new Exception("No data to save"); } if (File.Exists(filename)) { @@ -92,14 +93,13 @@ public class CollectionStorage using FileStream fs = new(filename, FileMode.Create); byte[] info = new UTF8Encoding(true).GetBytes(sb.ToString()); fs.Write(info, 0, info.Length); - return true; } - public bool LoadData(string filename) + public void LoadData(string filename) { if (!File.Exists(filename)) { - return false; + throw new Exception("File not found"); } string bufferTextFromFile = ""; using (FileStream fs = new(filename, FileMode.Open)) @@ -115,11 +115,11 @@ public class CollectionStorage StringSplitOptions.RemoveEmptyEntries); if (strs == null || strs.Length == 0) { - return false; + throw new Exception(filename + " is empty"); } if (!strs[0].Equals(_collectionKey)) { - return false; + throw new Exception("Invalid file format"); } _storages.Clear(); foreach (string data in strs) @@ -133,11 +133,9 @@ public class CollectionStorage CollectionType collectionType = (CollectionType)Enum.Parse(typeof(CollectionType), record[1]); IGenericObjectsCollection? collection = - CollectionStorage.CreateCollection(collectionType); - if (collection == null) - { - return false; - } + CollectionStorage.CreateCollection(collectionType) ?? + throw new Exception("Invalid collection type"); + collection.MaxCount = Convert.ToInt32(record[2]); string[] set = record[3].Split(_separatorItems, StringSplitOptions.RemoveEmptyEntries); @@ -145,15 +143,18 @@ public class CollectionStorage { if (elem?.CreateDrawingLiner() is T liner) { - if (!collection.Insert(liner)) + try { - return false; + collection.Insert(liner); + } + catch (CollectionOverflowException e) + { + throw new Exception("Collection overflow", e); } } } _storages.Add(record[0], collection); } - return true; } private static IGenericObjectsCollection? CreateCollection( diff --git a/ProjectLiner/ProjectLiner/GenericObjectsCollection/GenericObjectsCollection.cs b/ProjectLiner/ProjectLiner/GenericObjectsCollection/GenericObjectsCollection.cs index b0346bd..8a06f8e 100644 --- a/ProjectLiner/ProjectLiner/GenericObjectsCollection/GenericObjectsCollection.cs +++ b/ProjectLiner/ProjectLiner/GenericObjectsCollection/GenericObjectsCollection.cs @@ -1,4 +1,6 @@  +using ProjectLiner.Exceptions; + namespace ProjectLiner.GenericObjectsCollection; public class GenericObjectsCollection : IGenericObjectsCollection @@ -36,36 +38,45 @@ public class GenericObjectsCollection : IGenericObjectsCollection { if (position < 0 || position >= _collection.Length) { - return null; + throw new PosOutOfCollectionRangeException(position); + } + if (_collection[position] == null) + { + throw new ObjectNotFoundException("Object not found at position " + position); } return _collection[position]; } - public bool Insert(T obj) + public void Insert(T obj) { - for (int i = 0; i < _collection.Length; ++i) + try { - if (_collection[i] == null) - { - _collection[i] = obj; - return true; - } + Insert(obj, 0); + } + catch (CollectionOverflowException) + { + throw; } - return false; } - public bool Insert(T obj, int position) + public void Insert(T obj, int position) { + if (position < 0 || position >= _collection.Length) + { + throw new PosOutOfCollectionRangeException(position); + } + if (_collection[position] == null) { _collection[position] = obj; + return; } else { - while (position++ < _collection.Length) + while (position++ < _collection.Length - 1) { if (_collection[position] == null) { _collection[position] = obj; - return true; + return; } } @@ -74,20 +85,24 @@ public class GenericObjectsCollection : IGenericObjectsCollection if (_collection[position] == null) { _collection[position] = obj; - return true; + return; } } } - return false; + throw new CollectionOverflowException("Maximum number of objects has been exceeded: " + + _collection.Length); } - public bool Remove(int position) + public void Remove(int position) { + if (position < 0 || position >= _collection.Length) + { + throw new PosOutOfCollectionRangeException(position); + } if (_collection[position] == null) { - return false; + throw new ObjectNotFoundException("Object not found at position " + position); } _collection[position] = null; - return true; } public IEnumerable GetItems() diff --git a/ProjectLiner/ProjectLiner/GenericObjectsCollection/IGenericObjectsCollection.cs b/ProjectLiner/ProjectLiner/GenericObjectsCollection/IGenericObjectsCollection.cs index 5e56621..49dda06 100644 --- a/ProjectLiner/ProjectLiner/GenericObjectsCollection/IGenericObjectsCollection.cs +++ b/ProjectLiner/ProjectLiner/GenericObjectsCollection/IGenericObjectsCollection.cs @@ -5,9 +5,9 @@ public interface IGenericObjectsCollection { int Count { get; } int MaxCount { get; set; } - bool Insert(T obj); - bool Insert(T obj, int position); - bool Remove(int position); + void Insert(T obj); + void Insert(T obj, int position); + void Remove(int position); T? Get(int position); CollectionType GetCollectionType { get; } diff --git a/ProjectLiner/ProjectLiner/GenericObjectsCollection/LandingStage.cs b/ProjectLiner/ProjectLiner/GenericObjectsCollection/LandingStage.cs index ccee65d..eeeb911 100644 --- a/ProjectLiner/ProjectLiner/GenericObjectsCollection/LandingStage.cs +++ b/ProjectLiner/ProjectLiner/GenericObjectsCollection/LandingStage.cs @@ -1,4 +1,5 @@ using ProjectLiner.Drawnings; +using ProjectLiner.Exceptions; using ProjectLiner.GenericObjectsCollection; namespace ProjectLiner.CollectionGenericObjects; @@ -60,15 +61,17 @@ public class LandingStage : AbstractCompany return; } - DrawingBaseLiner? obj = _collection.Get(index); - if (obj != null) + try { - obj.SetPictureSize(_pictureWidth, _pictureHeight); + DrawingBaseLiner? obj = _collection.Get(index); + obj?.SetPictureSize(_pictureWidth, _pictureHeight); int x = i * (_placeSizeWidth); int y = j * (_placeSizeHeight); - obj.SetPosition(x + spacing, y + spacing); + obj?.SetPosition(x + spacing, y + spacing); + } + catch (ObjectNotFoundException) + { } - index++; } } diff --git a/ProjectLiner/ProjectLiner/GenericObjectsCollection/ListGenericObjects.cs b/ProjectLiner/ProjectLiner/GenericObjectsCollection/ListGenericObjects.cs index 7238ed4..3bbdbe0 100644 --- a/ProjectLiner/ProjectLiner/GenericObjectsCollection/ListGenericObjects.cs +++ b/ProjectLiner/ProjectLiner/GenericObjectsCollection/ListGenericObjects.cs @@ -1,4 +1,6 @@  +using ProjectLiner.Exceptions; + namespace ProjectLiner.GenericObjectsCollection; public class ListGenericObjects : IGenericObjectsCollection @@ -31,48 +33,50 @@ public class ListGenericObjects : IGenericObjectsCollection { if (position < 0 || position >= _collection.Count) { - return null; + throw new PosOutOfCollectionRangeException(position); + } + if (_collection[position] == null) + { + throw new ObjectNotFoundException("Object not found at position " + position); } return _collection[position]; } - public bool Insert(T obj) + public void Insert(T obj) { - if (_collection.Count < _maxCount) + if (_collection.Count == _maxCount) { - _collection.Add(obj); - return true; + throw new CollectionOverflowException("Collection is full " + _collection.Count); } - return false; + _collection.Add(obj); } - public bool Insert(T obj, int position) + public void Insert(T obj, int position) { if (position < 0 || position >= _maxCount) { - return false; + throw new PosOutOfCollectionRangeException(position); } if (position >= _collection.Count) { - _collection.AddRange(Enumerable.Repeat(default(T)!, position - _collection.Count + 1)); + _collection.AddRange(Enumerable.Repeat(default(T)!, + position - _collection.Count + 1)); } if (_collection[position] == null) { _collection[position] = obj; - return true; + return; } - - return false; + throw new CollectionOverflowException("Maximum number of objects has been exceeded: " + + _maxCount); } - public bool Remove(int position) + public void Remove(int position) { - if (position < 0 || position >= _collection.Count || - _collection[position] == null) + if (position < 0 || position >= _collection.Count) { - return false; + throw new PosOutOfCollectionRangeException(position); } _collection.RemoveAt(position); - return true; } public IEnumerable GetItems() diff --git a/ProjectLiner/ProjectLiner/Program.cs b/ProjectLiner/ProjectLiner/Program.cs index a294868..a6eb6d3 100644 --- a/ProjectLiner/ProjectLiner/Program.cs +++ b/ProjectLiner/ProjectLiner/Program.cs @@ -1,3 +1,8 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NLog.Extensions.Logging; +using Serilog; + namespace ProjectLiner { internal static class Program @@ -11,7 +16,28 @@ namespace ProjectLiner // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new FormShipCollection()); + + // Configure Serilog + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .WriteTo.Console() + .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day) + .CreateLogger(); + + ServiceCollection services = new ServiceCollection(); + ConfigureServices(services); + using ServiceProvider serviceProvider = services.BuildServiceProvider(); // Ensure BuildServiceProvider is available + Application.Run(serviceProvider.GetRequiredService()); + } + + private static void ConfigureServices(ServiceCollection services) + { + services.AddSingleton() + .AddLogging(loggingBuilder => + { + loggingBuilder.ClearProviders(); + loggingBuilder.AddSerilog(); + }); } } } \ No newline at end of file diff --git a/ProjectLiner/ProjectLiner/ProjectLiner.csproj b/ProjectLiner/ProjectLiner/ProjectLiner.csproj index af03d74..875d3c2 100644 --- a/ProjectLiner/ProjectLiner/ProjectLiner.csproj +++ b/ProjectLiner/ProjectLiner/ProjectLiner.csproj @@ -8,6 +8,16 @@ enable + + + + + + + + + + True