Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions src/LogExpert.Core/Classes/Persister/ProjectData.cs

This file was deleted.

133 changes: 0 additions & 133 deletions src/LogExpert.Core/Classes/Persister/ProjectPersister.cs

This file was deleted.

38 changes: 38 additions & 0 deletions src/LogExpert.Core/Classes/Persister/SessionData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Newtonsoft.Json;

namespace LogExpert.Core.Classes.Persister;

/// <summary>
/// Persisted workspace contents of a Session (.lxj): a list of log file paths
/// plus a tab/window layout XML blob. See CONTEXT.md "Sessions".
/// </summary>
[Serializable]
public class SessionData
{
#region Fields

/// <summary>
/// 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.
/// </summary>
public List<string> FileNames { get; set; } = [];

/// <summary>
/// Gets or sets the XML representation of the tab layout configuration.
/// </summary>
public string TabLayoutXml { get; set; }

/// <summary>
/// Gets or sets the full file path to the Session (.lxj) on disk.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[JsonProperty("SessionFilePath")]
public string SessionFilePath { get; set; }

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@
namespace LogExpert.Core.Classes.Persister;

/// <summary>
/// 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.
/// </summary>
public static class ProjectFileResolver
public static class SessionFileResolver
{
/// <summary>
/// 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.
/// </summary>
/// <param name="projectData">The project data containing file references</param>
/// <param name="sessionData">The Session data containing file references</param>
/// <param name="pluginRegistry">Plugin registry for file system resolution (optional)</param>
/// <returns>List of tuples containing (logFilePath, originalFilePath)</returns>
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));
}

return resolved.AsReadOnly();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.</remarks>
public static class ProjectFileValidator
public static class SessionFileValidator
{
/// <summary>
/// Validates the files referenced by the specified project and identifies missing or accessible files using
Expand All @@ -21,21 +21,21 @@ public static class ProjectFileValidator
/// <remarks>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.</remarks>
/// <param name="projectData">The project data containing the list of file names to validate and the project file path. Cannot be null.</param>
/// <param name="sessionData">The project data containing the list of file names to validate and the project file path. Cannot be null.</param>
/// <param name="pluginRegistry">The plugin registry used to resolve file system plugins for URI-based files. Cannot be null.</param>
/// <returns>A ProjectValidationResult containing lists of valid files, missing files, and possible alternative file paths
/// <returns>A SessionValidationResult containing lists of valid files, missing files, and possible alternative file paths
/// for missing files.</returns>
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);

Expand All @@ -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;
}
}
Expand Down Expand Up @@ -138,12 +138,12 @@ or DriveNotFoundException
/// result.</remarks>
/// <param name="fileName">The name or path of the file to search for. Can be an absolute or relative path. Cannot be null, empty, or
/// whitespace.</param>
/// <param name="projectFilePath">The full path to the project file used as a reference for searching related directories. Can be null or empty if
/// <param name="sessionFilePath">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.</param>
/// <param name="cachedDriveLetters">Pre-computed list of fixed drive letters to avoid repeated DriveInfo.GetDrives() calls.</param>
/// <returns>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.</returns>
private static List<string> FindAlternativePaths (string fileName, string projectFilePath, List<char> cachedDriveLetters)
private static List<string> FindAlternativePaths (string fileName, string sessionFilePath, List<char> cachedDriveLetters)
{
var alternatives = new List<string>();

Expand All @@ -160,21 +160,21 @@ private static List<string> 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))
Expand Down Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ namespace LogExpert.Core.Classes.Persister;
/// <summary>
/// Represents the result of loading a project file, including validation information.
/// </summary>
public class ProjectLoadResult
public class SessionLoadResult
{
/// <summary>
/// The loaded project data (contains resolved log file paths).
/// </summary>
public ProjectData ProjectData { get; set; }
public SessionData SessionData { get; set; }

/// <summary>
/// Validation result containing valid, missing, and alternative file paths.
/// </summary>
public ProjectValidationResult ValidationResult { get; set; }
public SessionValidationResult ValidationResult { get; set; }

/// <summary>
/// Mapping of original file references to resolved log files.
Expand Down
Loading