190 lines
6.9 KiB
C#
190 lines
6.9 KiB
C#
// SzfObject.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using SessionZero.Pages;
|
|
|
|
namespace SessionZero.Data;
|
|
|
|
/// <summary>
|
|
/// Represents common metadata for all SzfObjects.
|
|
/// </summary>
|
|
public class SzfMetadata
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public Version? Version { get; set; }
|
|
public Guid Guid { get; set; }
|
|
public string? Description { get; set; }
|
|
public string? Author { get; set; }
|
|
}
|
|
|
|
public abstract class SzfObject
|
|
{
|
|
/// <summary>
|
|
/// The unique string identifier for this SzfObject type, derived from its SzfObjectAttribute.
|
|
/// </summary>
|
|
public string TypeIdentifier { get; }
|
|
|
|
/// <summary>
|
|
/// Common metadata for all SzfObjects.
|
|
/// </summary>
|
|
public SzfMetadata Metadata { get; set; } = new SzfMetadata();
|
|
|
|
/// <summary>
|
|
/// Default constructor that reads the TypeIdentifier from the SzfObjectAttribute.
|
|
/// </summary>
|
|
protected SzfObject()
|
|
{
|
|
// Read the SzfObjectAttribute from the concrete class type
|
|
var attribute = GetType().GetCustomAttribute<SzfObjectAttribute>();
|
|
if (attribute == null)
|
|
{
|
|
// This indicates a missing attribute, which means the class is not properly defined as an SzfObject.
|
|
throw new InvalidOperationException(
|
|
$"SzfObject class '{GetType().Name}' is missing the SzfObjectAttribute. All concrete SzfObject types must have this attribute.");
|
|
}
|
|
|
|
TypeIdentifier = attribute.TypeIdentifier;
|
|
|
|
// Initialize metadata with a new GUID, this is a default, can be overridden by parsing
|
|
Metadata.Guid = Guid.NewGuid();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populates the object's metadata from a dictionary of parsed SzfFields.
|
|
/// This method is intended to be overridden by derived classes to handle their specific metadata.
|
|
/// </summary>
|
|
/// <param name="metadata">A dictionary of metadata fields.</param>
|
|
public virtual void PopulateFromMetadata(Dictionary<string, SzfField> metadata)
|
|
{
|
|
if (metadata.TryGetValue("Name", out var nameField))
|
|
Metadata.Name = nameField.Value?.ToString() ?? string.Empty;
|
|
|
|
if (metadata.TryGetValue("Version", out var versionField))
|
|
{
|
|
if (Version.TryParse(versionField.Value?.ToString(), out var ver))
|
|
{
|
|
Metadata.Version = ver;
|
|
}
|
|
}
|
|
|
|
if (metadata.TryGetValue("GUID", out var guidField))
|
|
{
|
|
if (Guid.TryParse(guidField.Value?.ToString() ?? string.Empty, out var guid))
|
|
{
|
|
Metadata.Guid = guid;
|
|
}
|
|
}
|
|
|
|
if (metadata.TryGetValue("Description", out var descriptionField))
|
|
Metadata.Description = descriptionField.Value?.ToString();
|
|
|
|
if (metadata.TryGetValue("Author", out var authorField))
|
|
Metadata.Author = authorField.Value?.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses the sections of the Szf object from a flat list of SzfSection objects
|
|
/// and constructs the object's internal data structure. This is an abstract method
|
|
/// that must be implemented by derived classes.
|
|
/// </summary>
|
|
/// <param name="sections">A list of parsed SzfSections.</param>
|
|
public abstract void ParseSections(List<SzfSection> sections);
|
|
|
|
/// <summary>
|
|
/// Generates the metadata section of the Szf file using the provided writer.
|
|
/// This method is virtual and can be extended by derived classes to add their specific metadata.
|
|
/// </summary>
|
|
/// <param name="writer">The SzfFieldWriter to use for writing.</param>
|
|
public virtual void GenerateMetadata(SzfFieldWriter writer)
|
|
{
|
|
// Write standard metadata fields common to all SzfObjects
|
|
writer.AppendSectionHeader("Metadata"); // Corrected method call
|
|
writer.WriteField("Name", "text", Metadata.Name);
|
|
writer.WriteField("Version", "text",
|
|
Metadata.Version?.ToString() ?? string.Empty); // Ensure Version is not null
|
|
writer.WriteField("GUID", "text", Metadata.Guid.ToString());
|
|
|
|
if (!string.IsNullOrEmpty(Metadata.Description))
|
|
writer.WriteField("Description", "text-field", Metadata.Description);
|
|
if (!string.IsNullOrEmpty(Metadata.Author))
|
|
writer.WriteField("Author", "text", Metadata.Author);
|
|
|
|
writer.AppendLine(); // Corrected method call to end section with a newline
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates the content sections of the Szf file using the provided writer.
|
|
/// This is an abstract method that must be implemented by derived classes.
|
|
/// </summary>
|
|
/// <param name="writer">The SzfFieldWriter to use for writing.</param>
|
|
public abstract void GenerateContent(SzfFieldWriter writer);
|
|
|
|
/// <summary>
|
|
/// Validates the current state of the Szf object.
|
|
/// This method is virtual and can be extended by derived classes to add their specific validation rules.
|
|
/// </summary>
|
|
/// <returns>A SzfValidationResult indicating any errors or warnings.</returns>
|
|
public virtual SzfValidationResult Validate()
|
|
{
|
|
var result = new SzfValidationResult();
|
|
|
|
if (string.IsNullOrWhiteSpace(Metadata.Name))
|
|
result.AddError("Name is required for SzfObject");
|
|
if (Metadata.Version == null)
|
|
result.AddError("Version is required for SzfObject");
|
|
if (Metadata.Guid == Guid.Empty)
|
|
result.AddError("GUID is required for SzfObject");
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if required metadata fields are present and adds errors if they are missing.
|
|
/// </summary>
|
|
/// <param name="metadata">Dictionary containing metadata fields</param>
|
|
/// <param name="requiredFields">Array of required field names</param>
|
|
/// <param name="errors">List to add errors to</param>
|
|
protected void CheckRequiredMetadata(Dictionary<string, object> metadata, string[] requiredFields, List<SzfEditor.SzfError> errors)
|
|
{
|
|
if (metadata == null)
|
|
{
|
|
errors.Add(new SzfEditor.SzfError(0, "Missing Metadata section"));
|
|
return;
|
|
}
|
|
|
|
foreach (var field in requiredFields)
|
|
{
|
|
if (!metadata.ContainsKey(field) || metadata[field] == null || string.IsNullOrEmpty(metadata[field].ToString()))
|
|
{
|
|
errors.Add(new SzfEditor.SzfError(0, $"Missing required metadata: {field}"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class SzfValidationResult
|
|
{
|
|
public bool IsValid { get; set; } = true;
|
|
public List<string> Errors { get; set; } = [];
|
|
public List<string> Warnings { get; set; } = [];
|
|
|
|
public void AddError(string error)
|
|
{
|
|
Errors.Add(error);
|
|
IsValid = false;
|
|
}
|
|
|
|
public void AddWarning(string warning)
|
|
{
|
|
Warnings.Add(warning);
|
|
}
|
|
}
|
|
|
|
public class SzfField
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public string Type { get; set; } = string.Empty;
|
|
public object? Value { get; set; }
|
|
} |