Skip to content

Commit 297e6d6

Browse files
committed
added json converter for encoding
fixed bookmarks not saved in PersistenceData and logexpert project sessions are also in json format fixed possible nullreference when filterparams was null / empty and a dirty search was started
1 parent 8760a15 commit 297e6d6

8 files changed

Lines changed: 129 additions & 70 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.Text;
2+
3+
using Newtonsoft.Json;
4+
5+
namespace LogExpert.Core.Classes.Persister;
6+
7+
/// <summary>
8+
/// Custom JsonConverter for Encoding objects.
9+
/// Serializes the encoding as its name (e.g. "utf-8").
10+
/// </summary>
11+
public class EncodingJsonConverter : JsonConverter
12+
{
13+
public override bool CanConvert (Type objectType)
14+
{
15+
return typeof(Encoding).IsAssignableFrom(objectType);
16+
}
17+
18+
public override void WriteJson (JsonWriter writer, object? value, JsonSerializer serializer)
19+
{
20+
ArgumentNullException.ThrowIfNull(writer);
21+
if (value is not Encoding encoding)
22+
{
23+
writer.WriteNull();
24+
return;
25+
}
26+
27+
writer.WriteValue(encoding.WebName);
28+
}
29+
30+
public override object? ReadJson (JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
31+
{
32+
ArgumentNullException.ThrowIfNull(reader);
33+
if (reader.TokenType == JsonToken.Null)
34+
{
35+
return null;
36+
}
37+
38+
var encodingName = reader.Value?.ToString();
39+
if (string.IsNullOrEmpty(encodingName))
40+
{
41+
return Encoding.Default;
42+
}
43+
44+
try
45+
{
46+
return Encoding.GetEncoding(encodingName);
47+
}
48+
catch (ArgumentException)
49+
{
50+
return Encoding.Default;
51+
}
52+
}
53+
}

src/LogExpert.Core/Classes/Persister/PersistenceData.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using LogExpert.Core.Classes.Filter;
44
using LogExpert.Core.Entities;
55

6+
using Newtonsoft.Json;
7+
68
namespace LogExpert.Core.Classes.Persister;
79

810
[Serializable]
@@ -18,6 +20,7 @@ public class PersistenceData
1820

1921
public int CurrentLine { get; set; } = -1;
2022

23+
[JsonConverter(typeof(EncodingJsonConverter))]
2124
public Encoding Encoding { get; set; }
2225

2326
public string FileName { get; set; }

src/LogExpert.Core/Classes/Persister/Persister.cs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ public static class Persister
1414

1515
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
1616

17+
private static readonly JsonSerializerSettings _jsonSettings = new()
18+
{
19+
Converters =
20+
{
21+
new ColumnizerJsonConverter(),
22+
new EncodingJsonConverter()
23+
},
24+
Formatting = Formatting.Indented,
25+
//This is needed for the BookmarkList and the Bookmark Overlay
26+
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
27+
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
28+
};
29+
1730
#endregion
1831

1932
#region Public methods
@@ -217,24 +230,16 @@ private static string BuildSessionFileNameFromPath (string logFileName)
217230
/// <param name="persistenceData">The data to be persisted. This cannot be null.</param>
218231
private static void Save (string fileName, PersistenceData persistenceData)
219232
{
220-
var settings = new JsonSerializerSettings
221-
{
222-
Converters =
223-
{
224-
new ColumnizerJsonConverter()
225-
},
226-
Formatting = Formatting.Indented,
227-
};
228-
229233
try
230234
{
231-
var json = JsonConvert.SerializeObject(persistenceData, settings);
235+
var json = JsonConvert.SerializeObject(persistenceData, _jsonSettings);
232236
File.WriteAllText(fileName, json, Encoding.UTF8);
233237
}
234-
catch (Exception ex)
238+
catch (Exception ex) when (ex is JsonSerializationException or
239+
UnauthorizedAccessException or
240+
IOException)
235241
{
236242
_logger.Error(ex, $"Error saving persistence data to {fileName}");
237-
throw;
238243
}
239244
}
240245

@@ -257,17 +262,8 @@ private static PersistenceData LoadInternal (string fileName)
257262

258263
try
259264
{
260-
var settings = new JsonSerializerSettings
261-
{
262-
Converters =
263-
{
264-
new ColumnizerJsonConverter()
265-
},
266-
Formatting = Formatting.Indented,
267-
};
268-
269265
var json = File.ReadAllText(fileName, Encoding.UTF8);
270-
var data = JsonConvert.DeserializeObject<PersistenceData>(json, settings);
266+
var data = JsonConvert.DeserializeObject<PersistenceData>(json, _jsonSettings);
271267
// Call Init on all FilterParams if needed
272268
if (data?.FilterParamsList != null)
273269
{

src/LogExpert.Core/Classes/Persister/ProjectData.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
namespace LogExpert.Core.Classes.Persister;
22

3+
[Serializable]
34
public class ProjectData
45
{
56
#region Fields
67

7-
public List<string> MemberList { get; set; } = [];
8+
/// <summary>
9+
/// Gets or sets the list of members.
10+
/// </summary>
11+
public List<string> FileNames { get; set; } = [];
812

13+
/// <summary>
14+
/// Gets or sets the XML representation of the tab layout configuration.
15+
/// </summary>
916
public string TabLayoutXml { get; set; }
1017

1118
#endregion

src/LogExpert.Core/Classes/Persister/ProjectPersister.cs

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,54 @@
1-
using System.Collections.Generic;
2-
using System.Xml;
1+
using System.Text;
2+
3+
using Newtonsoft.Json;
4+
5+
using NLog;
36

47
namespace LogExpert.Core.Classes.Persister;
58

69
public static class ProjectPersister
710
{
11+
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
12+
813
#region Public methods
914

10-
public static ProjectData LoadProjectData(string projectFileName)
15+
public static ProjectData LoadProjectData (string projectFileName)
1116
{
12-
ProjectData projectData = new();
13-
XmlDocument xmlDoc = new();
14-
xmlDoc.Load(projectFileName);
15-
var fileList = xmlDoc.GetElementsByTagName("member");
16-
foreach (XmlNode fileNode in fileList)
17+
try
1718
{
18-
var fileElement = fileNode as XmlElement;
19-
var fileName = fileElement.GetAttribute("fileName");
20-
projectData.MemberList.Add(fileName);
21-
}
19+
var settings = new JsonSerializerSettings
20+
{
21+
Formatting = Formatting.Indented,
22+
};
2223

23-
var layoutElements = xmlDoc.GetElementsByTagName("layout");
24-
if (layoutElements.Count > 0)
24+
var json = File.ReadAllText(projectFileName, Encoding.UTF8);
25+
return JsonConvert.DeserializeObject<ProjectData>(json, settings);
26+
}
27+
catch (Exception ex) when (ex is UnauthorizedAccessException or
28+
IOException)
2529
{
26-
projectData.TabLayoutXml = layoutElements[0].InnerXml;
30+
_logger.Error(ex, $"Error loading persistence data from {projectFileName}");
31+
return null;
2732
}
28-
29-
return projectData;
3033
}
3134

32-
33-
public static void SaveProjectData(string projectFileName, ProjectData projectData)
35+
public static void SaveProjectData (string projectFileName, ProjectData projectData)
3436
{
35-
XmlDocument xmlDoc = new();
36-
var rootElement = xmlDoc.CreateElement("logexpert");
37-
xmlDoc.AppendChild(rootElement);
38-
var projectElement = xmlDoc.CreateElement("project");
39-
rootElement.AppendChild(projectElement);
40-
var membersElement = xmlDoc.CreateElement("members");
41-
projectElement.AppendChild(membersElement);
42-
SaveProjectMembers(xmlDoc, membersElement, projectData.MemberList);
37+
var settings = new JsonSerializerSettings
38+
{
39+
Formatting = Formatting.Indented,
40+
};
4341

44-
if (projectData.TabLayoutXml != null)
42+
try
4543
{
46-
var layoutElement = xmlDoc.CreateElement("layout");
47-
layoutElement.InnerXml = projectData.TabLayoutXml;
48-
rootElement.AppendChild(layoutElement);
44+
var json = JsonConvert.SerializeObject(projectData, settings);
45+
File.WriteAllText(projectFileName, json, Encoding.UTF8);
4946
}
50-
51-
xmlDoc.Save(projectFileName);
52-
}
53-
54-
#endregion
55-
56-
#region Private Methods
57-
58-
private static void SaveProjectMembers(XmlDocument xmlDoc, XmlNode membersNode, List<string> memberList)
59-
{
60-
foreach (var fileName in memberList)
47+
catch (Exception ex) when (ex is JsonSerializationException or
48+
UnauthorizedAccessException or
49+
IOException)
6150
{
62-
var memberElement = xmlDoc.CreateElement("member");
63-
membersNode.AppendChild(memberElement);
64-
memberElement.SetAttribute("fileName", fileName);
51+
_logger.Error(ex, $"Error saving persistence data to {projectFileName}");
6552
}
6653
}
6754

src/LogExpert.Core/Entities/Bookmark.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
using System.Drawing;
22

3+
using Newtonsoft.Json;
4+
35
namespace LogExpert.Core.Entities;
46

57
[Serializable]
68
public class Bookmark
79
{
810
#region cTor
911

12+
[JsonConstructor]
13+
public Bookmark ()
14+
{
15+
16+
}
17+
1018
public Bookmark (int lineNum)
1119
{
1220
LineNum = lineNum;

src/LogExpert.UI/Controls/LogWindow/LogWindow.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4630,6 +4630,11 @@ private void CheckForFilterDirty ()
46304630
[SupportedOSPlatform("windows")]
46314631
private bool IsFilterSearchDirty (FilterParams filterParams)
46324632
{
4633+
if (filterParams == null || filterParams.SearchText == null)
4634+
{
4635+
return true;
4636+
}
4637+
46334638
if (!filterParams.SearchText.Equals(filterComboBox.Text, StringComparison.Ordinal))
46344639
{
46354640
return true;

src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,7 @@ private void LoadProject (string projectFileName, bool restoreLayout)
18181818

18191819
if (projectData != null)
18201820
{
1821-
foreach (var fileName in projectData.MemberList)
1821+
foreach (var fileName in projectData.FileNames)
18221822
{
18231823
if (hasLayoutData)
18241824
{
@@ -2767,7 +2767,7 @@ private void OnSaveProjectToolStripMenuItemClick (object sender, EventArgs e)
27672767

27682768
ProjectData projectData = new()
27692769
{
2770-
MemberList = fileNames,
2770+
FileNames = fileNames,
27712771
TabLayoutXml = SaveLayout()
27722772
};
27732773
ProjectPersister.SaveProjectData(fileName, projectData);

0 commit comments

Comments
 (0)