using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using JD.Kernel.StaticHelpers;
using JD.Kernel.Structs;
using JD.TeaBoxAddinSystem.Addins.Description;
using JD.TeaBoxAddinSystem.Addins.Description.Conditions;
using JD.TeaBoxAddinSystem.Addins.Internal;
namespace JD.TeaBoxAddinSystem.Addins
{
///
/// An addin is a plugin that adds or extends some functionality. It can also define extension points for other addins.
///
public sealed class Addin
{
#region Inner Types
private class ExtensionTypeSetCollection : AddinObjectKeyedCollection
{
#region Constructor
internal ExtensionTypeSetCollection(Module owner)
: base(owner)
{
}
#endregion
#region Methods
///
/// Overriden.
///
///
///
protected override string GetKeyForItem(ExtensionTypeSet item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(item.Name));
return item.Name;
}
#endregion
}
private class ModuleCollection : Collection
{
#region Variables
private readonly Addin m_addin;
#endregion
#region Constructor
public ModuleCollection(Addin addin)
{
m_addin = addin;
}
#endregion
#region Methods
protected override void InsertItem(int index, Module item)
{
m_addin.ThrowIfLoaded();
base.InsertItem(index, item);
item.SetAddin(m_addin);
}
protected override void SetItem(int index, Module item)
{
m_addin.ThrowIfLoaded();
this[index].SetAddin(null);
base.SetItem(index, item);
item.SetAddin(m_addin);
}
protected override void RemoveItem(int index)
{
m_addin.ThrowIfLoaded();
this[index].SetAddin(null);
base.RemoveItem(index);
}
protected override void ClearItems()
{
m_addin.ThrowIfLoaded();
foreach (Module module in this)
{
module.SetAddin(null);
}
base.ClearItems();
}
#endregion
}
#endregion
#region Variables
private readonly AddinManifest m_manifest;
private readonly Module m_mainModule = new Module();
private readonly ModuleCollection m_modules;
private readonly ExtensionPointCollection m_extensionPoints;
private readonly ExtensionTypeSetCollection m_extensionTypeSets;
private readonly NodeTypeCollection m_conditionTypes;
private FileLocation? m_fileLocation;
private readonly List m_partialAddinFilenames = new List();
#endregion
#region Constructor
///
/// Constructor.
///
public Addin()
: this(null)
{
}
///
/// Constructor.
///
///
public Addin(string id)
{
m_manifest = new AddinManifest(this, id);
m_mainModule.SetAddin(this);
m_modules = new ModuleCollection(this);
m_extensionPoints = new ExtensionPointCollection(MainModule);
m_extensionTypeSets = new ExtensionTypeSetCollection(MainModule);
m_conditionTypes = new NodeTypeCollection(MainModule);
}
#endregion
#region Properties
///
/// Full id of the addin.
///
public string FullId
{
get
{
return Manifest.FullId;
}
}
///
/// Returns whether this addin is laoded.
///
public bool IsLoaded
{
get
{
return AddinManager.IsAddinLoaded(this);
}
}
///
/// Manifest of this addin.
///
public AddinManifest Manifest
{
get
{
return m_manifest;
}
}
///
/// Main module.
///
public Module MainModule
{
get
{
return m_mainModule;
}
}
///
/// All modules, including the main module.
///
public IEnumerable AllModules
{
get
{
yield return MainModule;
foreach (Module module in Modules)
{
yield return module;
}
}
}
///
/// Optional modules of this addin.
///
public IList Modules
{
get
{
return m_modules;
}
}
///
/// s defined in this addin.
///
public KeyedCollection ExtensionPoints
{
get
{
return m_extensionPoints;
}
}
///
/// The s defined in this addin.
///
public KeyedCollection ExtensionTypeSets
{
get
{
return m_extensionTypeSets;
}
}
///
/// The s defined in this addin.
///
public KeyedCollection ConditionTypes
{
get
{
return m_conditionTypes;
}
}
///
/// File Location of the addin.
///
public FileLocation? FileLocation
{
get
{
return m_fileLocation;
}
set
{
ThrowIfLoaded();
m_fileLocation = value;
}
}
///
/// Filenames of the partial addins that contributed to this addin.
///
public IList PartialAddinFilenames
{
get
{
return m_partialAddinFilenames.AsReadOnly();
}
}
#endregion
#region Methods
internal void AddPartialAddinFilename(string filename)
{
m_partialAddinFilenames.Add(filename);
}
internal void ThrowIfLoaded()
{
Throw.InvalidOperationIf(IsLoaded, "Cannot modify an addin while it is loaded.");
}
///
/// Overriden.
///
///
public override string ToString()
{
return
$"[{Manifest.FullId}{(IsLoaded ? string.Empty : " (not loaded)")}: {Modules.Count} optional modules, {ExtensionPoints.Count} extension points, {ExtensionTypeSets.Count} extension type sets]";
}
#endregion
}
}