JD2022-TU1/main/tools/framework/JD.TeaBoxAddinSystem/Addins/Description/NodeDescription.cs

435 lines
13 KiB
C#

using System.Collections.Generic;
using JD.Kernel.StaticHelpers;
namespace JD.TeaBoxAddinSystem.Addins.Description
{
/// <summary>
/// Describes a node in an addin.
/// </summary>
public abstract class NodeDescription : AddinObject
{
#region Inner Types
/// <summary>
/// A dictionary that doesn't throw <see cref="KeyNotFoundException"/>s all the times.
/// </summary>
private class ForgivingDictionary<K, V> : IDictionary<K, V>
{
#region Variables
private readonly Dictionary<K, V> m_innerDictionary;
#endregion
#region Constructors
/// <summary>
/// Constructor.
/// </summary>
protected ForgivingDictionary()
{
m_innerDictionary = new Dictionary<K, V>();
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="dictionary"></param>
public ForgivingDictionary(IDictionary<K, V> dictionary)
{
m_innerDictionary = new Dictionary<K, V>(dictionary);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="comparer"></param>
public ForgivingDictionary(IEqualityComparer<K> comparer)
{
m_innerDictionary = new Dictionary<K, V>(comparer);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="capacity"></param>
public ForgivingDictionary(int capacity)
{
m_innerDictionary = new Dictionary<K, V>(capacity);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="dictionary"></param>
/// <param name="comparer"></param>
public ForgivingDictionary(IDictionary<K, V> dictionary, IEqualityComparer<K> comparer)
{
m_innerDictionary = new Dictionary<K, V>(dictionary, comparer);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="capacity"></param>
/// <param name="comparer"></param>
public ForgivingDictionary(int capacity, IEqualityComparer<K> comparer)
{
m_innerDictionary = new Dictionary<K, V>(capacity, comparer);
}
#endregion
#region IDictionary<K,V> Members
/// <summary>
/// Adds the specified key and value to the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void Add(K key, V value)
{
OnAddValue(key, value);
m_innerDictionary.Add(key, value);
}
/// <summary>
/// Determines whether the <see cref="ForgivingDictionary{K, V}"/> contains the specified key.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool ContainsKey(K key)
{
if (ReferenceEquals(key, null))
{
return false;
}
return m_innerDictionary.ContainsKey(key);
}
/// <summary>
/// Gets a collection containing the keys in the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
public ICollection<K> Keys
{
get { return m_innerDictionary.Keys; }
}
/// <summary>
/// Removes the value with the specified key from the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool Remove(K key)
{
if (ReferenceEquals(key, null))
{
return false;
}
OnRemoveValue(key);
return m_innerDictionary.Remove(key);
}
/// <summary>
/// Gets the value associated with the specified key.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool TryGetValue(K key, out V value)
{
if (ReferenceEquals(key, null))
{
value = default(V);
return false;
}
return m_innerDictionary.TryGetValue(key, out value);
}
/// <summary>
/// Gets a collection containing the values in the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
public ICollection<V> Values
{
get { return m_innerDictionary.Values; }
}
/// <summary>
/// Gets or sets the value associated with the specified key.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public V this[K key]
{
get
{
V value;
TryGetValue(key, out value);
return value;
}
set
{
OnSetValue(key, value);
m_innerDictionary[key] = value;
}
}
#endregion
#region ICollection<KeyValuePair<K,V>> Members
/// <summary>
/// Adds the specified value to the ICollection with the specified key.
/// </summary>
/// <param name="item"></param>
void ICollection<KeyValuePair<K, V>>.Add(KeyValuePair<K, V> item)
{
OnAddValue(item.Key, item.Value);
((ICollection<KeyValuePair<K, V>>)m_innerDictionary).Add(item);
}
/// <summary>
/// Removes all keys and values from the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
public void Clear()
{
OnClear();
m_innerDictionary.Clear();
}
/// <summary>
/// Determines whether the ICollection contains a specific key and value.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool ICollection<KeyValuePair<K, V>>.Contains(KeyValuePair<K, V> item)
{
return ((ICollection<KeyValuePair<K, V>>)m_innerDictionary).Contains(item);
}
/// <summary>
/// Copies the elements of the ICollection to an array of type KeyValuePair, starting at the specified array index.
/// </summary>
/// <param name="array"></param>
/// <param name="arrayIndex"></param>
void ICollection<KeyValuePair<K, V>>.CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<K, V>>)m_innerDictionary).CopyTo(array, arrayIndex);
}
/// <summary>
/// Gets the number of key/value pairs contained in the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
public int Count
{
get { return m_innerDictionary.Count; }
}
/// <summary>
/// Gets a value indicating whether the IDictionary is read-only.
/// </summary>
bool ICollection<KeyValuePair<K, V>>.IsReadOnly
{
get { return ((ICollection<KeyValuePair<K, V>>)m_innerDictionary).IsReadOnly; }
}
/// <summary>
/// Removes a key and value from the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool ICollection<KeyValuePair<K, V>>.Remove(KeyValuePair<K, V> item)
{
OnRemoveValue(item.Key);
return ((ICollection<KeyValuePair<K, V>>)m_innerDictionary).Remove(item);
}
#endregion
#region IEnumerable<KeyValuePair<K,V>> Members
/// <summary>
/// Returns an enumerator that iterates through the <see cref="ForgivingDictionary{K, V}"/>.
/// </summary>
/// <returns></returns>
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
return m_innerDictionary.GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns></returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Protected virtual methods
/// <summary>
/// Called before a value is added.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
protected virtual void OnAddValue(K key, V value)
{
}
/// <summary>
/// Called before a value is set.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
protected virtual void OnSetValue(K key, V value)
{
}
/// <summary>
/// Called before a value is removed.
/// </summary>
/// <param name="key"></param>
protected virtual void OnRemoveValue(K key)
{
}
/// <summary>
/// Called before the dictionary is cleared.
/// </summary>
protected virtual void OnClear()
{
}
#endregion
}
private class AttributeDictionary : ForgivingDictionary<string, string>
{
#region Variables
private readonly NodeDescription m_owner;
#endregion
#region Constructor
internal AttributeDictionary(NodeDescription owner)
{
System.Diagnostics.Debug.Assert(owner != null);
m_owner = owner;
}
#endregion
#region Methods
/// <summary>
/// Overriden.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
protected override void OnAddValue(string key, string value)
{
ThrowIfLoaded();
base.OnAddValue(key, value);
}
/// <summary>
/// Overriden.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
protected override void OnSetValue(string key, string value)
{
ThrowIfLoaded();
base.OnSetValue(key, value);
}
/// <summary>
/// Overriden.
/// </summary>
/// <param name="key"></param>
protected override void OnRemoveValue(string key)
{
ThrowIfLoaded();
base.OnRemoveValue(key);
}
/// <summary>
/// Overriden.
/// </summary>
protected override void OnClear()
{
ThrowIfLoaded();
base.OnClear();
}
private void ThrowIfLoaded()
{
if (m_owner.Addin != null)
{
m_owner.Addin.ThrowIfLoaded();
}
}
#endregion
}
#endregion
#region Variables
private readonly string m_name;
private readonly AttributeDictionary m_attributes;
#endregion
#region Constructor
/// <summary>
/// Constructor.
/// </summary>
/// <param name="name"></param>
internal NodeDescription(string name)
{
Throw.IfEmpty(name, "name");
m_name = name;
m_attributes = new AttributeDictionary(this);
}
#endregion
#region Properties
/// <summary>
/// Name.
/// </summary>
public string Name
{
get
{
return m_name;
}
}
/// <summary>
/// Attributes.
/// </summary>
public IDictionary<string, string> Attributes
{
get
{
return m_attributes;
}
}
#endregion
}
}