GenericFlowSwitchHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Core.Presentation / System / Activities / Core / Presentation / GenericFlowSwitchHelper.cs / 1305376 / GenericFlowSwitchHelper.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Activities.Core.Presentation 
{
    using System.Activities.Presentation; 
    using System.Activities.Presentation.Model; 
    using System.Activities.Statements;
    using System.Collections.Generic; 
    using System.Reflection;
    using System.ComponentModel;
    using System.Runtime;
    using System.Globalization; 

    static class GenericFlowSwitchHelper 
    { 
        static readonly MethodInfo genericCopy = typeof(GenericFlowSwitchHelper).GetMethod("GenericCopy");
        static readonly MethodInfo genericCreateGenericFlowSwitchLink = typeof(GenericFlowSwitchHelper).GetMethod("CreateGenericFlowSwitchLink"); 
        static readonly MethodInfo genericGetCaseName = typeof(GenericFlowSwitchHelper).GetMethod("GenericGetCaseName");
        const string flowSwitchCasesKeyIdentifier = "key";
        const string flowSwitchNullCaseKeyIdentifier = "(null)";
        const string flowSwitchEmptyCaseKeyIdentifier = "(empty)"; 

        public static string FlowSwitchCasesKeyIdentifier 
        { 
            get
            { 
                return flowSwitchCasesKeyIdentifier;
            }
        }
 
        public static string FlowSwitchNullCaseKeyIdentifier
        { 
            get 
            {
                return flowSwitchNullCaseKeyIdentifier; 
            }
        }

        public static string FlowSwitchEmptyCaseKeyIdentifier 
        {
            get 
            { 
                return flowSwitchEmptyCaseKeyIdentifier;
            } 
        }

        public static void Copy(Type genericType, FlowNode currentFlowElement, Dictionary clonedFlowElements)
        { 
            MethodInfo copy = genericCopy.MakeGenericMethod(new Type[] { genericType });
            copy.Invoke(null, new object[] { currentFlowElement, clonedFlowElements }); 
        } 

        public static void GenericCopy(FlowNode currentFlowElement, Dictionary clonedFlowElements) 
        {
            FlowSwitch currentFlowSwitch = (FlowSwitch)currentFlowElement;
            FlowSwitch clonedFlowSwitch = (FlowSwitch)clonedFlowElements[currentFlowElement];
 
            //Update the default case.
            FlowNode defaultCase = currentFlowSwitch.Default; 
            if (defaultCase != null && clonedFlowElements.ContainsKey(defaultCase)) 
            {
                clonedFlowSwitch.Default = clonedFlowElements[defaultCase]; 
            }
            else
            {
                clonedFlowSwitch.Default = null; 
            }
 
            //Update the Cases dictionary. 
            foreach (T key in currentFlowSwitch.Cases.Keys)
            { 
                if (clonedFlowElements.ContainsKey(currentFlowSwitch.Cases[key]))
                {
                    clonedFlowSwitch.Cases.Add(key, clonedFlowElements[currentFlowSwitch.Cases[key]]);
                } 
            }
        } 
 
        public static bool IsGenericFlowSwitch(Type type)
        { 
            return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(FlowSwitch<>);
        }

        public static IFlowSwitchLink CreateFlowSwitchLink(Type flowSwitchType, ModelItem currentMI, object caseValue, bool isDefault) 
        {
            Type genericType = null; 
            object key = null; 
            genericType = flowSwitchType.GetGenericArguments()[0];
            if (caseValue is string) 
            {
                key = GetObject(caseValue as string, genericType);
            }
            else 
            {
                key = caseValue; 
            } 
            MethodInfo method = genericCreateGenericFlowSwitchLink.MakeGenericMethod(genericType);
            return method.Invoke(null, new object[] { currentMI, key, isDefault }) as IFlowSwitchLink; 
        }

        public static IFlowSwitchLink CreateGenericFlowSwitchLink(ModelItem currentMI, T caseValue, bool isDefault)
        { 
            FlowSwitchLink link = new FlowSwitchLink(currentMI, caseValue, isDefault);
 
            return link; 
        }
 
        public static string GetCaseName(ModelProperty casesProperties, Type type, out string errorMessage)
        {
            object casesDict = casesProperties.Dictionary.GetCurrentValue();
            ModelItemCollection collection = casesProperties.Value.Properties["ItemsCollection"].Collection; 
            MethodInfo method = genericGetCaseName.MakeGenericMethod(type);
            object[] parameters = new object[] { collection, null }; 
            string result = (string)method.Invoke(null, parameters); 
            errorMessage = (string)parameters[1];
            return result; 
        }

        public static string GenericGetCaseName(ModelItemCollection collection, out string errorMessage)
        { 
            int maxName = 100000;
            Type type = typeof(T); 
            errorMessage = string.Empty; 
            if (typeof(string).IsAssignableFrom(type))
            { 
                string caseName = "caseN";
                for (int i = 1; i <= maxName; i++)
                {
                    caseName = string.Format(CultureInfo.InvariantCulture, SR.CaseFormat, i); 
                    if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, caseName))
                    { 
                        break; 
                    }
                } 
                return caseName;
            }
            else if (GenericFlowSwitchHelper.IsIntegralType(type))
            { 
                if (type == typeof(sbyte))
                { 
                    sbyte maxCount = (sbyte.MaxValue < maxName) ? sbyte.MaxValue : (sbyte)maxName; 
                    for (sbyte i = 0; i <= maxCount; i++)
                    { 
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i))
                        {
                            return GenericFlowSwitchHelper.GetString(i, type);
                        } 
                    }
                } 
                else if (type == typeof(byte)) 
                {
                    byte maxCount = (byte.MaxValue < maxName) ? byte.MaxValue : (byte)maxName; 
                    for (byte i = 0; i <= maxCount; i++)
                    {
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i))
                        { 
                            return GenericFlowSwitchHelper.GetString(i, type);
                        } 
                    } 
                }
                else if (type == typeof(char)) 
                {
                    char maxCount = unchecked((char)maxName);
                    for (char i = (char)48; i <= maxCount; i++)
                    { 
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i))
                        { 
                            return GenericFlowSwitchHelper.GetString(i, type); 
                        }
                    } 
                }
                else if (type == typeof(short))
                {
                    short maxCount = (short)maxName; 
                    for (short i = 0; i <= maxCount; i++)
                    { 
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) 
                        {
                            return GenericFlowSwitchHelper.GetString(i, type); 
                        }
                    }
                }
                else if (type == typeof(ushort)) 
                {
                    ushort maxCount = (ushort)maxName; 
                    for (ushort i = 0; i <= maxCount; i++) 
                    {
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) 
                        {
                            return GenericFlowSwitchHelper.GetString(i, type);
                        }
                    } 
                }
                else if (type == typeof(int)) 
                { 
                    for (int i = 0; i <= maxName; i++)
                    { 
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i))
                        {
                            return GenericFlowSwitchHelper.GetString(i, type);
                        } 
                    }
                } 
                else if (type == typeof(uint)) 
                {
                    for (uint i = 0; i <= (uint)maxName; i++) 
                    {
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i))
                        {
                            return GenericFlowSwitchHelper.GetString(i, type); 
                        }
                    } 
                } 
                else if (type == typeof(long))
                { 
                    for (long i = 0; i <= (long)maxName; i++)
                    {
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i))
                        { 
                            return GenericFlowSwitchHelper.GetString(i, type);
                        } 
                    } 
                }
                else if (type == typeof(ulong)) 
                {
                    for (ulong i = 0; i <= (ulong)maxName; i++)
                    {
                        if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) 
                        {
                            return GenericFlowSwitchHelper.GetString(i, type); 
                        } 
                    }
                } 
                errorMessage = SR.InvalidFlowSwitchCaseMessage;
                return string.Empty;
            }
            else if (type.IsEnum) 
            {
                Array array = type.GetEnumValues(); 
                foreach (object value in array) 
                {
                    if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, value)) 
                    {
                        return GenericFlowSwitchHelper.GetString(value, type);
                    }
                } 
                errorMessage = SR.InvalidFlowSwitchCaseMessage;
                return string.Empty; 
            } 
            else if (type == typeof(bool))
            { 
                if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, true))
                {
                    return GenericFlowSwitchHelper.GetString(true, type);
                } 
                else if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, false))
                { 
                    return GenericFlowSwitchHelper.GetString(false, type); 
                }
                errorMessage = SR.InvalidFlowSwitchCaseMessage; 
                return string.Empty;
            }
            return string.Empty;
        } 

        public static bool IsIntegralType(Type type) 
        { 
            if (type == typeof(sbyte) || type == typeof(byte) || type == typeof(char) || type == typeof(short) ||
                type == typeof(ushort) || type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong)) 
            {
                return true;
            }
            else 
            {
                return false; 
            } 
        }
 
        public static string GetString(object key, Type type)
        {
            string result = null;
            if (key == null && !type.IsValueType) 
            {
                result = FlowSwitchNullCaseKeyIdentifier; 
            } 
            else
            { 
                Fx.Assert(key != null, "Value type should not have null value");
                result = GetRawString(key);
                if (result == string.Empty && typeof(string).IsAssignableFrom(type))
                { 
                    result = FlowSwitchEmptyCaseKeyIdentifier;
                } 
            } 
            return result;
        } 

        //Raw string means the null is not represented as "" and string.Empty is not represented as "".
        static string GetRawString(object caseObject)
        { 
            string result = null;
 
            if (caseObject == null) 
            {
                return null; 
            }
            if (!(caseObject is string))
            {
                result = XamlUtilities.GetConverter(caseObject.GetType()).ConvertToString(caseObject); 
            }
            else 
            { 
                result = (string)caseObject;
            } 
            return result;
        }

        public static object GetObject(string caseString, Type genericType) 
        {
            object result; 
            if (!genericType.IsValueType && caseString == FlowSwitchNullCaseKeyIdentifier) 
            {
                result = null; 
            }
            else if (typeof(string).IsAssignableFrom(genericType))
            {
                if (caseString == FlowSwitchEmptyCaseKeyIdentifier) 
                {
                    result = string.Empty; 
                } 
                else
                { 
                    result = caseString;
                }
            }
            else 
            {
                //If target type is value type and the caseString is null, we should leave converter to process it. 
                //If target type is reference type, the caseString is a non-null value here. 
                result = XamlUtilities.GetConverter(genericType).ConvertFromString(caseString);
            } 
            return result;
        }

        public static bool ContainsCaseKey(ModelProperty casesProp, object key) 
        {
            ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; 
            return ContainsCaseKey(itemsCollection, key); 
        }
 
        static bool ContainsCaseKey(ModelItemCollection itemsCollection, object key)
        {
            if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(key))
            { 
                key = null;
            } 
 
            foreach (ModelItem item in itemsCollection)
            { 
                object value = item.Properties["Key"].ComputedValue;
                if (value == key || ((value != null) && item.Properties["Key"].ComputedValue.Equals(key)))
                {
                    return true; 
                }
            } 
            return false; 
        }
 
        public static ModelItem GetCaseModelItem(ModelProperty casesProp, object key)
        {
            ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection;
            return GenericFlowSwitchHelper.GetCaseModelItem(itemsCollection, key); 
        }
 
        static ModelItem GetCaseModelItem(ModelItemCollection itemsCollection, object key) 
        {
            if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(key)) 
            {
                key = null;
            }
 
            foreach (ModelItem item in itemsCollection)
            { 
                object value = item.Properties["Key"].ComputedValue; 
                if (value == key || (value != null && item.Properties["Key"].ComputedValue.Equals(key)))
                { 
                    return item.Properties["Value"].Value;
                }
            }
            string caseName = GetString(key, itemsCollection.ItemType); 
            throw FxTrace.Exception.AsError(new KeyNotFoundException(caseName));
        } 
 
        public static object GetCase(ModelItemCollection itemsCollection, object key)
        { 
            return GenericFlowSwitchHelper.GetCaseModelItem(itemsCollection, key).GetCurrentValue();
        }

        public static ModelItem[] GetCaseKeys(ModelProperty casesProp) 
        {
            ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; 
            ModelItem[] keys = new ModelItem[itemsCollection.Count]; 
            for (int i = 0; i < itemsCollection.Count; i++)
            { 
                keys[i] = (ModelItem) itemsCollection[i].Properties["Key"].Value;
            }
            return keys;
        } 

        public static void RemoveCase(ModelProperty casesProp, object key) 
        { 
            ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection;
 
            if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(key))
            {
                key = null;
            } 
            foreach (ModelItem item in itemsCollection)
            { 
                object value = item.Properties["Key"].ComputedValue; 
                if (value == key || (value != null && item.Properties["Key"].ComputedValue.Equals(key)))
                { 
                    itemsCollection.Remove(item);
                    return;
                }
 
            }
            string caseName = GetString(key, itemsCollection.ItemType.GetGenericArguments()[0]); 
            throw FxTrace.Exception.AsError(new KeyNotFoundException(caseName)); 
        }
 
        public static void AddCase(ModelProperty casesPropperties, object newKey, object newCase)
        {
            Type propertyType = casesPropperties.PropertyType;
            Fx.Assert(propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(IDictionary<,>), "Property type should be IDictonary"); 
            Type keyType = propertyType.GetGenericArguments()[0];
            ModelItemCollection itemsCollection = casesPropperties.Value.Properties["ItemsCollection"].Collection; 
 
            Type caseType = typeof(ModelItemKeyValuePair<,>).MakeGenericType(new Type[] { keyType, typeof(FlowNode) });
            object mutableKVPair = Activator.CreateInstance(caseType, new object[] { newKey, newCase }); 
            itemsCollection.Add(mutableKVPair);
        }

        public static bool CanBeGeneratedUniquely(Type typeArgument) 
        {
            return typeArgument.IsEnum || typeof(string).IsAssignableFrom(typeArgument) 
                || GenericFlowSwitchHelper.IsIntegralType(typeArgument) || typeof(bool) == typeArgument; 
        }
 
        public static bool CheckEquality(object value, Type targetType)
        {
            if (value == null)
            { 
                return true;
            } 
            else 
            {
                string stringValue = GetString(value, targetType); 
                object newValue = GetObject(stringValue, targetType);
                return value.GetHashCode() == newValue.GetHashCode() && value.Equals(newValue);
            }
        } 

        public static bool ValidateCaseKey(object obj, ModelProperty casesProp, Type genericType, out string reason) 
        { 
            reason = string.Empty;
            string key = GenericFlowSwitchHelper.GetString(obj, genericType); 
            if (GenericFlowSwitchHelper.CheckEquality(obj, genericType))
            {
                if (GenericFlowSwitchHelper.ContainsCaseKey(casesProp, obj))
                { 
                    reason = string.Format(CultureInfo.CurrentCulture, SR.DuplicateCaseKey, key);
                    return false; 
                } 
                return true;
            } 
            else
            {
                reason = string.Format(CultureInfo.CurrentUICulture, SR.EqualityError, genericType.Name);
                return false; 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK