435 lines
13 KiB
C#
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
|
|
}
|
|
}
|