Skip to content

Commit d1608e4

Browse files
authored
Merge pull request #474 from LogExperts/470-settings-deserialization-fails-if-filterparamscurrentcolumnizer-cant-be-deserialized
added json converter for encoding and bookmarks
2 parents 8760a15 + caaeb28 commit d1608e4

File tree

8 files changed

+177
-125
lines changed

8 files changed

+177
-125
lines changed
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: 20 additions & 23 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
{
@@ -287,7 +283,8 @@ private static PersistenceData LoadInternal (string fileName)
287283

288284
return data;
289285
}
290-
catch (Exception ex) when (ex is UnauthorizedAccessException or
286+
catch (Exception ex) when (ex is JsonSerializationException or
287+
UnauthorizedAccessException or
291288
IOException)
292289
{
293290
_logger.Error(ex, $"Error loading persistence data from {fileName}");

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 new ProjectData();
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
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+
1015
public Bookmark (int lineNum)
1116
{
1217
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;

0 commit comments

Comments
 (0)