224 lines
7.2 KiB
C#
224 lines
7.2 KiB
C#
using System;
|
|
using JD.Kernel.StaticHelpers;
|
|
using JD.Kernel.Structs;
|
|
using JD.LogService;
|
|
using JD.Serializers.Xml;
|
|
|
|
namespace JD.TeaBoxAddinSystem.Addins.Management
|
|
{
|
|
/// <summary>
|
|
/// Helper class used to deserialize an addin or other addin objects from xml.
|
|
/// </summary>
|
|
public abstract class AddinXmlSerializer
|
|
{
|
|
#region Constants
|
|
|
|
#region Nodes and attributes
|
|
|
|
internal const string IdAttribute = "id";
|
|
internal const string NameAttribute = "name";
|
|
internal const string DeprecatedAttribute = "deprecated";
|
|
internal const string VersionAttribute = "version";
|
|
internal const string AuthorAttribute = "author";
|
|
internal const string UrlAttribute = "url";
|
|
internal const string DescriptionAttribute = "description";
|
|
internal const string CategoryAttribute = "category";
|
|
internal const string X86OnlyAttribute = "x86_only";
|
|
|
|
internal const string FilesNode = "Files";
|
|
internal const string ImportNode = "Import";
|
|
internal const string AssemblyAttribute = "assembly";
|
|
internal const string ResourceAttribute = "resource";
|
|
internal const string FileAttribute = "file";
|
|
|
|
internal const string DependenciesNode = "Dependencies";
|
|
internal const string AddinNode = "Addin";
|
|
|
|
internal const string ExtensionNode = "Extension";
|
|
internal const string ExtensionPointNode = "ExtensionPoint";
|
|
internal const string PathAttribute = "path";
|
|
|
|
internal const string ModuleNode = "Module";
|
|
internal const string IncludeNode = "Include";
|
|
|
|
internal const string ExtensionNodeSetNode = "ExtensionNodeSet";
|
|
internal const string ExtensionNodeNode = "ExtensionNode";
|
|
internal const string DescriptionNode = "Description";
|
|
internal const string TypeAttribute = "type";
|
|
internal const string ObjectTypeAttribute = "object";
|
|
|
|
internal const string ConditionNodeNode = "ConditionNode";
|
|
internal const string ConditionPrefix = "If";
|
|
internal const string AndNode = "And";
|
|
internal const string OrNode = "Or";
|
|
internal const string XorNode = "Xor";
|
|
internal const string NotNode = "Not";
|
|
internal const string TrueNode = "True";
|
|
internal const string FalseNode = "False";
|
|
internal const string TargetAttribute = "target";
|
|
|
|
#endregion
|
|
|
|
#region Messages
|
|
|
|
internal const string InvalidOrMissingAttribute = "Invalid or missing \"{0}\" attribute in \"{1}\" element";
|
|
internal const string ElementMustBeEmpty = "\"{0}\" elements must be empty";
|
|
internal const string UnexpectedXmlElement = "Unexpected xml element \"{0}\"";
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Variables
|
|
|
|
/// <summary>
|
|
/// Logger.
|
|
/// </summary>
|
|
protected readonly ILogger m_logger;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
internal AddinXmlSerializer(ILogger logger)
|
|
{
|
|
Throw.IfNull(logger, "logger");
|
|
m_logger = logger;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// Current File Location.
|
|
/// </summary>
|
|
protected abstract FileLocation CurrentFileLocation
|
|
{
|
|
get;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
#region Static Methods
|
|
|
|
/// <summary>
|
|
/// Reads an addin from the given <paramref name="reader"/>.
|
|
/// </summary>
|
|
/// <param name="reader"></param>
|
|
/// <param name="logger"></param>
|
|
/// <returns></returns>
|
|
public static Addin ReadAddin(XmlSerializerReader reader, ILogger logger)
|
|
{
|
|
return new AddinXmlSerializerReaderSerializer(reader, logger).Serialize();
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Serializes the addin.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected abstract Addin Serialize();
|
|
|
|
/// <summary>
|
|
/// Parses a version from a string.
|
|
/// </summary>
|
|
/// <param name="version"></param>
|
|
/// <returns></returns>
|
|
protected Version ParseVersion(string version)
|
|
{
|
|
if (string.IsNullOrEmpty(version))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
return new Version(version);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogError($"Cannot convert '{version}' to a version: {e.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs a message.
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="importance"></param>
|
|
protected void LogMessage(string message, MessageImportance importance)
|
|
{
|
|
m_logger.Log(new Message(message) { Importance = importance });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs a warning.
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void LogWarning(string message)
|
|
{
|
|
m_logger.Log(new Error(LogCategory.Warning, message) { Origin = CurrentFileLocation });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs an error.
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void LogError(string message)
|
|
{
|
|
m_logger.Log(new Error(LogCategory.Error, message) { Origin = CurrentFileLocation });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs an unexpected xml node.
|
|
/// </summary>
|
|
/// <param name="actualNode"></param>
|
|
protected void LogUnexpectedXmlElement(string actualNode)
|
|
{
|
|
LogError(string.Format(UnexpectedXmlElement, actualNode));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs an invalid attribute node.
|
|
/// </summary>
|
|
/// <param name="attribute"></param>
|
|
/// <param name="node"></param>
|
|
protected void LogInvalidAttributeElement(string attribute, string node)
|
|
{
|
|
LogError(string.Format(InvalidOrMissingAttribute, attribute, node));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs a duplicate node.
|
|
/// </summary>
|
|
/// <param name="nodeType"></param>
|
|
/// <param name="nodeName"></param>
|
|
/// <param name="existingLocation"></param>
|
|
protected void LogDuplicateElement(string nodeType, string nodeName, FileLocation? existingLocation)
|
|
{
|
|
System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(nodeType));
|
|
System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(nodeName));
|
|
|
|
LogError($"Another {nodeType} named \"{nodeName}\" was already defined earlier in this context at {existingLocation}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs an already defined description.
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="existingLocation"></param>
|
|
protected void LogDescriptionAlreadyDefined(string name, FileLocation? existingLocation)
|
|
{
|
|
System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(name));
|
|
|
|
LogWarning($"Description of \"{name}\" will be ignored because it was already defined earlier at {existingLocation}");
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|