Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / EntityModel / SchemaObjectModel / SchemaElementLookUpTable.cs
1 //---------------------------------------------------------------------
2 // <copyright file="SchemaElementLookUpTable.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9
10 namespace System.Data.EntityModel.SchemaObjectModel
11 {
12     using System;
13     using System.Collections;
14     using System.Collections.Generic;
15     using System.Data.Metadata.Edm;
16     using System.Diagnostics;
17
18     /// <summary>
19     /// Summary description for SchemaElementLookUpTable.
20     /// </summary>
21     internal sealed class SchemaElementLookUpTable<T> : IEnumerable<T>, ISchemaElementLookUpTable<T>
22     where T : SchemaElement
23     {
24         #region Instance Fields
25         private Dictionary<string,T> _keyToType = null;
26         private List<string> _keysInDefOrder = new List<string>();
27         #endregion
28
29         #region Public Methods
30         /// <summary>
31         /// 
32         /// </summary>
33         public SchemaElementLookUpTable()
34         {
35         }
36
37         /// <summary>
38         /// 
39         /// </summary>
40         public int Count
41         {
42             get
43             {
44                 return KeyToType.Count;
45             }
46         }
47
48         /// <summary>
49         /// 
50         /// </summary>
51         /// <param name="key"></param>
52         /// <returns></returns>
53         public bool ContainsKey(string key)
54         {
55             return KeyToType.ContainsKey(KeyFromName(key));
56         }
57
58         /// <summary>
59         /// 
60         /// </summary>
61         /// <param name="key"></param>
62         /// <returns></returns>
63         public T LookUpEquivalentKey(string key)
64         {
65             key = KeyFromName(key);
66             T element;
67
68             if (KeyToType.TryGetValue(key, out element))
69             {
70                 return element;
71             }
72
73             return null;
74         }
75         /// <summary>
76         /// 
77         /// </summary>
78         public T this[string key]
79         {
80             get
81             {
82                 return KeyToType[KeyFromName(key)];
83             }
84         }
85
86         /// <summary>
87         /// 
88         /// </summary>
89         public T GetElementAt(int index)
90         {
91                 return KeyToType[_keysInDefOrder[index]];
92         }
93
94         /// <summary>
95         /// 
96         /// </summary>
97         /// <returns></returns>
98         public IEnumerator<T> GetEnumerator()
99         {
100             return new SchemaElementLookUpTableEnumerator<T,T>(KeyToType,_keysInDefOrder);
101         }
102         IEnumerator System.Collections.IEnumerable.GetEnumerator()
103         {
104             return new SchemaElementLookUpTableEnumerator<T,T>(KeyToType,_keysInDefOrder);
105         }
106
107         /// <summary>
108         /// 
109         /// </summary>
110         /// <returns></returns>
111         public IEnumerator<S> GetFilteredEnumerator<S>()
112         where S : T
113         {
114             return new SchemaElementLookUpTableEnumerator<S,T>(KeyToType,_keysInDefOrder);
115         }
116
117         /// <summary>
118         /// Add the given type to the schema look up table. If there is an error, it
119         /// adds the error and returns false. otherwise, it adds the type to the lookuptable
120         /// and returns true
121         /// </summary>
122         public AddErrorKind TryAdd(T type)
123         {
124             Debug.Assert(type != null, "type parameter is null");
125
126             if (String.IsNullOrEmpty(type.Identity))
127             {
128                 return AddErrorKind.MissingNameError;
129             }
130
131             string key = KeyFromElement(type);
132             T element;
133             if (KeyToType.TryGetValue(key, out element))
134             {
135                 return AddErrorKind.DuplicateNameError;
136             }
137
138             KeyToType.Add(key,type);
139             _keysInDefOrder.Add(key);
140
141             return AddErrorKind.Succeeded;
142         }
143
144         public void Add(T type, bool doNotAddErrorForEmptyName, Func<object, string> duplicateKeyErrorFormat)
145         {
146             Debug.Assert(type != null, "type parameter is null");
147             Debug.Assert(null != duplicateKeyErrorFormat, "duplicateKeyErrorFormat cannot be null");
148
149             AddErrorKind error = TryAdd(type);
150
151             if (error == AddErrorKind.MissingNameError)
152             {
153                 if (!doNotAddErrorForEmptyName)
154                 {
155                     type.AddError(ErrorCode.InvalidName, EdmSchemaErrorSeverity.Error,
156                         System.Data.Entity.Strings.MissingName);
157                 }
158                 return;
159             }
160             else if (error == AddErrorKind.DuplicateNameError)
161             {
162                 type.AddError(ErrorCode.AlreadyDefined, EdmSchemaErrorSeverity.Error,
163                         duplicateKeyErrorFormat(type.FQName));
164             }
165             else
166             {
167                 Debug.Assert(error == AddErrorKind.Succeeded, "Invalid error encountered");
168             }
169         }
170
171         #endregion
172
173         #region Internal Methods
174         #endregion
175
176         #region Private Methods
177         /// <summary>
178         /// 
179         /// </summary>
180         /// <param name="type"></param>
181         /// <returns></returns>
182         private static string KeyFromElement(T type)
183         {
184             return KeyFromName(type.Identity);
185         }
186
187         /// <summary>
188         /// 
189         /// </summary>
190         /// <param name="unnormalizedKey"></param>
191         /// <returns></returns>
192         private static string KeyFromName(string unnormalizedKey)
193         {
194             Debug.Assert(!String.IsNullOrEmpty(unnormalizedKey), "unnormalizedKey parameter is null or empty");
195
196             return unnormalizedKey;
197         }
198         #endregion
199
200         #region Private Properties
201         /// <summary>
202         /// 
203         /// </summary>
204         private Dictionary<string,T> KeyToType
205         {
206             get
207             {
208                 if ( _keyToType == null )
209                 {
210                     _keyToType = new Dictionary<string,T>(StringComparer.Ordinal);
211                 }
212                 return _keyToType;
213             }
214         }
215         #endregion
216     }
217
218     enum AddErrorKind
219     {
220         Succeeded,
221
222         MissingNameError,
223
224         DuplicateNameError,
225     }
226 }