// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace ICSharpCode.Core { /// /// Represents an extension path in the . /// public sealed class AddInTreeNode { readonly object lockObj = new object(); Dictionary childNodes = new Dictionary(); ReadOnlyCollection codons; List> codonInput; /// /// A dictionary containing the child paths. /// public Dictionary ChildNodes { get { return childNodes; } } public void AddCodons(IEnumerable newCodons) { if (newCodons == null) throw new ArgumentNullException("newCodons"); lock (lockObj) { if (codonInput == null) { codonInput = new List>(); if (codons != null) codonInput.Add(codons); } codonInput.Add(newCodons); } } /// /// A list of child s. /// public ReadOnlyCollection Codons { get { lock (lockObj) { if (codons == null) { if (codonInput == null) { codons = new ReadOnlyCollection(new Codon[0]); } else { codons = TopologicalSort.Sort(codonInput).AsReadOnly(); codonInput = null; } } return codons; } } } /// /// Builds the child items in this path. Ensures that all items have the type T. /// /// The owner used to create the objects. /// Additional conditions applied to the node. public List BuildChildItems(object caller, IEnumerable additionalConditions = null) { var codons = this.Codons; List items = new List(codons.Count); foreach (Codon codon in codons) { object result = BuildChildItem(codon, caller, additionalConditions); if (result == null) continue; IBuildItemsModifier mod = result as IBuildItemsModifier; if (mod != null) { mod.Apply(items); } else if (result is T) { items.Add((T)result); } else { throw new InvalidCastException("The AddInTreeNode <" + codon.Name + " id='" + codon.Id + "'> returned an instance of " + result.GetType().FullName + " but the type " + typeof(T).FullName + " is expected."); } } return items; } public object BuildChildItem(Codon codon, object caller, IEnumerable additionalConditions = null) { if (codon == null) throw new ArgumentNullException("codon"); AddInTreeNode subItemNode; childNodes.TryGetValue(codon.Id, out subItemNode); IEnumerable conditions; if (additionalConditions == null) conditions = codon.Conditions; else if (codon.Conditions.Length == 0) conditions = additionalConditions; else conditions = additionalConditions.Concat(codon.Conditions); return codon.BuildItem(new BuildItemArgs(caller, codon, conditions, subItemNode)); } /// /// Builds the child items in this path. /// /// The owner used to create the objects. [Obsolete("Use the generic BuildChildItems version instead")] public ArrayList BuildChildItems(object caller) { return new ArrayList(this.BuildChildItems(caller)); } /// /// Builds a specific child items in this path. /// /// /// The ID of the child item to build. /// /// The owner used to create the objects. /// Additional conditions applied to the created object /// /// Occurs when does not exist in this path. /// public object BuildChildItem(string childItemID, object caller, IEnumerable additionalConditions = null) { foreach (Codon codon in this.Codons) { if (codon.Id == childItemID) { return BuildChildItem(codon, caller, additionalConditions); } } throw new TreePathNotFoundException(childItemID); } } }