diff --git a/src/LogExpert.Core/Classes/Persister/ProjectData.cs b/src/LogExpert.Core/Classes/Persister/ProjectData.cs
deleted file mode 100644
index 5a5abd3d..00000000
--- a/src/LogExpert.Core/Classes/Persister/ProjectData.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace LogExpert.Core.Classes.Persister;
-
-[Serializable]
-public class ProjectData
-{
- #region Fields
-
- ///
- /// Gets or sets the list of members.
- ///
- public List FileNames { get; set; } = [];
-
- ///
- /// Gets or sets the XML representation of the tab layout configuration.
- ///
- public string TabLayoutXml { get; set; }
-
- ///
- /// Gets or sets the full file path to the project file.
- ///
- public string ProjectFilePath { get; set; }
-
- #endregion
-}
\ No newline at end of file
diff --git a/src/LogExpert.Core/Classes/Persister/ProjectPersister.cs b/src/LogExpert.Core/Classes/Persister/ProjectPersister.cs
deleted file mode 100644
index 877c6280..00000000
--- a/src/LogExpert.Core/Classes/Persister/ProjectPersister.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using System.Text;
-
-using LogExpert.Core.Interfaces;
-
-using Newtonsoft.Json;
-
-using NLog;
-
-namespace LogExpert.Core.Classes.Persister;
-
-public static class ProjectPersister
-{
- private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
-
- #region Public methods
-
- ///
- /// Loads the project session data from a specified file, including validation of referenced files.
- /// Resolves .lxp persistence files to actual .log files before validation.
- ///
- /// The path to the project file (.lxj)
- /// The plugin registry for file system validation
- /// A containing the project data and validation results
- public static ProjectLoadResult LoadProjectData (string projectFileName, IPluginRegistry pluginRegistry)
- {
- try
- {
- var settings = new JsonSerializerSettings
- {
- Formatting = Formatting.Indented,
- };
-
- var json = File.ReadAllText(projectFileName, Encoding.UTF8);
- var projectData = JsonConvert.DeserializeObject(json, settings);
-
- // Set project file path for alternative file search
- projectData.ProjectFilePath = projectFileName;
-
- // Resolve .lxp files to actual .log files
- var resolvedFiles = ProjectFileResolver.ResolveProjectFiles(projectData, pluginRegistry);
-
- // Create mapping: logFile → originalFile
- var logToOriginalMapping = new Dictionary();
- foreach (var (logFile, originalFile) in resolvedFiles)
- {
- logToOriginalMapping[logFile] = originalFile;
- }
-
- // Create new ProjectData with resolved log file paths
- var resolvedProjectData = new ProjectData
- {
- FileNames = [.. resolvedFiles.Select(r => r.LogFile)],
- TabLayoutXml = projectData.TabLayoutXml,
- ProjectFilePath = projectData.ProjectFilePath
- };
-
- // Validate the actual log files (not .lxp files)
- var validationResult = ProjectFileValidator.ValidateProject(resolvedProjectData, pluginRegistry);
-
- return new ProjectLoadResult
- {
- ProjectData = resolvedProjectData,
- ValidationResult = validationResult,
- LogToOriginalFileMapping = logToOriginalMapping
- };
- }
- catch (Exception ex) when (ex is UnauthorizedAccessException or
- IOException or
- JsonSerializationException)
- {
- _logger.Warn($"Error loading persistence data from {projectFileName}, trying old xml version");
-
- var projectData = ProjectPersisterXML.LoadProjectData(projectFileName);
-
- // Set project file path for alternative file search
- projectData.ProjectFilePath = projectFileName;
-
- // Resolve .lxp files for XML fallback as well
- var resolvedFiles = ProjectFileResolver.ResolveProjectFiles(projectData, pluginRegistry);
-
- var logToOriginalMapping = new Dictionary();
- foreach (var (logFile, originalFile) in resolvedFiles)
- {
- logToOriginalMapping[logFile] = originalFile;
- }
-
- var resolvedProjectData = new ProjectData
- {
- FileNames = [.. resolvedFiles.Select(r => r.LogFile)],
- TabLayoutXml = projectData.TabLayoutXml,
- ProjectFilePath = projectData.ProjectFilePath
- };
-
- var validationResult = ProjectFileValidator.ValidateProject(resolvedProjectData, pluginRegistry);
-
- return new ProjectLoadResult
- {
- ProjectData = resolvedProjectData,
- ValidationResult = validationResult,
- LogToOriginalFileMapping = logToOriginalMapping
- };
- }
- }
-
- ///
- /// Saves the specified project data to a file in JSON format.
- ///
- /// The method serializes the into a JSON string with indented
- /// formatting and writes it to the specified using UTF-8 encoding.
- /// The path to the file where the project data will be saved. Cannot be null or empty.
- /// The project data to be serialized and saved. Cannot be null.
- public static void SaveProjectData (string projectFileName, ProjectData projectData)
- {
- var settings = new JsonSerializerSettings
- {
- Formatting = Formatting.Indented,
- };
-
- try
- {
- var json = JsonConvert.SerializeObject(projectData, settings);
- File.WriteAllText(projectFileName, json, Encoding.UTF8);
- }
- catch (Exception ex) when (ex is JsonSerializationException or
- UnauthorizedAccessException or
- IOException)
- {
- _logger.Error(ex, $"Error saving persistence data to {projectFileName}");
- }
- }
-
- #endregion
-}
\ No newline at end of file
diff --git a/src/LogExpert.Core/Classes/Persister/SessionData.cs b/src/LogExpert.Core/Classes/Persister/SessionData.cs
new file mode 100644
index 00000000..001d6780
--- /dev/null
+++ b/src/LogExpert.Core/Classes/Persister/SessionData.cs
@@ -0,0 +1,38 @@
+using Newtonsoft.Json;
+
+namespace LogExpert.Core.Classes.Persister;
+
+///
+/// Persisted workspace contents of a Session (.lxj): a list of log file paths
+/// plus a tab/window layout XML blob. See CONTEXT.md "Sessions".
+///
+[Serializable]
+public class SessionData
+{
+ #region Fields
+
+ ///
+ /// Gets or sets the list of log file paths included in this Session.
+ /// May contain references to Session File (.lxp) entries that resolve to logs.
+ ///
+ public List FileNames { get; set; } = [];
+
+ ///
+ /// Gets or sets the XML representation of the tab layout configuration.
+ ///
+ public string TabLayoutXml { get; set; }
+
+ ///
+ /// Gets or sets the full file path to the Session (.lxj) on disk.
+ ///
+ ///
+ /// JSON property name pinned to "SessionFilePath" so existing .lxj files (which
+ /// were written under the previous "Project" terminology) continue to deserialize
+ /// without migration. The value is also re-set at load time from the file path,
+ /// so even old files without this key load correctly.
+ ///
+ [JsonProperty("SessionFilePath")]
+ public string SessionFilePath { get; set; }
+
+ #endregion
+}
diff --git a/src/LogExpert.Core/Classes/Persister/ProjectFileResolver.cs b/src/LogExpert.Core/Classes/Persister/SessionFileResolver.cs
similarity index 58%
rename from src/LogExpert.Core/Classes/Persister/ProjectFileResolver.cs
rename to src/LogExpert.Core/Classes/Persister/SessionFileResolver.cs
index 8ae60bba..6499ec99 100644
--- a/src/LogExpert.Core/Classes/Persister/ProjectFileResolver.cs
+++ b/src/LogExpert.Core/Classes/Persister/SessionFileResolver.cs
@@ -5,25 +5,25 @@
namespace LogExpert.Core.Classes.Persister;
///
-/// Helper class to resolve project file references to actual log files.
-/// Handles .lxp (persistence) files by extracting the actual log file path.
+/// Helper class to resolve Session file references to actual log files.
+/// Handles Session File (.lxp) entries by extracting the actual log file path.
///
-public static class ProjectFileResolver
+public static class SessionFileResolver
{
///
- /// Resolves project file names to actual log files.
- /// If a file is a .lxp persistence file, extracts the log file path from it.
+ /// Resolves Session file names to actual log files.
+ /// If a file is a Session File (.lxp) entry, extracts the log file path from it.
///
- /// The project data containing file references
+ /// The Session data containing file references
/// Plugin registry for file system resolution (optional)
/// List of tuples containing (logFilePath, originalFilePath)
- public static ReadOnlyCollection<(string LogFile, string OriginalFile)> ResolveProjectFiles (ProjectData projectData, IPluginRegistry pluginRegistry = null)
+ public static ReadOnlyCollection<(string LogFile, string OriginalFile)> ResolveSessionFiles (SessionData sessionData, IPluginRegistry pluginRegistry = null)
{
- ArgumentNullException.ThrowIfNull(projectData);
+ ArgumentNullException.ThrowIfNull(sessionData);
var resolved = new List<(string LogFile, string OriginalFile)>();
- foreach (var fileName in projectData.FileNames)
+ foreach (var fileName in sessionData.FileNames)
{
var logFile = PersisterHelpers.FindFilenameForSettings(fileName, pluginRegistry);
resolved.Add((logFile, fileName));
@@ -31,4 +31,4 @@ public static class ProjectFileResolver
return resolved.AsReadOnly();
}
-}
\ No newline at end of file
+}
diff --git a/src/LogExpert.Core/Classes/Persister/ProjectFileValidator.cs b/src/LogExpert.Core/Classes/Persister/SessionFileValidator.cs
similarity index 90%
rename from src/LogExpert.Core/Classes/Persister/ProjectFileValidator.cs
rename to src/LogExpert.Core/Classes/Persister/SessionFileValidator.cs
index dd8ebd0f..5344a94d 100644
--- a/src/LogExpert.Core/Classes/Persister/ProjectFileValidator.cs
+++ b/src/LogExpert.Core/Classes/Persister/SessionFileValidator.cs
@@ -12,7 +12,7 @@ namespace LogExpert.Core.Classes.Persister;
/// path. It supports validation of both local file paths and URI-based files through plugin resolution. All methods are
/// thread-safe and do not modify input data. Use the provided methods to check file existence, resolve canonical file
/// paths, and locate possible alternatives for missing files.
-public static class ProjectFileValidator
+public static class SessionFileValidator
{
///
/// Validates the files referenced by the specified project and identifies missing or accessible files using
@@ -21,21 +21,21 @@ public static class ProjectFileValidator
/// Files are considered valid if they exist on disk or if a suitable file system plugin is
/// available for URI-based files. For missing files, possible alternative paths are suggested based on the project
/// file location.
- /// The project data containing the list of file names to validate and the project file path. Cannot be null.
+ /// The project data containing the list of file names to validate and the project file path. Cannot be null.
/// The plugin registry used to resolve file system plugins for URI-based files. Cannot be null.
- /// A ProjectValidationResult containing lists of valid files, missing files, and possible alternative file paths
+ /// A SessionValidationResult containing lists of valid files, missing files, and possible alternative file paths
/// for missing files.
- public static ProjectValidationResult ValidateProject (ProjectData projectData, IPluginRegistry pluginRegistry)
+ public static SessionValidationResult ValidateSession (SessionData sessionData, IPluginRegistry pluginRegistry)
{
- ArgumentNullException.ThrowIfNull(projectData);
+ ArgumentNullException.ThrowIfNull(sessionData);
ArgumentNullException.ThrowIfNull(pluginRegistry);
- var result = new ProjectValidationResult();
+ var result = new SessionValidationResult();
// Cache drive letters once to avoid repeated expensive DriveInfo.GetDrives() calls
var cachedDriveLetters = GetFixedDriveLetters();
- foreach (var fileName in projectData.FileNames)
+ foreach (var fileName in sessionData.FileNames)
{
var normalizedPath = NormalizeFilePath(fileName);
@@ -60,7 +60,7 @@ public static ProjectValidationResult ValidateProject (ProjectData projectData,
{
result.MissingFiles.Add(fileName);
- var alternativePaths = FindAlternativePaths(fileName, projectData.ProjectFilePath, cachedDriveLetters);
+ var alternativePaths = FindAlternativePaths(fileName, sessionData.SessionFilePath, cachedDriveLetters);
result.PossibleAlternatives[fileName] = alternativePaths;
}
}
@@ -138,12 +138,12 @@ or DriveNotFoundException
/// result.
/// The name or path of the file to search for. Can be an absolute or relative path. Cannot be null, empty, or
/// whitespace.
- /// The full path to the project file used as a reference for searching related directories. Can be null or empty if
+ /// The full path to the project file used as a reference for searching related directories. Can be null or empty if
/// project context is not available.
/// Pre-computed list of fixed drive letters to avoid repeated DriveInfo.GetDrives() calls.
/// A list of strings containing the full paths of files found that match the specified file name in alternative
/// locations. The list will be empty if no matching files are found.
- private static List FindAlternativePaths (string fileName, string projectFilePath, List cachedDriveLetters)
+ private static List FindAlternativePaths (string fileName, string sessionFilePath, List cachedDriveLetters)
{
var alternatives = new List();
@@ -160,21 +160,21 @@ private static List FindAlternativePaths (string fileName, string projec
}
// Search in directory of .lxj project file
- if (!string.IsNullOrWhiteSpace(projectFilePath))
+ if (!string.IsNullOrWhiteSpace(sessionFilePath))
{
try
{
- var projectDir = Path.GetDirectoryName(projectFilePath);
- if (!string.IsNullOrEmpty(projectDir) && Directory.Exists(projectDir))
+ var sessionDir = Path.GetDirectoryName(sessionFilePath);
+ if (!string.IsNullOrEmpty(sessionDir) && Directory.Exists(sessionDir))
{
- var candidatePath = Path.Join(projectDir, baseName);
+ var candidatePath = Path.Join(sessionDir, baseName);
if (File.Exists(candidatePath))
{
alternatives.Add(candidatePath);
}
// Also check subdirectories (one level deep)
- var subdirs = Directory.GetDirectories(projectDir);
+ var subdirs = Directory.GetDirectories(sessionDir);
alternatives.AddRange(
subdirs
.Select(subdir => Path.Join(subdir, baseName))
@@ -243,14 +243,14 @@ UnauthorizedAccessException or
}
// Try relative path resolution from project directory
- if (!Path.IsPathRooted(fileName) && !string.IsNullOrWhiteSpace(projectFilePath))
+ if (!Path.IsPathRooted(fileName) && !string.IsNullOrWhiteSpace(sessionFilePath))
{
try
{
- var projectDir = Path.GetDirectoryName(projectFilePath);
- if (!string.IsNullOrEmpty(projectDir))
+ var sessionDir = Path.GetDirectoryName(sessionFilePath);
+ if (!string.IsNullOrEmpty(sessionDir))
{
- var relativePath = Path.Join(projectDir, fileName);
+ var relativePath = Path.Join(sessionDir, fileName);
var normalizedPath = Path.GetFullPath(relativePath);
if (File.Exists(normalizedPath) && !alternatives.Contains(normalizedPath))
diff --git a/src/LogExpert.Core/Classes/Persister/ProjectLoadResult.cs b/src/LogExpert.Core/Classes/Persister/SessionLoadResult.cs
similarity index 88%
rename from src/LogExpert.Core/Classes/Persister/ProjectLoadResult.cs
rename to src/LogExpert.Core/Classes/Persister/SessionLoadResult.cs
index 83b15ceb..72a919e9 100644
--- a/src/LogExpert.Core/Classes/Persister/ProjectLoadResult.cs
+++ b/src/LogExpert.Core/Classes/Persister/SessionLoadResult.cs
@@ -3,17 +3,17 @@ namespace LogExpert.Core.Classes.Persister;
///
/// Represents the result of loading a project file, including validation information.
///
-public class ProjectLoadResult
+public class SessionLoadResult
{
///
/// The loaded project data (contains resolved log file paths).
///
- public ProjectData ProjectData { get; set; }
+ public SessionData SessionData { get; set; }
///
/// Validation result containing valid, missing, and alternative file paths.
///
- public ProjectValidationResult ValidationResult { get; set; }
+ public SessionValidationResult ValidationResult { get; set; }
///
/// Mapping of original file references to resolved log files.
diff --git a/src/LogExpert.Core/Classes/Persister/SessionPersister.cs b/src/LogExpert.Core/Classes/Persister/SessionPersister.cs
new file mode 100644
index 00000000..7a26a38e
--- /dev/null
+++ b/src/LogExpert.Core/Classes/Persister/SessionPersister.cs
@@ -0,0 +1,133 @@
+using System.Text;
+
+using LogExpert.Core.Interfaces;
+
+using Newtonsoft.Json;
+
+using NLog;
+
+namespace LogExpert.Core.Classes.Persister;
+
+public static class SessionPersister
+{
+ private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
+
+ #region Public methods
+
+ ///
+ /// Loads a Session (.lxj) from disk, including validation of referenced files.
+ /// Resolves Session File (.lxp) entries to actual .log files before validation.
+ ///
+ /// The path to the Session file (.lxj)
+ /// The plugin registry for file system validation
+ /// A containing the session data and validation results
+ public static SessionLoadResult LoadSessionData (string sessionFileName, IPluginRegistry pluginRegistry)
+ {
+ try
+ {
+ var settings = new JsonSerializerSettings
+ {
+ Formatting = Formatting.Indented,
+ };
+
+ var json = File.ReadAllText(sessionFileName, Encoding.UTF8);
+ var sessionData = JsonConvert.DeserializeObject(json, settings);
+
+ // Set Session file path for alternative file search
+ sessionData.SessionFilePath = sessionFileName;
+
+ // Resolve Session File (.lxp) entries to actual .log files
+ var resolvedFiles = SessionFileResolver.ResolveSessionFiles(sessionData, pluginRegistry);
+
+ // Create mapping: logFile → originalFile
+ var logToOriginalMapping = new Dictionary();
+ foreach (var (logFile, originalFile) in resolvedFiles)
+ {
+ logToOriginalMapping[logFile] = originalFile;
+ }
+
+ // Create new SessionData with resolved log file paths
+ var resolvedSessionData = new SessionData
+ {
+ FileNames = [.. resolvedFiles.Select(r => r.LogFile)],
+ TabLayoutXml = sessionData.TabLayoutXml,
+ SessionFilePath = sessionData.SessionFilePath
+ };
+
+ // Validate the actual log files (not Session File .lxp entries)
+ var validationResult = SessionFileValidator.ValidateSession(resolvedSessionData, pluginRegistry);
+
+ return new SessionLoadResult
+ {
+ SessionData = resolvedSessionData,
+ ValidationResult = validationResult,
+ LogToOriginalFileMapping = logToOriginalMapping
+ };
+ }
+ catch (Exception ex) when (ex is UnauthorizedAccessException or
+ IOException or
+ JsonSerializationException)
+ {
+ _logger.Warn($"Error loading session data from {sessionFileName}, trying old xml version");
+
+ var sessionData = SessionPersisterXML.LoadSessionData(sessionFileName);
+
+ // Set Session file path for alternative file search
+ sessionData.SessionFilePath = sessionFileName;
+
+ // Resolve Session File (.lxp) entries for XML fallback as well
+ var resolvedFiles = SessionFileResolver.ResolveSessionFiles(sessionData, pluginRegistry);
+
+ var logToOriginalMapping = new Dictionary();
+ foreach (var (logFile, originalFile) in resolvedFiles)
+ {
+ logToOriginalMapping[logFile] = originalFile;
+ }
+
+ var resolvedSessionData = new SessionData
+ {
+ FileNames = [.. resolvedFiles.Select(r => r.LogFile)],
+ TabLayoutXml = sessionData.TabLayoutXml,
+ SessionFilePath = sessionData.SessionFilePath
+ };
+
+ var validationResult = SessionFileValidator.ValidateSession(resolvedSessionData, pluginRegistry);
+
+ return new SessionLoadResult
+ {
+ SessionData = resolvedSessionData,
+ ValidationResult = validationResult,
+ LogToOriginalFileMapping = logToOriginalMapping
+ };
+ }
+ }
+
+ ///
+ /// Saves the specified Session data to a file in JSON format.
+ ///
+ /// The method serializes the into a JSON string with indented
+ /// formatting and writes it to the specified using UTF-8 encoding.
+ /// The path to the file where the Session data will be saved. Cannot be null or empty.
+ /// The Session data to be serialized and saved. Cannot be null.
+ public static void SaveSessionData (string sessionFileName, SessionData sessionData)
+ {
+ var settings = new JsonSerializerSettings
+ {
+ Formatting = Formatting.Indented,
+ };
+
+ try
+ {
+ var json = JsonConvert.SerializeObject(sessionData, settings);
+ File.WriteAllText(sessionFileName, json, Encoding.UTF8);
+ }
+ catch (Exception ex) when (ex is JsonSerializationException or
+ UnauthorizedAccessException or
+ IOException)
+ {
+ _logger.Error(ex, $"Error saving session data to {sessionFileName}");
+ }
+ }
+
+ #endregion
+}
diff --git a/src/LogExpert.Core/Classes/Persister/ProjectPersisterXML.cs b/src/LogExpert.Core/Classes/Persister/SessionPersisterXML.cs
similarity index 52%
rename from src/LogExpert.Core/Classes/Persister/ProjectPersisterXML.cs
rename to src/LogExpert.Core/Classes/Persister/SessionPersisterXML.cs
index 618b925e..5e51cc4e 100644
--- a/src/LogExpert.Core/Classes/Persister/ProjectPersisterXML.cs
+++ b/src/LogExpert.Core/Classes/Persister/SessionPersisterXML.cs
@@ -4,50 +4,54 @@
namespace LogExpert.Core.Classes.Persister;
-public static class ProjectPersisterXML
+///
+/// Legacy XML loader for Session (.lxj) files written under the older XML format.
+/// Used as a fallback when JSON deserialization fails. See .
+///
+public static class SessionPersisterXML
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
///
- /// Loads project data from the specified XML file.
+ /// Loads Session data from a legacy XML-format .lxj file.
///
/// The method reads the XML file to extract file names and layout information. If the XML file
/// contains a layout element, its inner XML is stored in the TabLayoutXml property of the returned
- /// object. If any exception occurs during the loading process, an error is logged, and an
- /// empty object is returned.
- /// The path to the XML file containing the project data.
- /// A object populated with file names and layout information from the XML file. If an
- /// error occurs during loading, an empty object is returned.
- public static ProjectData LoadProjectData (string projectFileName)
+ /// object. If any exception occurs during loading, an error is logged and an
+ /// empty object is returned.
+ /// The path to the XML file containing the Session data.
+ /// A object populated with file names and layout information from the XML file. If an
+ /// error occurs during loading, an empty object is returned.
+ public static SessionData LoadSessionData (string sessionFileName)
{
- var projectData = new ProjectData();
+ var sessionData = new SessionData();
var xmlDoc = new XmlDocument();
try
{
- xmlDoc.Load(projectFileName);
+ xmlDoc.Load(sessionFileName);
var fileList = xmlDoc.GetElementsByTagName("member");
foreach (XmlNode fileNode in fileList)
{
var fileElement = fileNode as XmlElement;
var fileName = fileElement.GetAttribute("fileName");
- projectData.FileNames.Add(fileName);
+ sessionData.FileNames.Add(fileName);
}
var layoutElements = xmlDoc.GetElementsByTagName("layout");
if (layoutElements.Count > 0)
{
- projectData.TabLayoutXml = layoutElements[0].InnerXml;
+ sessionData.TabLayoutXml = layoutElements[0].InnerXml;
}
- return projectData;
+ return sessionData;
}
catch (Exception xmlParsingException) when (xmlParsingException is XmlException or
UnauthorizedAccessException or
IOException)
{
- _logger.Error(xmlParsingException, $"Error loading persistence data from {projectFileName}, unknown format, parsing xml or json was not possible");
- return new ProjectData();
+ _logger.Error(xmlParsingException, $"Error loading Session data from {sessionFileName}, unknown format, parsing xml or json was not possible");
+ return new SessionData();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/LogExpert.Core/Classes/Persister/ProjectValidationResult.cs b/src/LogExpert.Core/Classes/Persister/SessionValidationResult.cs
similarity index 88%
rename from src/LogExpert.Core/Classes/Persister/ProjectValidationResult.cs
rename to src/LogExpert.Core/Classes/Persister/SessionValidationResult.cs
index fed2d742..3d570db2 100644
--- a/src/LogExpert.Core/Classes/Persister/ProjectValidationResult.cs
+++ b/src/LogExpert.Core/Classes/Persister/SessionValidationResult.cs
@@ -1,6 +1,6 @@
namespace LogExpert.Core.Classes.Persister;
-public class ProjectValidationResult
+public class SessionValidationResult
{
public List ValidFiles { get; } = [];
diff --git a/src/LogExpert.Core/Enums/ProjectLoadDlgResult.cs b/src/LogExpert.Core/Enums/SessionLoadDlgResult.cs
similarity index 74%
rename from src/LogExpert.Core/Enums/ProjectLoadDlgResult.cs
rename to src/LogExpert.Core/Enums/SessionLoadDlgResult.cs
index c32b6c2c..7386d8c7 100644
--- a/src/LogExpert.Core/Enums/ProjectLoadDlgResult.cs
+++ b/src/LogExpert.Core/Enums/SessionLoadDlgResult.cs
@@ -1,6 +1,6 @@
namespace LogExpert.Core.Enums;
-public enum ProjectLoadDlgResult
+public enum SessionLoadDlgResult
{
Cancel,
CloseTabs,
diff --git a/src/LogExpert.Persister.Tests/ProjectFileValidatorTests.cs b/src/LogExpert.Persister.Tests/SessionFileValidatorTests.cs
similarity index 86%
rename from src/LogExpert.Persister.Tests/ProjectFileValidatorTests.cs
rename to src/LogExpert.Persister.Tests/SessionFileValidatorTests.cs
index e030fe0b..fae0e744 100644
--- a/src/LogExpert.Persister.Tests/ProjectFileValidatorTests.cs
+++ b/src/LogExpert.Persister.Tests/SessionFileValidatorTests.cs
@@ -7,10 +7,10 @@ namespace LogExpert.Persister.Tests;
///
/// Unit tests for the Project File Validator implementation (Issue #514).
/// Tests validation logic for missing files in project/session loading.
-/// Includes tests for ProjectFileResolver, PersisterHelpers, and ProjectPersister updates.
+/// Includes tests for SessionFileResolver, PersisterHelpers, and SessionPersister updates.
///
[TestFixture]
-public class ProjectFileValidatorTests
+public class SessionFileValidatorTests
{
private string _testDirectory;
private string _projectFile;
@@ -20,7 +20,7 @@ public class ProjectFileValidatorTests
public void Setup ()
{
// Create temporary test directory
- _testDirectory = Path.Join(Path.GetTempPath(), "LogExpertTests", "ProjectValidator", Guid.NewGuid().ToString());
+ _testDirectory = Path.Join(Path.GetTempPath(), "LogExpertTests", "SessionValidator", Guid.NewGuid().ToString());
_ = Directory.CreateDirectory(_testDirectory);
// Initialize test log files list
@@ -71,13 +71,13 @@ private void CreateTestLogFiles (params string[] fileNames)
///
private void CreateTestProjectFile (params string[] logFileNames)
{
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = [.. logFileNames.Select(name => Path.Join(_testDirectory, name))],
TabLayoutXml = "test"
};
- ProjectPersister.SaveProjectData(_projectFile, projectData);
+ SessionPersister.SaveSessionData(_projectFile, sessionData);
}
///
@@ -221,14 +221,14 @@ public void PersisterHelpers_FindFilenameForSettings_CorruptedLxp_ReturnsLxpPath
#endregion
- #region ProjectFileResolver Tests
+ #region SessionFileResolver Tests
[Test]
public void ProjectFileResolver_ResolveProjectFiles_AllLogFiles_ReturnsUnchanged ()
{
// Arrange
CreateTestLogFiles("file1.log", "file2.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames =
[
@@ -238,7 +238,7 @@ public void ProjectFileResolver_ResolveProjectFiles_AllLogFiles_ReturnsUnchanged
};
// Act
- var result = ProjectFileResolver.ResolveProjectFiles(projectData, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionFileResolver.ResolveSessionFiles(sessionData, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Has.Count.EqualTo(2));
@@ -256,7 +256,7 @@ public void ProjectFileResolver_ResolveProjectFiles_WithLxpFiles_ResolvesToLogs
CreatePersistenceFile("settings1.lxp", "actual1.log");
CreatePersistenceFile("settings2.lxp", "actual2.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames =
[
@@ -266,7 +266,7 @@ public void ProjectFileResolver_ResolveProjectFiles_WithLxpFiles_ResolvesToLogs
};
// Act
- var result = ProjectFileResolver.ResolveProjectFiles(projectData, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionFileResolver.ResolveSessionFiles(sessionData, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Has.Count.EqualTo(2));
@@ -283,7 +283,7 @@ public void ProjectFileResolver_ResolveProjectFiles_MixedFiles_ResolvesProperly
CreateTestLogFiles("direct.log", "referenced.log");
CreatePersistenceFile("indirect.lxp", "referenced.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames =
[
@@ -293,7 +293,7 @@ public void ProjectFileResolver_ResolveProjectFiles_MixedFiles_ResolvesProperly
};
// Act
- var result = ProjectFileResolver.ResolveProjectFiles(projectData, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionFileResolver.ResolveSessionFiles(sessionData, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Has.Count.EqualTo(2));
@@ -308,20 +308,20 @@ public void ProjectFileResolver_ResolveProjectFiles_NullProjectData_ThrowsArgume
{
// Act & Assert
_ = Assert.Throws(() =>
- ProjectFileResolver.ResolveProjectFiles(null, PluginRegistry.PluginRegistry.Instance));
+ SessionFileResolver.ResolveSessionFiles(null, PluginRegistry.PluginRegistry.Instance));
}
[Test]
public void ProjectFileResolver_ResolveProjectFiles_EmptyProject_ReturnsEmptyList ()
{
// Arrange
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = []
};
// Act
- var result = ProjectFileResolver.ResolveProjectFiles(projectData, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionFileResolver.ResolveSessionFiles(sessionData, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Empty, "Empty project should return empty list");
@@ -332,13 +332,13 @@ public void ProjectFileResolver_ResolveProjectFiles_ReturnsReadOnlyCollection ()
{
// Arrange
CreateTestLogFiles("test.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = [Path.Join(_testDirectory, "test.log")]
};
// Act
- var result = ProjectFileResolver.ResolveProjectFiles(projectData, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionFileResolver.ResolveSessionFiles(sessionData, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.InstanceOf>());
@@ -346,20 +346,20 @@ public void ProjectFileResolver_ResolveProjectFiles_ReturnsReadOnlyCollection ()
#endregion
- #region ProjectLoadResult Tests
+ #region SessionLoadResult Tests
[Test]
public void ProjectLoadResult_HasValidFiles_AllFilesValid_ReturnsTrue ()
{
// Arrange
- var projectData = new ProjectData();
- var validationResult = new ProjectValidationResult();
+ var sessionData = new SessionData();
+ var validationResult = new SessionValidationResult();
validationResult.ValidFiles.Add("file1.log");
validationResult.ValidFiles.Add("file2.log");
- var result = new ProjectLoadResult
+ var result = new SessionLoadResult
{
- ProjectData = projectData,
+ SessionData = sessionData,
ValidationResult = validationResult
};
@@ -374,14 +374,14 @@ public void ProjectLoadResult_HasValidFiles_AllFilesValid_ReturnsTrue ()
public void ProjectLoadResult_HasValidFiles_NoValidFiles_ReturnsFalse ()
{
// Arrange
- var projectData = new ProjectData();
- var validationResult = new ProjectValidationResult();
+ var sessionData = new SessionData();
+ var validationResult = new SessionValidationResult();
validationResult.MissingFiles.Add("file1.log");
validationResult.MissingFiles.Add("file2.log");
- var result = new ProjectLoadResult
+ var result = new SessionLoadResult
{
- ProjectData = projectData,
+ SessionData = sessionData,
ValidationResult = validationResult
};
@@ -396,15 +396,15 @@ public void ProjectLoadResult_HasValidFiles_NoValidFiles_ReturnsFalse ()
public void ProjectLoadResult_HasValidFiles_SomeValidFiles_ReturnsTrue ()
{
// Arrange
- var projectData = new ProjectData();
- var validationResult = new ProjectValidationResult();
+ var sessionData = new SessionData();
+ var validationResult = new SessionValidationResult();
validationResult.ValidFiles.Add("file1.log");
validationResult.MissingFiles.Add("file2.log");
validationResult.MissingFiles.Add("file3.log");
- var result = new ProjectLoadResult
+ var result = new SessionLoadResult
{
- ProjectData = projectData,
+ SessionData = sessionData,
ValidationResult = validationResult
};
@@ -419,14 +419,14 @@ public void ProjectLoadResult_HasValidFiles_SomeValidFiles_ReturnsTrue ()
public void ProjectLoadResult_RequiresUserIntervention_AllFilesValid_ReturnsFalse ()
{
// Arrange
- var projectData = new ProjectData();
- var validationResult = new ProjectValidationResult();
+ var sessionData = new SessionData();
+ var validationResult = new SessionValidationResult();
validationResult.ValidFiles.Add("file1.log");
validationResult.ValidFiles.Add("file2.log");
- var result = new ProjectLoadResult
+ var result = new SessionLoadResult
{
- ProjectData = projectData,
+ SessionData = sessionData,
ValidationResult = validationResult
};
@@ -441,14 +441,14 @@ public void ProjectLoadResult_RequiresUserIntervention_AllFilesValid_ReturnsFals
public void ProjectLoadResult_RequiresUserIntervention_SomeMissingFiles_ReturnsTrue ()
{
// Arrange
- var projectData = new ProjectData();
- var validationResult = new ProjectValidationResult();
+ var sessionData = new SessionData();
+ var validationResult = new SessionValidationResult();
validationResult.ValidFiles.Add("file1.log");
validationResult.MissingFiles.Add("file2.log");
- var result = new ProjectLoadResult
+ var result = new SessionLoadResult
{
- ProjectData = projectData,
+ SessionData = sessionData,
ValidationResult = validationResult
};
@@ -469,7 +469,7 @@ public void ProjectLoadResult_LogToOriginalFileMapping_StoresMapping ()
["C:\\logs\\direct.log"] = "C:\\logs\\direct.log"
};
- var result = new ProjectLoadResult
+ var result = new SessionLoadResult
{
LogToOriginalFileMapping = mapping
};
@@ -482,13 +482,13 @@ public void ProjectLoadResult_LogToOriginalFileMapping_StoresMapping ()
#endregion
- #region ProjectValidationResult Tests
+ #region SessionValidationResult Tests
[Test]
public void ProjectValidationResult_HasMissingFiles_WithMissingFiles_ReturnsTrue ()
{
// Arrange
- var result = new ProjectValidationResult();
+ var result = new SessionValidationResult();
result.ValidFiles.Add("file1.log");
result.MissingFiles.Add("file2.log");
@@ -503,7 +503,7 @@ public void ProjectValidationResult_HasMissingFiles_WithMissingFiles_ReturnsTrue
public void ProjectValidationResult_HasMissingFiles_WithoutMissingFiles_ReturnsFalse ()
{
// Arrange
- var result = new ProjectValidationResult();
+ var result = new SessionValidationResult();
result.ValidFiles.Add("file1.log");
result.ValidFiles.Add("file2.log");
@@ -516,7 +516,7 @@ public void ProjectValidationResult_HasMissingFiles_WithoutMissingFiles_ReturnsF
#endregion
- #region ProjectPersister.LoadProjectData - All Files Valid
+ #region SessionPersister.LoadSessionData - All Files Valid
[Test]
public void LoadProjectData_AllFilesExist_ReturnsSuccessResult ()
@@ -526,11 +526,11 @@ public void LoadProjectData_AllFilesExist_ReturnsSuccessResult ()
CreateTestProjectFile("log1.log", "log2.log", "log3.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null, "Result should not be null");
- Assert.That(result.ProjectData, Is.Not.Null, "ProjectData should not be null");
+ Assert.That(result.SessionData, Is.Not.Null, "SessionData should not be null");
Assert.That(result.ValidationResult, Is.Not.Null, "ValidationResult should not be null");
Assert.That(result.HasValidFiles, Is.True, "Should have valid files");
Assert.That(result.RequiresUserIntervention, Is.False, "Should not require intervention");
@@ -546,10 +546,10 @@ public void LoadProjectData_AllFilesExist_ProjectDataContainsCorrectFiles ()
CreateTestProjectFile("alpha.log", "beta.log", "gamma.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
- var fileNames = result.ProjectData.FileNames.Select(Path.GetFileName).ToList();
+ var fileNames = result.SessionData.FileNames.Select(Path.GetFileName).ToList();
Assert.That(fileNames, Does.Contain("alpha.log"), "Should contain alpha.log");
Assert.That(fileNames, Does.Contain("beta.log"), "Should contain beta.log");
Assert.That(fileNames, Does.Contain("gamma.log"), "Should contain gamma.log");
@@ -563,11 +563,11 @@ public void LoadProjectData_AllFilesExist_PreservesTabLayoutXml ()
CreateTestProjectFile("test.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
- Assert.That(result.ProjectData.TabLayoutXml, Is.Not.Null.And.Not.Empty, "TabLayoutXml should be preserved");
- Assert.That(result.ProjectData.TabLayoutXml, Does.Contain(""), "Should contain layout XML");
+ Assert.That(result.SessionData.TabLayoutXml, Is.Not.Null.And.Not.Empty, "TabLayoutXml should be preserved");
+ Assert.That(result.SessionData.TabLayoutXml, Does.Contain(""), "Should contain layout XML");
}
[Test]
@@ -579,7 +579,7 @@ public void LoadProjectData_WithLxpFiles_ResolvesToActualLogs ()
CreatePersistenceFile("settings2.lxp", "actual2.log");
// Create project referencing .lxp files
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames =
[
@@ -587,15 +587,15 @@ public void LoadProjectData_WithLxpFiles_ResolvesToActualLogs ()
Path.Join(_testDirectory, "settings2.lxp")
]
};
- ProjectPersister.SaveProjectData(_projectFile, projectData);
+ SessionPersister.SaveSessionData(_projectFile, sessionData);
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null);
Assert.That(result.ValidationResult.ValidFiles.Count, Is.EqualTo(2), "Should validate actual log files");
- var fileNames = result.ProjectData.FileNames.Select(Path.GetFileName).ToList();
+ var fileNames = result.SessionData.FileNames.Select(Path.GetFileName).ToList();
Assert.That(fileNames, Does.Contain("actual1.log"), "Should contain resolved log file");
Assert.That(fileNames, Does.Contain("actual2.log"), "Should contain resolved log file");
}
@@ -607,14 +607,14 @@ public void LoadProjectData_WithLxpFiles_PreservesMapping ()
CreateTestLogFiles("actual.log");
CreatePersistenceFile("settings.lxp", "actual.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = [Path.Join(_testDirectory, "settings.lxp")]
};
- ProjectPersister.SaveProjectData(_projectFile, projectData);
+ SessionPersister.SaveSessionData(_projectFile, sessionData);
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result.LogToOriginalFileMapping, Is.Not.Null);
@@ -626,7 +626,7 @@ public void LoadProjectData_WithLxpFiles_PreservesMapping ()
#endregion
- #region ProjectPersister.LoadProjectData - Some Files Missing
+ #region SessionPersister.LoadSessionData - Some Files Missing
[Test]
public void LoadProjectData_SomeFilesMissing_ReturnsPartialSuccessResult ()
@@ -637,7 +637,7 @@ public void LoadProjectData_SomeFilesMissing_ReturnsPartialSuccessResult ()
CreateTestProjectFile("exists1.log", "exists2.log", "missing.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null, "Result should not be null");
@@ -656,7 +656,7 @@ public void LoadProjectData_SomeFilesMissing_ValidFilesListIsCorrect ()
CreateTestProjectFile("valid1.log", "valid2.log", "invalid.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
var validFileNames = result.ValidationResult.ValidFiles.Select(Path.GetFileName).ToList();
@@ -674,7 +674,7 @@ public void LoadProjectData_SomeFilesMissing_MissingFilesListIsCorrect ()
CreateTestProjectFile("present.log", "absent1.log", "absent2.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
var missingFileNames = result.ValidationResult.MissingFiles.Select(Path.GetFileName).ToList();
@@ -692,7 +692,7 @@ public void LoadProjectData_MajorityFilesMissing_StillReturnsValidFiles ()
CreateTestProjectFile("only_valid.log", "missing1.log", "missing2.log", "missing3.log", "missing4.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result.HasValidFiles, Is.True, "Should have at least one valid file");
@@ -708,14 +708,14 @@ public void LoadProjectData_LxpReferencingMissingLog_ReportsLogAsMissing ()
CreatePersistenceFile("settings.lxp", "missing.log");
DeleteLogFiles("missing.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = [Path.Join(_testDirectory, "settings.lxp")]
};
- ProjectPersister.SaveProjectData(_projectFile, projectData);
+ SessionPersister.SaveSessionData(_projectFile, sessionData);
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result.ValidationResult.MissingFiles.Count, Is.EqualTo(1), "Should report missing log file");
@@ -724,7 +724,7 @@ public void LoadProjectData_LxpReferencingMissingLog_ReportsLogAsMissing ()
#endregion
- #region ProjectPersister.LoadProjectData - All Files Missing
+ #region SessionPersister.LoadSessionData - All Files Missing
[Test]
public void LoadProjectData_AllFilesMissing_ReturnsFailureResult ()
@@ -735,7 +735,7 @@ public void LoadProjectData_AllFilesMissing_ReturnsFailureResult ()
CreateTestProjectFile("missing1.log", "missing2.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null, "Result should not be null");
@@ -753,7 +753,7 @@ public void LoadProjectData_AllFilesMissing_MissingFilesListComplete ()
CreateTestProjectFile("gone1.log", "gone2.log", "gone3.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result.ValidationResult.MissingFiles.Count, Is.EqualTo(3), "Should have 3 missing files");
@@ -765,7 +765,7 @@ public void LoadProjectData_AllFilesMissing_MissingFilesListComplete ()
#endregion
- #region ProjectPersister.LoadProjectData - Empty/Invalid Projects
+ #region SessionPersister.LoadSessionData - Empty/Invalid Projects
[Test]
public void LoadProjectData_EmptyProject_ReturnsEmptyResult ()
@@ -774,11 +774,11 @@ public void LoadProjectData_EmptyProject_ReturnsEmptyResult ()
CreateTestProjectFile(); // Empty project with no files
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null, "Result should not be null");
- Assert.That(result.ProjectData.FileNames, Is.Empty, "FileNames should be empty");
+ Assert.That(result.SessionData.FileNames, Is.Empty, "FileNames should be empty");
Assert.That(result.ValidationResult.ValidFiles, Is.Empty, "ValidFiles should be empty");
Assert.That(result.ValidationResult.MissingFiles, Is.Empty, "MissingFiles should be empty");
}
@@ -790,12 +790,12 @@ public void LoadProjectData_NonExistentProjectFile_ReturnsNull ()
var nonExistentProject = Path.Join(_testDirectory, "does_not_exist.lxj");
// Act
- var result = ProjectPersister.LoadProjectData(nonExistentProject, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(nonExistentProject, PluginRegistry.PluginRegistry.Instance);
// Assert
// FIXED: Now returns empty result instead of null when file doesn't exist
Assert.That(result, Is.Not.Null, "Result should not be null even for non-existent file");
- Assert.That(result.ProjectData, Is.Not.Null, "ProjectData should be initialized");
+ Assert.That(result.SessionData, Is.Not.Null, "SessionData should be initialized");
}
[Test]
@@ -807,7 +807,7 @@ public void LoadProjectData_CorruptedProjectFile_ThrowsJsonReaderException ()
// Act & Assert - JsonReaderException is not caught, so it propagates
_ = Assert.Throws(() =>
- ProjectPersister.LoadProjectData(corruptedProject, PluginRegistry.PluginRegistry.Instance));
+ SessionPersister.LoadSessionData(corruptedProject, PluginRegistry.PluginRegistry.Instance));
}
#endregion
@@ -819,7 +819,7 @@ public void LoadProjectData_DuplicateFileReferences_HandlesCorrectly ()
{
// Arrange
CreateTestLogFiles("duplicate.log");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames =
[
@@ -828,10 +828,10 @@ public void LoadProjectData_DuplicateFileReferences_HandlesCorrectly ()
Path.Join(_testDirectory, "duplicate.log")
]
};
- ProjectPersister.SaveProjectData(_projectFile, projectData);
+ SessionPersister.SaveSessionData(_projectFile, sessionData);
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null, "Result should not be null");
@@ -847,7 +847,7 @@ public void LoadProjectData_FilesWithSpecialCharacters_ValidatesCorrectly ()
CreateTestProjectFile("file with spaces.log", "file-with-dashes.log", "file_with_underscores.log");
// Act
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
// Assert
Assert.That(result, Is.Not.Null, "Result should not be null");
@@ -872,7 +872,7 @@ public void LoadProjectData_VeryLargeProject_ValidatesEfficiently ()
// Act
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
stopwatch.Stop();
// Assert
@@ -909,7 +909,7 @@ public void LoadProjectData_ManyMissingFiles_PerformsEfficiently ()
// Act
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
- var result = ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance);
+ var result = SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance);
stopwatch.Stop();
// Assert
@@ -928,7 +928,7 @@ public void LoadProjectData_NullProjectFile_ThrowsArgumentNullException ()
{
// Act & Assert - File.ReadAllText throws ArgumentNullException for null path
_ = Assert.Throws(() =>
- ProjectPersister.LoadProjectData(null, PluginRegistry.PluginRegistry.Instance));
+ SessionPersister.LoadSessionData(null, PluginRegistry.PluginRegistry.Instance));
}
[Test]
@@ -936,7 +936,7 @@ public void LoadProjectData_EmptyProjectFile_ThrowsArgumentException ()
{
// Act & Assert - File.ReadAllText throws ArgumentException for empty string
_ = Assert.Throws(() =>
- ProjectPersister.LoadProjectData(string.Empty, PluginRegistry.PluginRegistry.Instance));
+ SessionPersister.LoadSessionData(string.Empty, PluginRegistry.PluginRegistry.Instance));
}
[Test]
@@ -947,7 +947,7 @@ public void LoadProjectData_NullPluginRegistry_ThrowsArgumentNullException ()
// Act & Assert
_ = Assert.Throws(() =>
- ProjectPersister.LoadProjectData(_projectFile, null));
+ SessionPersister.LoadSessionData(_projectFile, null));
}
#endregion
@@ -973,7 +973,7 @@ public void LoadProjectData_LegacyProjectFormat_ThrowsJsonReaderException ()
// Act & Assert - JsonReaderException is not caught, so XML fallback doesn't trigger
_ = Assert.Throws(() =>
- ProjectPersister.LoadProjectData(_projectFile, PluginRegistry.PluginRegistry.Instance));
+ SessionPersister.LoadSessionData(_projectFile, PluginRegistry.PluginRegistry.Instance));
}
#endregion
diff --git a/src/LogExpert.Resources/Resources.Designer.cs b/src/LogExpert.Resources/Resources.Designer.cs
index 4d43832d..15e879d7 100644
--- a/src/LogExpert.Resources/Resources.Designer.cs
+++ b/src/LogExpert.Resources/Resources.Designer.cs
@@ -1380,74 +1380,65 @@ public static string KeywordActionDlg_UI_Title {
}
///
- /// Looks up a localized string similar to Error loading project file. The file may be corrupted or inaccessible..
+ /// Looks up a localized string similar to Error loading session. The file may be corrupted or inaccessible..
///
- public static string LoadProject_UI_Message_Error_FileMaybeCorruptedOrInaccessible {
+ public static string LoadSession_UI_Message_Error_FileMaybeCorruptedOrInaccessible {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_FileMaybeCorruptedOrInaccessible", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Error_FileMaybeCorruptedOrInaccessible", resourceCulture);
}
}
///
/// Looks up a localized string similar to Failed to update session file: {0}.
///
- public static string LoadProject_UI_Message_Error_Message_FailedToUpdateSessionFile {
+ public static string LoadSession_UI_Message_Error_Message_FailedToUpdateSessionFile {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_Message_FailedToUpdateSessionFile", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Error_Message_FailedToUpdateSessionFile", resourceCulture);
}
}
///
/// Looks up a localized string similar to Session file has been updated with the new file paths..
///
- public static string LoadProject_UI_Message_Error_Message_UpdateSessionFile {
+ public static string LoadSession_UI_Message_Error_Message_UpdateSessionFile {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_Message_UpdateSessionFile", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Error_Message_UpdateSessionFile", resourceCulture);
}
}
///
/// Looks up a localized string similar to Session Update Failed.
///
- public static string LoadProject_UI_Message_Error_Title_FailedToUpdateSessionFile {
+ public static string LoadSession_UI_Message_Error_Title_FailedToUpdateSessionFile {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_Title_FailedToUpdateSessionFile", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Project Load Failed.
- ///
- public static string LoadProject_UI_Message_Error_Title_ProjectLoadFailed {
- get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_Title_ProjectLoadFailed", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Error_Title_FailedToUpdateSessionFile", resourceCulture);
}
}
///
/// Looks up a localized string similar to Session Load Failed.
///
- public static string LoadProject_UI_Message_Error_Title_SessionLoadFailed {
+ public static string LoadSession_UI_Message_Error_Title_SessionLoadFailed {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_Title_SessionLoadFailed", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Error_Title_SessionLoadFailed", resourceCulture);
}
}
///
/// Looks up a localized string similar to Session Updated.
///
- public static string LoadProject_UI_Message_Error_Title_UpdateSessionFile {
+ public static string LoadSession_UI_Message_Error_Title_UpdateSessionFile {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Error_Title_UpdateSessionFile", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Error_Title_UpdateSessionFile", resourceCulture);
}
}
///
/// Looks up a localized string similar to None of the files in this session could be found. The session cannot be loaded..
///
- public static string LoadProject_UI_Message_Message_FilesForSessionCouldNotBeFound {
+ public static string LoadSession_UI_Message_Message_FilesForSessionCouldNotBeFound {
get {
- return ResourceManager.GetString("LoadProject_UI_Message_Message_FilesForSessionCouldNotBeFound", resourceCulture);
+ return ResourceManager.GetString("LoadSession_UI_Message_Message_FilesForSessionCouldNotBeFound", resourceCulture);
}
}
@@ -1945,9 +1936,9 @@ public static string LogTabWindow_UI_Message_PluginTrustConfigurationUpdate {
///
/// Looks up a localized string similar to LogExpert session {0}.
///
- public static string LogTabWindow_UI_Project_Session_Default_Filter {
+ public static string LogTabWindow_UI_Session_Default_Filter {
get {
- return ResourceManager.GetString("LogTabWindow_UI_Project_Session_Default_Filter", resourceCulture);
+ return ResourceManager.GetString("LogTabWindow_UI_Session_Default_Filter", resourceCulture);
}
}
diff --git a/src/LogExpert.Resources/Resources.de.resx b/src/LogExpert.Resources/Resources.de.resx
index e6ef440d..7c1e8ce8 100644
--- a/src/LogExpert.Resources/Resources.de.resx
+++ b/src/LogExpert.Resources/Resources.de.resx
@@ -659,7 +659,7 @@
Das ist eine Test Fehlermeldung, geworfen durch einen Hintergrund Thread
-
+
LogExpert Session {0}
@@ -2074,29 +2074,26 @@ Fortfahren?
Gültig
-
+
Sitzungsaktualisierung fehlgeschlagen
-
+
Sitzungsdatei konnte nicht aktualisiert werden: {0}
-
+
Sitzung aktualisiert
-
+
Die Sitzungsdatei wurde mit den neuen Dateipfaden aktualisiert.
-
+
Das Laden der Sitzung ist fehlgeschlagen
-
+
Keine der Dateien in dieser Sitzung konnte gefunden werden. Die Sitzung kann nicht geladen werden.
-
- Das Laden des Projekts ist fehlgeschlagen
-
-
- Fehler beim Laden der Projektdatei. Die Datei ist möglicherweise beschädigt oder nicht zugänglich.
+
+ Fehler beim Laden der Sitzung. Die Datei ist möglicherweise beschädigt oder nicht zugänglich.
Standard (einzelne Zeile)
diff --git a/src/LogExpert.Resources/Resources.resx b/src/LogExpert.Resources/Resources.resx
index 02c7ca72..711968a9 100644
--- a/src/LogExpert.Resources/Resources.resx
+++ b/src/LogExpert.Resources/Resources.resx
@@ -665,7 +665,7 @@
This is a test exception thrown by a background thread
-
+
LogExpert session {0}
@@ -2138,28 +2138,25 @@ Restart LogExpert to apply changes?
Default (single line)
-
- Error loading project file. The file may be corrupted or inaccessible.
+
+ Error loading session. The file may be corrupted or inaccessible.
-
- Project Load Failed
-
-
+
None of the files in this session could be found. The session cannot be loaded.
-
+
Session Load Failed
-
+
Session file has been updated with the new file paths.
-
+
Session Updated
-
+
Failed to update session file: {0}
-
+
Session Update Failed
diff --git a/src/LogExpert.Resources/Resources.zh-CN.resx b/src/LogExpert.Resources/Resources.zh-CN.resx
index e2b407eb..df390ea7 100644
--- a/src/LogExpert.Resources/Resources.zh-CN.resx
+++ b/src/LogExpert.Resources/Resources.zh-CN.resx
@@ -568,7 +568,7 @@
这是由后台线程抛出的测试异常
-
+
LogExpert 会话 {0}
@@ -1927,28 +1927,25 @@ YY[YY] = 年
默认(单行)
-
- 加载项目文件出错。文件可能已损坏或无法访问。
+
+ 加载会话出错。文件可能已损坏或无法访问。
-
- 项目加载失败
-
-
+
此会话中的文件均未找到。无法加载会话。
-
+
会话加载失败
-
+
会话文件已使用新文件路径更新。
-
+
会话已更新
-
+
更新会话文件失败:{0}
-
+
会话更新失败
diff --git a/src/LogExpert.Tests/Services/ProjectFileHandlerTests.cs b/src/LogExpert.Tests/Services/SessionHandlerTests.cs
similarity index 85%
rename from src/LogExpert.Tests/Services/ProjectFileHandlerTests.cs
rename to src/LogExpert.Tests/Services/SessionHandlerTests.cs
index 598eaf20..5153cb43 100644
--- a/src/LogExpert.Tests/Services/ProjectFileHandlerTests.cs
+++ b/src/LogExpert.Tests/Services/SessionHandlerTests.cs
@@ -6,7 +6,7 @@
using LogExpert.UI.Controls.LogWindow;
using LogExpert.UI.Interface;
using LogExpert.UI.Services.FileOperationService;
-using LogExpert.UI.Services.ProjectFileHandlerService;
+using LogExpert.UI.Services.SessionHandlerService;
using Moq;
@@ -17,14 +17,14 @@ namespace LogExpert.Tests.Services;
[TestFixture]
[Apartment(ApartmentState.STA)]
[SupportedOSPlatform("windows")]
-internal class ProjectFileHandlerTests : IDisposable
+internal class SessionHandlerTests : IDisposable
{
private Mock _pluginRegistryMock = null!;
private List _addFileTabCalls = null!;
private Settings _settings;
private Mock _configManagerMock;
private LogWindow _stubLogWindow = null!;
- private ProjectFileHandler _sut = null!;
+ private SessionHandler _sut = null!;
private bool _disposed;
@@ -54,7 +54,7 @@ public void SetUp ()
forcePersistenceLoading: false,
configManager: _configManagerMock.Object);
- _sut = new ProjectFileHandler(
+ _sut = new SessionHandler(
_pluginRegistryMock.Object,
request =>
{
@@ -69,7 +69,7 @@ public void TearDown ()
_stubLogWindow?.Dispose();
}
- #region LoadProject — Phase 1 tests
+ #region LoadSession — Phase 1 tests
[Test]
public void LoadProject_ValidProjectFile_ReturnsSuccess ()
@@ -81,12 +81,12 @@ public void LoadProject_ValidProjectFile_ReturnsSuccess ()
try
{
// Act
- var outcome = _sut.LoadProject(tempFile);
+ var outcome = _sut.LoadSession(tempFile);
// Assert
- Assert.That(outcome.Status, Is.EqualTo(ProjectLoadOutcome.LoadStatus.Success));
- Assert.That(outcome.ProjectData, Is.Not.Null);
- Assert.That(outcome.ProjectData!.FileNames, Has.Count.EqualTo(1));
+ Assert.That(outcome.Status, Is.EqualTo(SessionLoadOutcome.LoadStatus.Success));
+ Assert.That(outcome.SessionData, Is.Not.Null);
+ Assert.That(outcome.SessionData!.FileNames, Has.Count.EqualTo(1));
Assert.That(outcome.ErrorMessage, Is.Null);
Assert.That(outcome.ValidationResult, Is.Null);
}
@@ -107,10 +107,10 @@ public void LoadProject_ValidProjectWithLayoutXml_HasLayoutDataIsTrue ()
try
{
// Act
- var outcome = _sut.LoadProject(tempFile);
+ var outcome = _sut.LoadSession(tempFile);
// Assert
- Assert.That(outcome.Status, Is.EqualTo(ProjectLoadOutcome.LoadStatus.Success));
+ Assert.That(outcome.Status, Is.EqualTo(SessionLoadOutcome.LoadStatus.Success));
Assert.That(outcome.HasLayoutData, Is.True);
Assert.That(outcome.LayoutXml, Is.EqualTo(""));
}
@@ -130,7 +130,7 @@ public void LoadProject_ValidProjectWithoutLayoutXml_HasLayoutDataIsFalse ()
try
{
// Act
- var outcome = _sut.LoadProject(tempFile);
+ var outcome = _sut.LoadSession(tempFile);
// Assert
Assert.That(outcome.HasLayoutData, Is.False);
@@ -153,11 +153,11 @@ public void LoadProject_ProjectWithMissingFiles_ReturnsNeedsIntervention ()
try
{
// Act
- var outcome = _sut.LoadProject(tempFile);
+ var outcome = _sut.LoadSession(tempFile);
// Assert
- Assert.That(outcome.Status, Is.EqualTo(ProjectLoadOutcome.LoadStatus.NeedsIntervention));
- Assert.That(outcome.ProjectData, Is.Not.Null);
+ Assert.That(outcome.Status, Is.EqualTo(SessionLoadOutcome.LoadStatus.NeedsIntervention));
+ Assert.That(outcome.SessionData, Is.Not.Null);
Assert.That(outcome.ValidationResult, Is.Not.Null);
Assert.That(outcome.ValidationResult!.HasMissingFiles, Is.True);
}
@@ -177,12 +177,12 @@ public void LoadProject_CorruptFile_ReturnsError ()
try
{
// Act
- var outcome = _sut.LoadProject(tempFile);
+ var outcome = _sut.LoadSession(tempFile);
// Assert
- Assert.That(outcome.Status, Is.EqualTo(ProjectLoadOutcome.LoadStatus.Error));
+ Assert.That(outcome.Status, Is.EqualTo(SessionLoadOutcome.LoadStatus.Error));
Assert.That(outcome.ErrorMessage, Is.Not.Null.And.Not.Empty);
- Assert.That(outcome.ProjectData, Is.Null);
+ Assert.That(outcome.SessionData, Is.Null);
}
finally
{
@@ -197,10 +197,10 @@ public void LoadProject_NonexistentFile_ReturnsError ()
var fakePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".lxj");
// Act
- var outcome = _sut.LoadProject(fakePath);
+ var outcome = _sut.LoadSession(fakePath);
// Assert
- Assert.That(outcome.Status, Is.EqualTo(ProjectLoadOutcome.LoadStatus.Error));
+ Assert.That(outcome.Status, Is.EqualTo(SessionLoadOutcome.LoadStatus.Error));
Assert.That(outcome.ErrorMessage, Is.Not.Null.And.Not.Empty);
}
@@ -213,10 +213,10 @@ public void LoadProject_EmptyFileList_ReturnsEmptyProject ()
try
{
// Act
- var outcome = _sut.LoadProject(tempFile);
+ var outcome = _sut.LoadSession(tempFile);
// Assert
- Assert.That(outcome.Status, Is.EqualTo(ProjectLoadOutcome.LoadStatus.EmptyProject));
+ Assert.That(outcome.Status, Is.EqualTo(SessionLoadOutcome.LoadStatus.EmptySession));
Assert.That(outcome.ErrorMessage, Is.Not.Null.And.Not.Empty);
}
finally
@@ -234,7 +234,7 @@ public void LoadProject_DoesNotInvokeAddFileTabCallback ()
try
{
// Act
- _ = _sut.LoadProject(tempFile);
+ _ = _sut.LoadSession(tempFile);
// Assert — phase 1 must never open tabs
Assert.That(_addFileTabCalls, Is.Empty);
@@ -316,7 +316,7 @@ public void ContinueLoad_WithAlternatives_ReplacesFilePathsBeforeOpening ()
{
// Arrange
var outcome = CreateOutcome(
- ProjectLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionLoadOutcome.LoadStatus.NeedsIntervention,
["C:\\old\\missing.log", "C:\\logs\\existing.log"],
layoutXml: null);
@@ -342,7 +342,7 @@ public void ContinueLoad_DuplicateFileWithAlternative_ReplacesBothOccurrences ()
{
// Arrange
var outcome = CreateOutcome(
- ProjectLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionLoadOutcome.LoadStatus.NeedsIntervention,
["C:\\missing.log", "C:\\missing.log"],
layoutXml: null);
@@ -368,7 +368,7 @@ public void ContinueLoad_CloseAllTabs_ReturnsTrueInResult ()
{
// Arrange
var outcome = CreateOutcome(
- ProjectLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionLoadOutcome.LoadStatus.NeedsIntervention,
["C:\\logs\\app.log"],
layoutXml: "");
@@ -388,7 +388,7 @@ public void ContinueLoad_OpenInNewWindow_DoesNotOpenTabs_ReturnsFileNames ()
{
// Arrange
var outcome = CreateOutcome(
- ProjectLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionLoadOutcome.LoadStatus.NeedsIntervention,
["C:\\logs\\app.log"],
layoutXml: null);
@@ -409,7 +409,7 @@ public void ContinueLoad_OpenInNewWindowWithAlternatives_AppliesAlternativesThen
{
// Arrange
var outcome = CreateOutcome(
- ProjectLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionLoadOutcome.LoadStatus.NeedsIntervention,
["C:\\old\\missing.log", "C:\\logs\\existing.log"],
layoutXml: null);
@@ -441,14 +441,14 @@ public void ContinueLoad_UpdateSessionFileTrue_SavesAmendedProject ()
try
{
- var outcome = new ProjectLoadOutcome
+ var outcome = new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.NeedsIntervention,
- ProjectData = new ProjectData
+ Status = SessionLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionData = new SessionData
{
FileNames = ["C:\\old\\missing.log"],
TabLayoutXml = "",
- ProjectFilePath = tempFile
+ SessionFilePath = tempFile
},
LayoutXml = ""
};
@@ -466,10 +466,10 @@ public void ContinueLoad_UpdateSessionFileTrue_SavesAmendedProject ()
_ = _sut.ContinueLoad(outcome, resolution, restoreLayout: false);
// Assert: reload the file and check the path was updated
- var reloaded = ProjectPersister.LoadProjectData(tempFile, _pluginRegistryMock.Object);
- Assert.That(reloaded?.ProjectData?.FileNames, Has.Some.Contains("found.log"));
+ var reloaded = SessionPersister.LoadSessionData(tempFile, _pluginRegistryMock.Object);
+ Assert.That(reloaded?.SessionData?.FileNames, Has.Some.Contains("found.log"));
// Layout XML must be preserved
- Assert.That(reloaded?.ProjectData?.TabLayoutXml, Is.EqualTo(""));
+ Assert.That(reloaded?.SessionData?.TabLayoutXml, Is.EqualTo(""));
}
finally
{
@@ -487,13 +487,13 @@ public void ContinueLoad_UpdateSessionFileFalse_DoesNotSave ()
{
var originalContent = File.ReadAllText(tempFile);
- var outcome = new ProjectLoadOutcome
+ var outcome = new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.NeedsIntervention,
- ProjectData = new ProjectData
+ Status = SessionLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionData = new SessionData
{
FileNames = ["C:\\old\\missing.log"],
- ProjectFilePath = tempFile
+ SessionFilePath = tempFile
}
};
@@ -534,14 +534,14 @@ public void ContinueLoad_NullResolution_SuccessReturnsCloseAllTabsFalse ()
#endregion
- #region SaveProject tests
+ #region SaveSession tests
[Test]
public void SaveProject_ValidData_ReturnsTrueAndNullError ()
{
// Arrange
var tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".lxj");
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = ["C:\\logs\\app.log"],
TabLayoutXml = ""
@@ -550,7 +550,7 @@ public void SaveProject_ValidData_ReturnsTrueAndNullError ()
try
{
// Act
- var success = _sut.SaveProject(tempFile, projectData, out var errorMessage);
+ var success = _sut.SaveSession(tempFile, sessionData, out var errorMessage);
// Assert
Assert.That(success, Is.True);
@@ -569,16 +569,16 @@ public void SaveProject_ValidData_ReturnsTrueAndNullError ()
[Test]
public void SaveProject_NullPath_ReturnsFalseWithErrorMessage ()
{
- // Note: ProjectPersister.SaveProjectData swallows IOException/UnauthorizedAccessException/
+ // Note: SessionPersister.SaveSessionData swallows IOException/UnauthorizedAccessException/
// JsonSerializationException. Only uncaught exceptions (e.g. ArgumentNullException from
- // File.WriteAllText(null,...)) propagate to ProjectFileHandler.SaveProject's catch block.
- var projectData = new ProjectData
+ // File.WriteAllText(null,...)) propagate to SessionHandler.SaveSession's catch block.
+ var sessionData = new SessionData
{
FileNames = ["C:\\logs\\app.log"]
};
// Act
- var success = _sut.SaveProject(null!, projectData, out var errorMessage);
+ var success = _sut.SaveSession(null!, sessionData, out var errorMessage);
// Assert
Assert.That(success, Is.False);
@@ -589,17 +589,17 @@ public void SaveProject_NullPath_ReturnsFalseWithErrorMessage ()
#region Helpers
- private static ProjectLoadOutcome CreateSuccessOutcome (List fileNames, string? layoutXml)
+ private static SessionLoadOutcome CreateSuccessOutcome (List fileNames, string? layoutXml)
{
- return CreateOutcome(ProjectLoadOutcome.LoadStatus.Success, fileNames, layoutXml);
+ return CreateOutcome(SessionLoadOutcome.LoadStatus.Success, fileNames, layoutXml);
}
- private static ProjectLoadOutcome CreateOutcome (ProjectLoadOutcome.LoadStatus status, List fileNames, string? layoutXml)
+ private static SessionLoadOutcome CreateOutcome (SessionLoadOutcome.LoadStatus status, List fileNames, string? layoutXml)
{
- return new ProjectLoadOutcome
+ return new SessionLoadOutcome
{
Status = status,
- ProjectData = new ProjectData
+ SessionData = new SessionData
{
FileNames = fileNames,
TabLayoutXml = layoutXml!
@@ -624,14 +624,14 @@ private static string CreateTempLogFile ()
///
private static string CreateTempProjectFile (List fileNames, string? layoutXml)
{
- var projectData = new ProjectData
+ var sessionData = new SessionData
{
FileNames = fileNames,
TabLayoutXml = layoutXml!
};
var tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".lxj");
- ProjectPersister.SaveProjectData(tempFile, projectData);
+ SessionPersister.SaveSessionData(tempFile, sessionData);
return tempFile;
}
diff --git a/src/LogExpert.UI/Dialogs/Helpers/MissingFilesMessageBox.cs b/src/LogExpert.UI/Dialogs/Helpers/MissingFilesMessageBox.cs
index 1ef0b8ad..826ad172 100644
--- a/src/LogExpert.UI/Dialogs/Helpers/MissingFilesMessageBox.cs
+++ b/src/LogExpert.UI/Dialogs/Helpers/MissingFilesMessageBox.cs
@@ -17,7 +17,7 @@ internal static class MissingFilesMessageBox
///
/// The validation result containing missing file information
/// True if user wants to continue loading valid files, false to cancel
- public static bool Show (ProjectValidationResult validationResult)
+ public static bool Show (SessionValidationResult validationResult)
{
ArgumentNullException.ThrowIfNull(validationResult);
diff --git a/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.cs b/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.cs
index 9caadd91..80efe776 100644
--- a/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.cs
+++ b/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.cs
@@ -25,7 +25,7 @@
using LogExpert.UI.Services.LedService;
using LogExpert.UI.Services.LogWindowCoordinatorService;
using LogExpert.UI.Services.MenuToolbarService;
-using LogExpert.UI.Services.ProjectFileHandlerService;
+using LogExpert.UI.Services.SessionHandlerService;
using LogExpert.UI.Services.TabControllerService;
using LogExpert.UI.Services.ToolWindowCoordinatorService;
@@ -53,7 +53,7 @@ internal partial class LogTabWindow : Form, ILogTabWindow
private readonly LogWindowCoordinator _logWindowCoordinator;
private readonly ToolWindowCoordinator _toolWindowCoordinator;
private readonly FileOperationService _fileOperationService;
- private readonly ProjectFileHandler _projectFileHandler;
+ private readonly SessionHandler _sessionHandler;
private bool _disposed;
@@ -108,12 +108,12 @@ public LogTabWindow (string[] fileNames, int instanceNumber, bool showInstanceNu
_deadIcon = _ledService.GetDeadIcon();
- _fileOperationService = new FileOperationService(configManager, _tabController, _ledService, PluginRegistry.PluginRegistry.Instance, CreateLogWindowFromRequest, () => Clipboard.ContainsText() ? Clipboard.GetText() : null, LoadProject);
+ _fileOperationService = new FileOperationService(configManager, _tabController, _ledService, PluginRegistry.PluginRegistry.Instance, CreateLogWindowFromRequest, () => Clipboard.ContainsText() ? Clipboard.GetText() : null, LoadSession);
_fileOperationService.FileHistoryChanged += (_, _) => FillHistoryMenu();
_fileOperationService.FileOpened += OnFileOperationServiceFileOpened;
- _projectFileHandler = new ProjectFileHandler(PluginRegistry.PluginRegistry.Instance, request => _fileOperationService.AddFileTab(request));
+ _sessionHandler = new SessionHandler(PluginRegistry.PluginRegistry.Instance, request => _fileOperationService.AddFileTab(request));
_logWindowCoordinator = new LogWindowCoordinator(configManager, PluginRegistry.PluginRegistry.Instance, this, _tabController, _ledService, _fileOperationService);
@@ -421,8 +421,8 @@ private void ApplyContextMenuResources ()
multiFileToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_multiFileToolStripMenuItem;
multiFileEnabledStripMenuItem.Text = Resources.LogTabWindow_UI_StripMenuItem_multiFileEnabledStripMenuItem;
multifileMaskToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_multifileMaskToolStripMenuItem;
- loadProjectToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_loadProjectToolStripMenuItem;
- saveProjectToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_saveProjectToolStripMenuItem;
+ loadSessionToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_loadProjectToolStripMenuItem;
+ saveSessionToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_saveProjectToolStripMenuItem;
exportBookmarksToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_exportBookmarksToolStripMenuItem;
lastUsedToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_lastUsedToolStripMenuItem;
exitToolStripMenuItem.Text = Resources.LogTabWindow_UI_ToolStripMenuItem_exitToolStripMenuItem;
@@ -499,8 +499,8 @@ private void ApplyToolTips ()
openURIToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_openURIToolStripMenuItem;
newFromClipboardToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_newFromClipboardToolStripMenuItem;
multiFileToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_multiFileToolStripMenuItem;
- loadProjectToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_loadProjectToolStripMenuItem;
- saveProjectToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_saveProjectToolStripMenuItem;
+ loadSessionToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_loadProjectToolStripMenuItem;
+ saveSessionToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_saveProjectToolStripMenuItem;
timeshiftToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_timeshiftToolStripMenuItem;
copyMarkedLinesIntoNewTabToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_copyMarkedLinesIntoNewTabToolStripMenuItem;
columnizerToolStripMenuItem.ToolTipText = Resources.LogTabWindow_UI_ToolStripMenuItem_ToolTip_columnizerToolStripMenuItem;
@@ -1437,28 +1437,28 @@ private void CloseAllTabs ()
[SupportedOSPlatform("windows")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0010:Add missing cases", Justification = "no need for the other switch cases")]
- private void LoadProject (string projectFileName, bool restoreLayout)
+ private void LoadSession (string sessionFileName, bool restoreLayout)
{
- var outcome = _projectFileHandler.LoadProject(projectFileName);
+ var outcome = _sessionHandler.LoadSession(sessionFileName);
bool openedTabs = false;
switch (outcome.Status)
{
- case ProjectLoadOutcome.LoadStatus.Error:
+ case SessionLoadOutcome.LoadStatus.Error:
{
ShowOkMessage(outcome.ErrorMessage ?? Resources.LogExpert_Common_UI_Title_Error,
- Resources.LoadProject_UI_Message_Error_Title_ProjectLoadFailed,
+ Resources.LoadSession_UI_Message_Error_Title_SessionLoadFailed,
MessageBoxIcon.Error);
return;
}
- case ProjectLoadOutcome.LoadStatus.EmptyProject:
+ case SessionLoadOutcome.LoadStatus.EmptySession:
{
- ShowOkMessage(outcome.ErrorMessage ?? Resources.LoadProject_UI_Message_Error_Title_SessionLoadFailed,
- Resources.LoadProject_UI_Message_Message_FilesForSessionCouldNotBeFound,
+ ShowOkMessage(outcome.ErrorMessage ?? Resources.LoadSession_UI_Message_Error_Title_SessionLoadFailed,
+ Resources.LoadSession_UI_Message_Message_FilesForSessionCouldNotBeFound,
MessageBoxIcon.Error);
return;
}
- case ProjectLoadOutcome.LoadStatus.NeedsIntervention:
+ case SessionLoadOutcome.LoadStatus.NeedsIntervention:
{
var (dialogResult, updateSessionFile, selectedAlternatives) =
MissingFilesDialog.ShowDialog(outcome.ValidationResult!, outcome.HasLayoutData);
@@ -1481,12 +1481,12 @@ private void LoadProject (string projectFileName, bool restoreLayout)
SelectedAlternatives = selectedAlternatives
};
- var interventionResult = _projectFileHandler.ContinueLoad(outcome, resolution, restoreLayout);
+ var interventionResult = _sessionHandler.ContinueLoad(outcome, resolution, restoreLayout);
if (updateSessionFile)
{
- ShowOkMessage(Resources.LoadProject_UI_Message_Error_Message_UpdateSessionFile,
- Resources.LoadProject_UI_Message_Error_Title_UpdateSessionFile,
+ ShowOkMessage(Resources.LoadSession_UI_Message_Error_Message_UpdateSessionFile,
+ Resources.LoadSession_UI_Message_Error_Title_UpdateSessionFile,
MessageBoxIcon.Information);
}
@@ -1504,9 +1504,9 @@ private void LoadProject (string projectFileName, bool restoreLayout)
openedTabs = interventionResult.OpenedTabs;
break;
}
- case ProjectLoadOutcome.LoadStatus.Success:
+ case SessionLoadOutcome.LoadStatus.Success:
{
- openedTabs = _projectFileHandler.ContinueLoad(outcome, null, restoreLayout).OpenedTabs;
+ openedTabs = _sessionHandler.ContinueLoad(outcome, null, restoreLayout).OpenedTabs;
break;
}
}
@@ -2364,12 +2364,12 @@ private void OnLogTabWindowSizeChanged (object sender, EventArgs e)
}
[SupportedOSPlatform("windows")]
- private void OnSaveProjectToolStripMenuItemClick (object sender, EventArgs e)
+ private void OnSaveSessionToolStripMenuItemClick (object sender, EventArgs e)
{
SaveFileDialog dlg = new()
{
DefaultExt = "lxj",
- Filter = string.Format(CultureInfo.InvariantCulture, Resources.LogTabWindow_UI_Project_Session_Default_Filter, "(*.lxj)|*.lxj")
+ Filter = string.Format(CultureInfo.InvariantCulture, Resources.LogTabWindow_UI_Session_Default_Filter, "(*.lxj)|*.lxj")
};
if (dlg.ShowDialog() == DialogResult.OK)
@@ -2386,13 +2386,13 @@ private void OnSaveProjectToolStripMenuItemClick (object sender, EventArgs e)
}
}
- ProjectData projectData = new()
+ SessionData sessionData = new()
{
FileNames = fileNames,
TabLayoutXml = SaveLayout()
};
- if (!_projectFileHandler.SaveProject(fileName, projectData, out var errorMessage))
+ if (!_sessionHandler.SaveSession(fileName, sessionData, out var errorMessage))
{
ShowOkMessage(errorMessage ?? Resources.LogExpert_Common_UI_Title_Error,
Resources.LogExpert_Common_UI_Title_Error,
@@ -2402,18 +2402,18 @@ private void OnSaveProjectToolStripMenuItemClick (object sender, EventArgs e)
}
[SupportedOSPlatform("windows")]
- private void OnLoadProjectToolStripMenuItemClick (object sender, EventArgs e)
+ private void OnLoadSessionToolStripMenuItemClick (object sender, EventArgs e)
{
OpenFileDialog dlg = new()
{
DefaultExt = "lxj",
- Filter = string.Format(CultureInfo.InvariantCulture, Resources.LogTabWindow_UI_Project_Session_Default_Filter, "(*.lxj)|*.lxj")
+ Filter = string.Format(CultureInfo.InvariantCulture, Resources.LogTabWindow_UI_Session_Default_Filter, "(*.lxj)|*.lxj")
};
if (dlg.ShowDialog() == DialogResult.OK)
{
- var projectFileName = dlg.FileName;
- LoadProject(projectFileName, true);
+ var sessionFileName = dlg.FileName;
+ LoadSession(sessionFileName, true);
}
}
diff --git a/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs b/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs
index e5f9c152..8f7bab2a 100644
--- a/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs
+++ b/src/LogExpert.UI/Dialogs/LogTabWindow/LogTabWindow.designer.cs
@@ -40,8 +40,8 @@ private void InitializeComponent ()
multiFileEnabledStripMenuItem = new ToolStripMenuItem();
multifileMaskToolStripMenuItem = new ToolStripMenuItem();
ToolStripSeparator2 = new ToolStripSeparator();
- loadProjectToolStripMenuItem = new ToolStripMenuItem();
- saveProjectToolStripMenuItem = new ToolStripMenuItem();
+ loadSessionToolStripMenuItem = new ToolStripMenuItem();
+ saveSessionToolStripMenuItem = new ToolStripMenuItem();
exportBookmarksToolStripMenuItem = new ToolStripMenuItem();
ToolStripSeparator3 = new ToolStripSeparator();
lastUsedToolStripMenuItem = new ToolStripMenuItem();
@@ -205,7 +205,7 @@ private void InitializeComponent ()
//
// fileToolStripMenuItem
//
- fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openToolStripMenuItem, openURIToolStripMenuItem, closeFileToolStripMenuItem, reloadToolStripMenuItem, newFromClipboardToolStripMenuItem, ToolStripSeparator1, multiFileToolStripMenuItem, ToolStripSeparator2, loadProjectToolStripMenuItem, saveProjectToolStripMenuItem, exportBookmarksToolStripMenuItem, ToolStripSeparator3, lastUsedToolStripMenuItem, exitToolStripMenuItem });
+ fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openToolStripMenuItem, openURIToolStripMenuItem, closeFileToolStripMenuItem, reloadToolStripMenuItem, newFromClipboardToolStripMenuItem, ToolStripSeparator1, multiFileToolStripMenuItem, ToolStripSeparator2, loadSessionToolStripMenuItem, saveSessionToolStripMenuItem, exportBookmarksToolStripMenuItem, ToolStripSeparator3, lastUsedToolStripMenuItem, exitToolStripMenuItem });
fileToolStripMenuItem.Name = "fileToolStripMenuItem";
fileToolStripMenuItem.Size = new Size(37, 19);
fileToolStripMenuItem.Text = "File";
@@ -296,21 +296,21 @@ private void InitializeComponent ()
ToolStripSeparator2.Name = "ToolStripSeparator2";
ToolStripSeparator2.Size = new Size(240, 6);
//
- // loadProjectToolStripMenuItem
+ // loadSessionToolStripMenuItem
//
- loadProjectToolStripMenuItem.Name = "loadProjectToolStripMenuItem";
- loadProjectToolStripMenuItem.Size = new Size(243, 22);
- loadProjectToolStripMenuItem.Text = "Load session...";
- loadProjectToolStripMenuItem.ToolTipText = "Load a saved session (list of log files)";
- loadProjectToolStripMenuItem.Click += OnLoadProjectToolStripMenuItemClick;
+ loadSessionToolStripMenuItem.Name = "loadSessionToolStripMenuItem";
+ loadSessionToolStripMenuItem.Size = new Size(243, 22);
+ loadSessionToolStripMenuItem.Text = "Load session...";
+ loadSessionToolStripMenuItem.ToolTipText = "Load a saved session (list of log files)";
+ loadSessionToolStripMenuItem.Click += OnLoadSessionToolStripMenuItemClick;
//
- // saveProjectToolStripMenuItem
+ // saveSessionToolStripMenuItem
//
- saveProjectToolStripMenuItem.Name = "saveProjectToolStripMenuItem";
- saveProjectToolStripMenuItem.Size = new Size(243, 22);
- saveProjectToolStripMenuItem.Text = "Save session...";
- saveProjectToolStripMenuItem.ToolTipText = "Save a session (all open tabs)";
- saveProjectToolStripMenuItem.Click += OnSaveProjectToolStripMenuItemClick;
+ saveSessionToolStripMenuItem.Name = "saveSessionToolStripMenuItem";
+ saveSessionToolStripMenuItem.Size = new Size(243, 22);
+ saveSessionToolStripMenuItem.Text = "Save session...";
+ saveSessionToolStripMenuItem.ToolTipText = "Save a session (all open tabs)";
+ saveSessionToolStripMenuItem.Click += OnSaveSessionToolStripMenuItemClick;
//
// exportBookmarksToolStripMenuItem
//
@@ -1169,8 +1169,8 @@ private void InitializeComponent ()
private ToolStripMenuItem closeOtherTabsToolStripMenuItem;
private ToolStripMenuItem closeAllTabsToolStripMenuItem;
private ToolStripMenuItem tabColorToolStripMenuItem;
- private ToolStripMenuItem loadProjectToolStripMenuItem;
- private ToolStripMenuItem saveProjectToolStripMenuItem;
+ private ToolStripMenuItem loadSessionToolStripMenuItem;
+ private ToolStripMenuItem saveSessionToolStripMenuItem;
private ToolStripButton toolStripButtonBubbles;
private ToolStripMenuItem copyPathToClipboardToolStripMenuItem;
private ToolStripMenuItem findInExplorerToolStripMenuItem;
diff --git a/src/LogExpert.UI/Dialogs/MissingFilesDialog.cs b/src/LogExpert.UI/Dialogs/MissingFilesDialog.cs
index 74e85f4e..91dec327 100644
--- a/src/LogExpert.UI/Dialogs/MissingFilesDialog.cs
+++ b/src/LogExpert.UI/Dialogs/MissingFilesDialog.cs
@@ -16,7 +16,7 @@ public partial class MissingFilesDialog : Form
{
#region Fields
- private readonly ProjectValidationResult _validationResult;
+ private readonly SessionValidationResult _validationResult;
private readonly Dictionary _fileItems;
private readonly bool _hasLayoutData;
@@ -50,7 +50,7 @@ public partial class MissingFilesDialog : Form
/// Validation result containing file information
/// Whether to show layout restoration options
/// Whether the project has layout data to restore
- public MissingFilesDialog (ProjectValidationResult validationResult, bool hasLayoutData = false)
+ public MissingFilesDialog (SessionValidationResult validationResult, bool hasLayoutData = false)
{
ArgumentNullException.ThrowIfNull(validationResult);
@@ -78,7 +78,7 @@ public MissingFilesDialog (ProjectValidationResult validationResult, bool hasLay
/// Validation result
/// Whether the project has layout data
/// Tuple containing the dialog result, whether to update session file, and selected alternatives
- public static (MissingFilesDialogResult Result, bool UpdateSessionFile, Dictionary SelectedAlternatives) ShowDialog (ProjectValidationResult validationResult, bool hasLayoutData)
+ public static (MissingFilesDialogResult Result, bool UpdateSessionFile, Dictionary SelectedAlternatives) ShowDialog (SessionValidationResult validationResult, bool hasLayoutData)
{
using var dialog = new MissingFilesDialog(validationResult, hasLayoutData);
_ = dialog.ShowDialog();
diff --git a/src/LogExpert.UI/Dialogs/ProjectLoadDlg.Designer.cs b/src/LogExpert.UI/Dialogs/SessionLoadDlg.Designer.cs
similarity index 96%
rename from src/LogExpert.UI/Dialogs/ProjectLoadDlg.Designer.cs
rename to src/LogExpert.UI/Dialogs/SessionLoadDlg.Designer.cs
index 3e5677c3..4e38dbdb 100644
--- a/src/LogExpert.UI/Dialogs/ProjectLoadDlg.Designer.cs
+++ b/src/LogExpert.UI/Dialogs/SessionLoadDlg.Designer.cs
@@ -1,6 +1,6 @@
namespace LogExpert.Dialogs;
-partial class ProjectLoadDlg
+partial class SessionLoadDlg
{
///
/// Required designer variable.
@@ -28,7 +28,7 @@ protected override void Dispose(bool disposing)
///
private void InitializeComponent()
{
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectLoadDlg));
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SessionLoadDlg));
this.labelInformational = new System.Windows.Forms.Label();
this.buttonCloseTabs = new System.Windows.Forms.Button();
this.buttonNewWindow = new System.Windows.Forms.Button();
@@ -88,7 +88,7 @@ private void InitializeComponent()
this.labelChooseHowToProceed.TabIndex = 4;
this.labelChooseHowToProceed.Text = "Please choose how to proceed:";
//
- // ProjectLoadDlg
+ // SessionLoadDlg
//
this.ClientSize = new System.Drawing.Size(258, 196);
this.Controls.Add(this.labelChooseHowToProceed);
@@ -100,7 +100,7 @@ private void InitializeComponent()
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
- this.Name = "ProjectLoadDlg";
+ this.Name = "SessionLoadDlg";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Loading Session";
diff --git a/src/LogExpert.UI/Dialogs/ProjectLoadDlg.cs b/src/LogExpert.UI/Dialogs/SessionLoadDlg.cs
similarity index 80%
rename from src/LogExpert.UI/Dialogs/ProjectLoadDlg.cs
rename to src/LogExpert.UI/Dialogs/SessionLoadDlg.cs
index 5b0d78ff..8d8c3f19 100644
--- a/src/LogExpert.UI/Dialogs/ProjectLoadDlg.cs
+++ b/src/LogExpert.UI/Dialogs/SessionLoadDlg.cs
@@ -6,7 +6,7 @@
namespace LogExpert.Dialogs;
[SupportedOSPlatform("windows")]
-internal partial class ProjectLoadDlg : Form
+internal partial class SessionLoadDlg : Form
{
#region Fields
@@ -14,7 +14,7 @@ internal partial class ProjectLoadDlg : Form
#region cTor
- public ProjectLoadDlg ()
+ public SessionLoadDlg ()
{
SuspendLayout();
@@ -43,7 +43,7 @@ private void ApplyResources ()
#region Properties
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
- public ProjectLoadDlgResult ProjectLoadResult { get; set; } = ProjectLoadDlgResult.Cancel;
+ public SessionLoadDlgResult SessionLoadResult { get; set; } = SessionLoadDlgResult.Cancel;
#endregion
@@ -51,19 +51,19 @@ private void ApplyResources ()
private void OnButtonCloseTabsClick (object sender, EventArgs e)
{
- ProjectLoadResult = ProjectLoadDlgResult.CloseTabs;
+ SessionLoadResult = SessionLoadDlgResult.CloseTabs;
Close();
}
private void OnButtonNewWindowClick (object sender, EventArgs e)
{
- ProjectLoadResult = ProjectLoadDlgResult.NewWindow;
+ SessionLoadResult = SessionLoadDlgResult.NewWindow;
Close();
}
private void OnButtonIgnoreClick (object sender, EventArgs e)
{
- ProjectLoadResult = ProjectLoadDlgResult.IgnoreLayout;
+ SessionLoadResult = SessionLoadDlgResult.IgnoreLayout;
Close();
}
diff --git a/src/LogExpert.UI/Dialogs/ProjectLoadDlg.resx b/src/LogExpert.UI/Dialogs/SessionLoadDlg.resx
similarity index 100%
rename from src/LogExpert.UI/Dialogs/ProjectLoadDlg.resx
rename to src/LogExpert.UI/Dialogs/SessionLoadDlg.resx
diff --git a/src/LogExpert.UI/Interface/IFileOperationService.cs b/src/LogExpert.UI/Interface/IFileOperationService.cs
index ec64a34f..0547f4b4 100644
--- a/src/LogExpert.UI/Interface/IFileOperationService.cs
+++ b/src/LogExpert.UI/Interface/IFileOperationService.cs
@@ -33,7 +33,7 @@ internal interface IFileOperationService
///
/// Convenience for AddFileTab with DoNotAddToDockPanel = true.
- /// Used by LoadProject for layout-restored windows.
+ /// Used by LoadSession for layout-restored windows.
///
LogWindow AddFileTabDeferred (string fileName, bool isTempFile, string? title, bool forcePersistenceLoading, ILogLineMemoryColumnizer? preProcessColumnizer);
diff --git a/src/LogExpert.UI/Interface/IProjectFileHandler.cs b/src/LogExpert.UI/Interface/IProjectFileHandler.cs
deleted file mode 100644
index dff9d966..00000000
--- a/src/LogExpert.UI/Interface/IProjectFileHandler.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using LogExpert.Core.Classes.Persister;
-using LogExpert.UI.Services.ProjectFileHandlerService;
-
-namespace LogExpert.UI.Interface;
-
-internal interface IProjectFileHandler
-{
- ProjectLoadOutcome LoadProject (string projectFileName);
-
- ContinueLoadResult ContinueLoad (ProjectLoadOutcome loadOutcome, MissingFilesResolution? resolution, bool restoreLayout);
-
- bool SaveProject (string projectFileName, ProjectData projectData, out string? errorMessage);
-}
\ No newline at end of file
diff --git a/src/LogExpert.UI/Interface/ISessionHandler.cs b/src/LogExpert.UI/Interface/ISessionHandler.cs
new file mode 100644
index 00000000..cd5b913c
--- /dev/null
+++ b/src/LogExpert.UI/Interface/ISessionHandler.cs
@@ -0,0 +1,13 @@
+using LogExpert.Core.Classes.Persister;
+using LogExpert.UI.Services.SessionHandlerService;
+
+namespace LogExpert.UI.Interface;
+
+internal interface ISessionHandler
+{
+ SessionLoadOutcome LoadSession (string sessionFileName);
+
+ ContinueLoadResult ContinueLoad (SessionLoadOutcome loadOutcome, MissingFilesResolution? resolution, bool restoreLayout);
+
+ bool SaveSession (string sessionFileName, SessionData sessionData, out string? errorMessage);
+}
\ No newline at end of file
diff --git a/src/LogExpert.UI/Services/FileOperationService/FileOperationService.cs b/src/LogExpert.UI/Services/FileOperationService/FileOperationService.cs
index 56a6a3f6..a8a77d51 100644
--- a/src/LogExpert.UI/Services/FileOperationService/FileOperationService.cs
+++ b/src/LogExpert.UI/Services/FileOperationService/FileOperationService.cs
@@ -22,7 +22,7 @@ internal sealed class FileOperationService (
IPluginRegistry pluginRegistry,
Func logWindowFactory,
Func clipboardTextProvider,
- Action projectFileCallback) : IFileOperationService
+ Action loadSessionCallback) : IFileOperationService
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
@@ -32,7 +32,7 @@ internal sealed class FileOperationService (
private readonly IPluginRegistry _pluginRegistry = pluginRegistry;
private readonly Func _logWindowFactory = logWindowFactory;
private readonly Func _clipboardTextProvider = clipboardTextProvider;
- private readonly Action _projectFileCallback = projectFileCallback;
+ private readonly Action _loadSessionCallback = loadSessionCallback;
public event EventHandler? FileHistoryChanged;
public event EventHandler? FileOpened;
@@ -189,8 +189,9 @@ public LogWindow AddTempFileTab (string fileName, string title)
{
foreach (var sessionFile in fileNames.Where(f => f.EndsWith(".lxj", StringComparison.OrdinalIgnoreCase)))
{
- _projectFileCallback(sessionFile, false);
+ _loadSessionCallback(sessionFile, false);
}
+
var logs = fileNames.Where(f => !f.EndsWith(".lxj", StringComparison.OrdinalIgnoreCase)).ToArray();
return logs.Length > 0 ? AddMultiFileTab(logs) : null;
}
@@ -231,7 +232,7 @@ public MultiFileDecision LoadFilesWithOption (string[] fileNames, bool invertLog
{
if (fileNames[0].EndsWith(".lxj", StringComparison.OrdinalIgnoreCase))
{
- _projectFileCallback(fileNames[0], true);
+ _loadSessionCallback(fileNames[0], true);
return MultiFileDecision.Cancel; // Already handled
}
@@ -269,7 +270,7 @@ public void AddFileTabs (string[] fileNames)
{
if (fileName.EndsWith(".lxj", StringComparison.OrdinalIgnoreCase))
{
- _projectFileCallback(fileName, false);
+ _loadSessionCallback(fileName, false);
}
else
{
diff --git a/src/LogExpert.UI/Services/ProjectFileHandlerService/ContinueLoadResult.cs b/src/LogExpert.UI/Services/SessionHandlerService/ContinueLoadResult.cs
similarity index 77%
rename from src/LogExpert.UI/Services/ProjectFileHandlerService/ContinueLoadResult.cs
rename to src/LogExpert.UI/Services/SessionHandlerService/ContinueLoadResult.cs
index ee71c88a..250eaa02 100644
--- a/src/LogExpert.UI/Services/ProjectFileHandlerService/ContinueLoadResult.cs
+++ b/src/LogExpert.UI/Services/SessionHandlerService/ContinueLoadResult.cs
@@ -1,4 +1,4 @@
-namespace LogExpert.UI.Services.ProjectFileHandlerService;
+namespace LogExpert.UI.Services.SessionHandlerService;
internal readonly record struct ContinueLoadResult
{
diff --git a/src/LogExpert.UI/Services/ProjectFileHandlerService/MissingFilesResolution.cs b/src/LogExpert.UI/Services/SessionHandlerService/MissingFilesResolution.cs
similarity index 82%
rename from src/LogExpert.UI/Services/ProjectFileHandlerService/MissingFilesResolution.cs
rename to src/LogExpert.UI/Services/SessionHandlerService/MissingFilesResolution.cs
index 0a14b1b3..53d83334 100644
--- a/src/LogExpert.UI/Services/ProjectFileHandlerService/MissingFilesResolution.cs
+++ b/src/LogExpert.UI/Services/SessionHandlerService/MissingFilesResolution.cs
@@ -1,4 +1,4 @@
-namespace LogExpert.UI.Services.ProjectFileHandlerService;
+namespace LogExpert.UI.Services.SessionHandlerService;
internal readonly record struct MissingFilesResolution
{
diff --git a/src/LogExpert.UI/Services/ProjectFileHandlerService/ProjectFileHandler.cs b/src/LogExpert.UI/Services/SessionHandlerService/SessionHandler.cs
similarity index 62%
rename from src/LogExpert.UI/Services/ProjectFileHandlerService/ProjectFileHandler.cs
rename to src/LogExpert.UI/Services/SessionHandlerService/SessionHandler.cs
index 6071fca1..2178b37c 100644
--- a/src/LogExpert.UI/Services/ProjectFileHandlerService/ProjectFileHandler.cs
+++ b/src/LogExpert.UI/Services/SessionHandlerService/SessionHandler.cs
@@ -8,71 +8,71 @@
using NLog;
-namespace LogExpert.UI.Services.ProjectFileHandlerService;
+namespace LogExpert.UI.Services.SessionHandlerService;
[SupportedOSPlatform("windows")]
-internal sealed class ProjectFileHandler (
+internal sealed class SessionHandler (
IPluginRegistry pluginRegistry,
Func addFileTab)
- : IProjectFileHandler
+ : ISessionHandler
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
- public ProjectLoadOutcome LoadProject (string projectFileName)
+ public SessionLoadOutcome LoadSession (string sessionFileName)
{
try
{
- if (!File.Exists(projectFileName))
+ if (!File.Exists(sessionFileName))
{
- _logger.Warn("LoadProject: File does not exist: {FileName}", projectFileName);
+ _logger.Warn("LoadSession: File does not exist: {FileName}", sessionFileName);
- return new ProjectLoadOutcome
+ return new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.Error,
- ErrorMessage = $"Project file not found: {projectFileName}"
+ Status = SessionLoadOutcome.LoadStatus.Error,
+ ErrorMessage = $"Project file not found: {sessionFileName}"
};
}
- var loadResult = ProjectPersister.LoadProjectData(projectFileName, pluginRegistry);
+ var loadResult = SessionPersister.LoadSessionData(sessionFileName, pluginRegistry);
- if (loadResult?.ProjectData == null)
+ if (loadResult?.SessionData == null)
{
- _logger.Warn("LoadProject: ProjectData is null for {FileName}", projectFileName);
+ _logger.Warn("LoadSession: SessionData is null for {FileName}", sessionFileName);
- return new ProjectLoadOutcome
+ return new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.Error,
- ErrorMessage = Resources.LoadProject_UI_Message_Error_FileMaybeCorruptedOrInaccessible
+ Status = SessionLoadOutcome.LoadStatus.Error,
+ ErrorMessage = Resources.LoadSession_UI_Message_Error_FileMaybeCorruptedOrInaccessible
};
}
- var projectData = loadResult.ProjectData;
+ var sessionData = loadResult.SessionData;
- if (projectData.FileNames.Count == 0)
+ if (sessionData.FileNames.Count == 0)
{
- _logger.Warn("LoadProject: No files in project {FileName}", projectFileName);
+ _logger.Warn("LoadSession: No files in project {FileName}", sessionFileName);
- return new ProjectLoadOutcome
+ return new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.EmptyProject,
- ErrorMessage = Resources.LoadProject_UI_Message_Message_FilesForSessionCouldNotBeFound
+ Status = SessionLoadOutcome.LoadStatus.EmptySession,
+ ErrorMessage = Resources.LoadSession_UI_Message_Message_FilesForSessionCouldNotBeFound
};
}
- var layoutXml = projectData.TabLayoutXml;
+ var layoutXml = sessionData.TabLayoutXml;
return loadResult.RequiresUserIntervention
- ? new ProjectLoadOutcome
+ ? new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.NeedsIntervention,
- ProjectData = projectData,
+ Status = SessionLoadOutcome.LoadStatus.NeedsIntervention,
+ SessionData = sessionData,
ValidationResult = loadResult.ValidationResult,
LayoutXml = layoutXml
}
- : new ProjectLoadOutcome
+ : new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.Success,
- ProjectData = projectData,
+ Status = SessionLoadOutcome.LoadStatus.Success,
+ SessionData = sessionData,
LayoutXml = layoutXml
};
}
@@ -81,50 +81,50 @@ UnauthorizedAccessException or
InvalidOperationException or
Newtonsoft.Json.JsonException)
{
- _logger.Error(ex, "LoadProject: Exception loading {FileName}", projectFileName);
+ _logger.Error(ex, "LoadSession: Exception loading {FileName}", sessionFileName);
- return new ProjectLoadOutcome
+ return new SessionLoadOutcome
{
- Status = ProjectLoadOutcome.LoadStatus.Error,
+ Status = SessionLoadOutcome.LoadStatus.Error,
ErrorMessage = $"Error loading project: {ex.Message}"
};
}
}
- public ContinueLoadResult ContinueLoad (ProjectLoadOutcome loadOutcome, MissingFilesResolution? resolution, bool restoreLayout)
+ public ContinueLoadResult ContinueLoad (SessionLoadOutcome loadOutcome, MissingFilesResolution? resolution, bool restoreLayout)
{
ArgumentNullException.ThrowIfNull(loadOutcome);
- ArgumentNullException.ThrowIfNull(loadOutcome.ProjectData);
+ ArgumentNullException.ThrowIfNull(loadOutcome.SessionData);
- var projectData = loadOutcome.ProjectData;
+ var sessionData = loadOutcome.SessionData;
// Apply selected alternatives to file paths (in-place, exact string match)
if (resolution?.SelectedAlternatives is { } alternatives)
{
- for (int i = 0; i < projectData.FileNames.Count; i++)
+ for (int i = 0; i < sessionData.FileNames.Count; i++)
{
- var originalPath = projectData.FileNames[i];
+ var originalPath = sessionData.FileNames[i];
if (alternatives.TryGetValue(originalPath, out var replacement))
{
- projectData.FileNames[i] = replacement;
+ sessionData.FileNames[i] = replacement;
}
}
}
// Save updated session file if requested
- if (resolution is { UpdateSessionFile: true } && !string.IsNullOrEmpty(projectData.ProjectFilePath))
+ if (resolution is { UpdateSessionFile: true } && !string.IsNullOrEmpty(sessionData.SessionFilePath))
{
try
{
- ProjectPersister.SaveProjectData(projectData.ProjectFilePath, projectData);
- _logger.Info("ContinueLoad: Updated session file {FileName}", projectData.ProjectFilePath);
+ SessionPersister.SaveSessionData(sessionData.SessionFilePath, sessionData);
+ _logger.Info("ContinueLoad: Updated session file {FileName}", sessionData.SessionFilePath);
}
catch (Exception ex) when (ex is IOException or
UnauthorizedAccessException or
InvalidOperationException or
ArgumentException)
{
- _logger.Error(ex, "ContinueLoad: Failed to update session file {FileName}", projectData.ProjectFilePath);
+ _logger.Error(ex, "ContinueLoad: Failed to update session file {FileName}", sessionData.SessionFilePath);
}
}
@@ -132,7 +132,7 @@ InvalidOperationException or
if (resolution is { OpenInNewWindow: true })
{
var resolvedFiles = PersisterHelpers.FindFilenameForSettings(
- projectData.FileNames.AsReadOnly(), pluginRegistry);
+ sessionData.FileNames.AsReadOnly(), pluginRegistry);
return new ContinueLoadResult
{
@@ -146,7 +146,7 @@ InvalidOperationException or
bool deferForLayout = loadOutcome.HasLayoutData && restoreLayout;
int openedCount = 0;
- foreach (var fileName in projectData.FileNames)
+ foreach (var fileName in sessionData.FileNames)
{
var request = new FileTabRequest
{
@@ -181,11 +181,11 @@ and not InvalidProgramException
};
}
- public bool SaveProject (string projectFileName, ProjectData projectData, out string? errorMessage)
+ public bool SaveSession (string sessionFileName, SessionData sessionData, out string? errorMessage)
{
try
{
- ProjectPersister.SaveProjectData(projectFileName, projectData);
+ SessionPersister.SaveSessionData(sessionFileName, sessionData);
errorMessage = null;
return true;
}
@@ -194,7 +194,7 @@ UnauthorizedAccessException or
InvalidOperationException or
ArgumentException)
{
- _logger.Error(ex, "SaveProject: Failed to save {FileName}", projectFileName);
+ _logger.Error(ex, "SaveSession: Failed to save {FileName}", sessionFileName);
errorMessage = $"Error saving project: {ex.Message}";
return false;
}
diff --git a/src/LogExpert.UI/Services/ProjectFileHandlerService/ProjectLoadOutcome.cs b/src/LogExpert.UI/Services/SessionHandlerService/SessionLoadOutcome.cs
similarity index 60%
rename from src/LogExpert.UI/Services/ProjectFileHandlerService/ProjectLoadOutcome.cs
rename to src/LogExpert.UI/Services/SessionHandlerService/SessionLoadOutcome.cs
index d1e352e7..146d6c27 100644
--- a/src/LogExpert.UI/Services/ProjectFileHandlerService/ProjectLoadOutcome.cs
+++ b/src/LogExpert.UI/Services/SessionHandlerService/SessionLoadOutcome.cs
@@ -1,22 +1,22 @@
using LogExpert.Core.Classes.Persister;
-namespace LogExpert.UI.Services.ProjectFileHandlerService;
+namespace LogExpert.UI.Services.SessionHandlerService;
-internal sealed class ProjectLoadOutcome
+internal sealed class SessionLoadOutcome
{
public enum LoadStatus
{
Success,
NeedsIntervention,
Error,
- EmptyProject
+ EmptySession
}
public required LoadStatus Status { get; init; }
- public ProjectData? ProjectData { get; init; }
+ public SessionData? SessionData { get; init; }
- public ProjectValidationResult? ValidationResult { get; init; }
+ public SessionValidationResult? ValidationResult { get; init; }
public string? LayoutXml { get; init; }
diff --git a/src/PluginRegistry/PluginHashGenerator.Generated.cs b/src/PluginRegistry/PluginHashGenerator.Generated.cs
index 1a47eae3..e387aad4 100644
--- a/src/PluginRegistry/PluginHashGenerator.Generated.cs
+++ b/src/PluginRegistry/PluginHashGenerator.Generated.cs
@@ -10,7 +10,7 @@ public static partial class PluginValidator
{
///
/// Gets pre-calculated SHA256 hashes for built-in plugins.
- /// Generated: 2026-05-28 14:55:19 UTC
+ /// Generated: 2026-05-28 19:52:00 UTC
/// Configuration: Release
/// Plugin count: 21
///
@@ -18,27 +18,27 @@ public static Dictionary GetBuiltInPluginHashes()
{
return new Dictionary(StringComparer.OrdinalIgnoreCase)
{
- ["AutoColumnizer.dll"] = "3EA41A42F0A17C1DDAE3807E899B8F0E4B6A3CFCD0412FB04370C29F218A34C9",
+ ["AutoColumnizer.dll"] = "EDF4B48F71CF2192A99F63B9FE493661521A2E671D9185CCEB181B513DF0C1A5",
["BouncyCastle.Cryptography.dll"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6",
["BouncyCastle.Cryptography.dll (x86)"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6",
- ["CsvColumnizer.dll"] = "31343A536E79669DBC292CBFC728CB63F77EA661C4E9F36FE4E3025166BA444B",
- ["CsvColumnizer.dll (x86)"] = "31343A536E79669DBC292CBFC728CB63F77EA661C4E9F36FE4E3025166BA444B",
- ["DefaultPlugins.dll"] = "3820088CC0BFB6584BB48BA3F45710D2DD3076163F82FDC41400BF467611444C",
- ["FlashIconHighlighter.dll"] = "07518957DFE748B01D86870CFC3AE05AE8DE2EBE602C268997585A2F6AE3D505",
- ["GlassfishColumnizer.dll"] = "77DC1A20B32491055DDE72F159894AE6889218BA2D1F2AF709D3388E83371AF5",
- ["JsonColumnizer.dll"] = "846B45CFD8B3E24E12B065AC0D0F0252BFCDEDA8CA8E4E06A67B2200662CB5AE",
- ["JsonCompactColumnizer.dll"] = "0E9BC4CEF045D3C2C8BDACA96B40A469EF65BB80326332A0F8325769855D65D8",
- ["Log4jXmlColumnizer.dll"] = "665546EBF0D55758214034CBD026D54B6B018FF90D240076659E674B2350E7CD",
- ["LogExpert.Resources.dll"] = "202FE9534087C11461DFF3A8653410181EF481C8A3C40AB96868389189B49DCE",
+ ["CsvColumnizer.dll"] = "397CCA331A6FD1687C8CBDF78DF6DF9C080B7A16860C511F2DC0E275A5257C4F",
+ ["CsvColumnizer.dll (x86)"] = "397CCA331A6FD1687C8CBDF78DF6DF9C080B7A16860C511F2DC0E275A5257C4F",
+ ["DefaultPlugins.dll"] = "58B2ED626556C1B0E1B02D62DF0A0658618FA05B309BFAA2C2582B180594B7E6",
+ ["FlashIconHighlighter.dll"] = "0861244E3F7B52D44B8487732724E277658143E5940AACFF977AA74048FF1B9D",
+ ["GlassfishColumnizer.dll"] = "B75D7808007E9CA1235E282B07431C70A16D378B647B58BAEE605075D7B8FF08",
+ ["JsonColumnizer.dll"] = "A469FEC6C1E6F7B209D960CE7C3416CF80EFD5A2A062BCAD7B0E8AE6A3988ABF",
+ ["JsonCompactColumnizer.dll"] = "F6735973634AE8A986BC9FD8B89F8817D36458E488B6A7BCD2320883DD4BA5BC",
+ ["Log4jXmlColumnizer.dll"] = "D148D1FEC9A0152714AAE8CBAB0A9BDDF9ACFBFED3FF0CEB8D5966908DC24760",
+ ["LogExpert.Resources.dll"] = "A25FDA182EECF5BCC828C0C3F145FD774530980E9C72AC17591043677FA9E201",
["Microsoft.Extensions.DependencyInjection.Abstractions.dll"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93",
["Microsoft.Extensions.DependencyInjection.Abstractions.dll (x86)"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93",
["Microsoft.Extensions.Logging.Abstractions.dll"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D",
["Microsoft.Extensions.Logging.Abstractions.dll (x86)"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D",
- ["RegexColumnizer.dll"] = "4461F126C06332E732970E2D90DD8289C2F004B5B4BFF26AAC1EE6132717FEEA",
- ["SftpFileSystem.dll"] = "F77A0C6C717E5BDB3CDB03DBE68DF1E39413E004893B4DDD2BEE5E59B7DB140B",
- ["SftpFileSystem.dll (x86)"] = "6DD7950C31A3BDEE31B283BE78C17FEEDE8D2CDA13869A98FBEEA2F6C9BFFC16",
- ["SftpFileSystem.Resources.dll"] = "4ED850E091351011208213BA1D8DDC2371D115316D87A7410B0C1AC901492BE8",
- ["SftpFileSystem.Resources.dll (x86)"] = "4ED850E091351011208213BA1D8DDC2371D115316D87A7410B0C1AC901492BE8",
+ ["RegexColumnizer.dll"] = "C0DC4D43DB02C2015A490BC4C62549D7CDD1B107C6944F20DB0B4C4285371288",
+ ["SftpFileSystem.dll"] = "AAD426FB4E53916B8B26F427374EA3E6706B940564F4CD0E059E69A613CBE02B",
+ ["SftpFileSystem.dll (x86)"] = "6FEC9B0EC9B9241ACA09999C55AD96F33FD52A2A1A14DC513D06BC42BF2C1B86",
+ ["SftpFileSystem.Resources.dll"] = "0F8C4D65FE7E8A79A11DF521116E36E65AC28DE732C67264A3790AD2F1E4CBB8",
+ ["SftpFileSystem.Resources.dll (x86)"] = "0F8C4D65FE7E8A79A11DF521116E36E65AC28DE732C67264A3790AD2F1E4CBB8",
};
}