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