~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections;
 
6
using System.Collections.Generic;
 
7
using System.Collections.ObjectModel;
 
8
using System.Linq;
 
9
 
 
10
namespace ICSharpCode.Core
 
11
{
 
12
        /// <summary>
 
13
        /// Represents an extension path in the <see cref="AddInTree"/>.
 
14
        /// </summary>
 
15
        public sealed class AddInTreeNode
 
16
        {
 
17
                readonly object lockObj = new object();
 
18
                Dictionary<string, AddInTreeNode> childNodes = new Dictionary<string, AddInTreeNode>();
 
19
                ReadOnlyCollection<Codon> codons;
 
20
                List<IEnumerable<Codon>> codonInput;
 
21
                
 
22
                /// <summary>
 
23
                /// A dictionary containing the child paths.
 
24
                /// </summary>
 
25
                public Dictionary<string, AddInTreeNode> ChildNodes {
 
26
                        get {
 
27
                                return childNodes;
 
28
                        }
 
29
                }
 
30
                
 
31
                public void AddCodons(IEnumerable<Codon> newCodons)
 
32
                {
 
33
                        if (newCodons == null)
 
34
                                throw new ArgumentNullException("newCodons");
 
35
                        lock (lockObj) {
 
36
                                if (codonInput == null) {
 
37
                                        codonInput = new List<IEnumerable<Codon>>();
 
38
                                        if (codons != null)
 
39
                                                codonInput.Add(codons);
 
40
                                }
 
41
                                codonInput.Add(newCodons);
 
42
                        }
 
43
                }
 
44
                
 
45
                /// <summary>
 
46
                /// A list of child <see cref="Codon"/>s.
 
47
                /// </summary>
 
48
                public ReadOnlyCollection<Codon> Codons {
 
49
                        get {
 
50
                                lock (lockObj) {
 
51
                                        if (codons == null) {
 
52
                                                if (codonInput == null) {
 
53
                                                        codons = new ReadOnlyCollection<Codon>(new Codon[0]);
 
54
                                                } else {
 
55
                                                        codons = TopologicalSort.Sort(codonInput).AsReadOnly();
 
56
                                                        codonInput = null;
 
57
                                                }
 
58
                                        }
 
59
                                        return codons;
 
60
                                }
 
61
                        }
 
62
                }
 
63
                
 
64
                /// <summary>
 
65
                /// Builds the child items in this path. Ensures that all items have the type T.
 
66
                /// </summary>
 
67
                /// <param name="caller">The owner used to create the objects.</param>
 
68
                /// <param name="additionalConditions">Additional conditions applied to the node.</param>
 
69
                public List<T> BuildChildItems<T>(object caller, IEnumerable<ICondition> additionalConditions = null)
 
70
                {
 
71
                        var codons = this.Codons;
 
72
                        List<T> items = new List<T>(codons.Count);
 
73
                        foreach (Codon codon in codons) {
 
74
                                object result = BuildChildItem(codon, caller, additionalConditions);
 
75
                                if (result == null)
 
76
                                        continue;
 
77
                                IBuildItemsModifier mod = result as IBuildItemsModifier;
 
78
                                if (mod != null) {
 
79
                                        mod.Apply(items);
 
80
                                } else if (result is T) {
 
81
                                        items.Add((T)result);
 
82
                                } else {
 
83
                                        throw new InvalidCastException("The AddInTreeNode <" + codon.Name + " id='" + codon.Id
 
84
                                                                       + "'> returned an instance of " + result.GetType().FullName
 
85
                                                                       + " but the type " + typeof(T).FullName + " is expected.");
 
86
                                }
 
87
                        }
 
88
                        return items;
 
89
                }
 
90
                
 
91
                public object BuildChildItem(Codon codon, object caller, IEnumerable<ICondition> additionalConditions = null)
 
92
                {
 
93
                        if (codon == null)
 
94
                                throw new ArgumentNullException("codon");
 
95
                        
 
96
                        AddInTreeNode subItemNode;
 
97
                        childNodes.TryGetValue(codon.Id, out subItemNode);
 
98
                        
 
99
                        IEnumerable<ICondition> conditions;
 
100
                        if (additionalConditions == null)
 
101
                                conditions = codon.Conditions;
 
102
                        else if (codon.Conditions.Length == 0)
 
103
                                conditions = additionalConditions;
 
104
                        else
 
105
                                conditions = additionalConditions.Concat(codon.Conditions);
 
106
                        
 
107
                        return codon.BuildItem(new BuildItemArgs(caller, codon, conditions, subItemNode));
 
108
                }
 
109
                
 
110
                /// <summary>
 
111
                /// Builds the child items in this path.
 
112
                /// </summary>
 
113
                /// <param name="caller">The owner used to create the objects.</param>
 
114
                [Obsolete("Use the generic BuildChildItems version instead")]
 
115
                public ArrayList BuildChildItems(object caller)
 
116
                {
 
117
                        return new ArrayList(this.BuildChildItems<object>(caller));
 
118
                }
 
119
                
 
120
                /// <summary>
 
121
                /// Builds a specific child items in this path.
 
122
                /// </summary>
 
123
                /// <param name="childItemID">
 
124
                /// The ID of the child item to build.
 
125
                /// </param>
 
126
                /// <param name="caller">The owner used to create the objects.</param>
 
127
                /// <param name="additionalConditions">Additional conditions applied to the created object</param>
 
128
                /// <exception cref="TreePathNotFoundException">
 
129
                /// Occurs when <paramref name="childItemID"/> does not exist in this path.
 
130
                /// </exception>
 
131
                public object BuildChildItem(string childItemID, object caller, IEnumerable<ICondition> additionalConditions = null)
 
132
                {
 
133
                        foreach (Codon codon in this.Codons) {
 
134
                                if (codon.Id == childItemID) {
 
135
                                        return BuildChildItem(codon, caller, additionalConditions);
 
136
                                }
 
137
                        }
 
138
                        throw new TreePathNotFoundException(childItemID);
 
139
                }
 
140
        }
 
141
}