|
//---------------------------------------------------------------------
// <copyright file="SchemaElementLookUpTable.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//
// @owner Microsoft
// @backupOwner Microsoft
//---------------------------------------------------------------------
namespace System.Data.EntityModel.SchemaObjectModel
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Metadata.Edm;
using System.Diagnostics;
/// <summary>
/// Summary description for SchemaElementLookUpTable.
/// </summary>
internal sealed class SchemaElementLookUpTable<T> : IEnumerable<T>, ISchemaElementLookUpTable<T>
where T : SchemaElement
{
#region Instance Fields
private Dictionary<string,T> _keyToType = null;
private List<string> _keysInDefOrder = new List<string>();
#endregion
#region Public Methods
/// <summary>
///
/// </summary>
public SchemaElementLookUpTable()
{
}
/// <summary>
///
/// </summary>
public int Count
{
get
{
return KeyToType.Count;
}
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool ContainsKey(string key)
{
return KeyToType.ContainsKey(KeyFromName(key));
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public T LookUpEquivalentKey(string key)
{
key = KeyFromName(key);
T element;
if (KeyToType.TryGetValue(key, out element))
{
return element;
}
return null;
}
/// <summary>
///
/// </summary>
public T this[string key]
{
get
{
return KeyToType[KeyFromName(key)];
}
}
/// <summary>
///
/// </summary>
public T GetElementAt(int index)
{
return KeyToType[_keysInDefOrder[index]];
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerator<T> GetEnumerator()
{
return new SchemaElementLookUpTableEnumerator<T,T>(KeyToType,_keysInDefOrder);
}
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return new SchemaElementLookUpTableEnumerator<T,T>(KeyToType,_keysInDefOrder);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerator<S> GetFilteredEnumerator<S>()
where S : T
{
return new SchemaElementLookUpTableEnumerator<S,T>(KeyToType,_keysInDefOrder);
}
/// <summary>
/// Add the given type to the schema look up table. If there is an error, it
/// adds the error and returns false. otherwise, it adds the type to the lookuptable
/// and returns true
/// </summary>
public AddErrorKind TryAdd(T type)
{
Debug.Assert(type != null, "type parameter is null");
if (String.IsNullOrEmpty(type.Identity))
{
return AddErrorKind.MissingNameError;
}
string key = KeyFromElement(type);
T element;
if (KeyToType.TryGetValue(key, out element))
{
return AddErrorKind.DuplicateNameError;
}
KeyToType.Add(key,type);
_keysInDefOrder.Add(key);
return AddErrorKind.Succeeded;
}
public void Add(T type, bool doNotAddErrorForEmptyName, Func<object, string> duplicateKeyErrorFormat)
{
Debug.Assert(type != null, "type parameter is null");
Debug.Assert(null != duplicateKeyErrorFormat, "duplicateKeyErrorFormat cannot be null");
AddErrorKind error = TryAdd(type);
if (error == AddErrorKind.MissingNameError)
{
if (!doNotAddErrorForEmptyName)
{
type.AddError(ErrorCode.InvalidName, EdmSchemaErrorSeverity.Error,
System.Data.Entity.Strings.MissingName);
}
return;
}
else if (error == AddErrorKind.DuplicateNameError)
{
type.AddError(ErrorCode.AlreadyDefined, EdmSchemaErrorSeverity.Error,
duplicateKeyErrorFormat(type.FQName));
}
else
{
Debug.Assert(error == AddErrorKind.Succeeded, "Invalid error encountered");
}
}
#endregion
#region Internal Methods
#endregion
#region Private Methods
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static string KeyFromElement(T type)
{
return KeyFromName(type.Identity);
}
/// <summary>
///
/// </summary>
/// <param name="unnormalizedKey"></param>
/// <returns></returns>
private static string KeyFromName(string unnormalizedKey)
{
Debug.Assert(!String.IsNullOrEmpty(unnormalizedKey), "unnormalizedKey parameter is null or empty");
return unnormalizedKey;
}
#endregion
#region Private Properties
/// <summary>
///
/// </summary>
private Dictionary<string,T> KeyToType
{
get
{
if ( _keyToType == null )
{
_keyToType = new Dictionary<string,T>(StringComparer.Ordinal);
}
return _keyToType;
}
}
#endregion
}
enum AddErrorKind
{
Succeeded,
MissingNameError,
DuplicateNameError,
}
}
|