ValidationHelper.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 / System.Activities / System / Activities / Validation / ValidationHelper.cs / 1305376 / ValidationHelper.cs

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

namespace System.Activities.Validation 
{
    using System; 
    using System.Activities; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Linq;
    using System.Runtime;
    using System.Globalization;
 
    static class ValidationHelper
    { 
        public static void ValidateArguments(Activity activity, OverloadGroupEquivalenceInfo equivalenceInfo, Dictionary> overloadGroups, List requiredArgumentsNotInOverloadGroups, IDictionary inputs, ref IList validationErrors) 
        {
            if (!requiredArgumentsNotInOverloadGroups.IsNullOrEmpty()) 
            {
                // 1. Check if there are any Required arguments (outside overload groups) that were not specified.
                foreach (RuntimeArgument argument in requiredArgumentsNotInOverloadGroups)
                { 
                    if (CheckIfArgumentIsNotBound(argument, inputs))
                    { 
                        ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.RequiredArgumentValueNotSupplied(argument.Name), false, argument.Name, activity)); 
                    }
                } 
            }

            if (!overloadGroups.IsNullOrEmpty())
            { 
                //1. Check to see if any of the overload groups are configured.
                // An overload group is considered to be completely configured if all it's required arguments 
                // are non-null. If an overload group does not have any required arguments then the group is 
                // considered configured if any of the optional arguments are configured.
                Dictionary configurationResults = new Dictionary(); 
                string configuredGroupName = string.Empty;
                int configuredCount = 0;
                int overloadGroupsWithNoRequiredArgs = 0;
 
                foreach (KeyValuePair> entry in overloadGroups)
                { 
                    string groupName = entry.Key; 
                    configurationResults.Add(groupName, false);
                    IEnumerable requiredArguments = entry.Value.Where((a) => a.IsRequired); 

                    if (requiredArguments.Count() > 0)
                    {
                        if (requiredArguments.All(localArgument => CheckIfArgumentIsBound(localArgument, inputs))) 
                        {
                            configurationResults[groupName] = true; 
                            configuredGroupName = groupName; 
                            configuredCount++;
                        } 
                    }
                    else
                    {
                        overloadGroupsWithNoRequiredArgs++; 
                        IEnumerable optionalArguments = entry.Value.Where((a) => !a.IsRequired);
                        if (optionalArguments.Any(localArgument => CheckIfArgumentIsBound(localArgument, inputs))) 
                        { 
                            configurationResults[groupName] = true;
                            configuredGroupName = groupName; 
                            configuredCount++;
                        }
                    }
                } 

                //2. It's an error if none of the groups are configured unless there 
                // is atleast one overload group with no required arguments in it. 
                if (configuredCount == 0)
                { 
                    if (overloadGroupsWithNoRequiredArgs == 0)
                    {
                        ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.NoOverloadGroupsAreConfigured, false, activity));
                    } 
                }
                //3. If only one overload group was configured, ensure none of the disjoint/overlapping groups have any 
                // required or optional activity arguments set. 
                else if (configuredCount == 1)
                { 
                    HashSet configuredOverloadSet = new HashSet(overloadGroups[configuredGroupName]);
                    Predicate checkIfArgumentIsBound = new Predicate(localArgument => CheckIfArgumentIsBound(localArgument, inputs));

                    List disjointGroups = null; 
                    if (!equivalenceInfo.DisjointGroupsDictionary.IsNullOrEmpty())
                    { 
                        equivalenceInfo.DisjointGroupsDictionary.TryGetValue(configuredGroupName, out disjointGroups); 
                    }
 
                    List overlappingGroups = null;
                    if (!equivalenceInfo.OverlappingGroupsDictionary.IsNullOrEmpty())
                    {
                        equivalenceInfo.OverlappingGroupsDictionary.TryGetValue(configuredGroupName, out overlappingGroups); 
                    }
 
                    // Iterate over the groups that may not be completely configured. 
                    foreach (string groupName in configurationResults.Keys.Where((k) => configurationResults[k] == false))
                    { 
                        // Check if the partially configured group name is in the disjoint groups list.
                        // If so, find all configured arguments.
                        if (disjointGroups != null && disjointGroups.Contains(groupName))
                        { 
                            foreach (RuntimeArgument configuredArgument in overloadGroups[groupName].FindAll(checkIfArgumentIsBound))
                            { 
                                ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ExtraOverloadGroupPropertiesConfigured(configuredGroupName, 
                                    configuredArgument.Name, groupName), false, activity));
                            } 
                        }
                        else if (overlappingGroups != null && overlappingGroups.Contains(groupName))
                        {
                            // Find all arguments of the Overlapping group that are not in the configuredOverloadSet. 
                            HashSet overloadGroupSet = new HashSet(overloadGroups[groupName]);
                            IEnumerable intersectSet = overloadGroupSet.Intersect(configuredOverloadSet); 
                            List exceptList = overloadGroupSet.Except(intersectSet).ToList(); 

                            foreach (RuntimeArgument configuredArgument in exceptList.FindAll(checkIfArgumentIsBound)) 
                            {
                                ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ExtraOverloadGroupPropertiesConfigured(configuredGroupName,
                                    configuredArgument.Name, groupName), false, activity));
                            } 
                        }
                    } 
                } 
                //4. If more than one overload group is configured, generate an error.
                else 
                {
                    IEnumerable configuredGroups = configurationResults.Keys.Where((k) => configurationResults[k]).OrderBy((k) => k, StringComparer.Ordinal);
                    ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.MultipleOverloadGroupsConfigured(configuredGroups.AsCommaSeparatedValues()), false, activity));
                } 
            }
        } 
 
        public static bool GatherAndValidateOverloads(Activity activity, out Dictionary> overloadGroups, out List requiredArgumentsNotInOverloadGroups, out OverloadGroupEquivalenceInfo equivalenceInfo, ref IList validationErrors)
        { 
            overloadGroups = null;
            requiredArgumentsNotInOverloadGroups = null;
            IEnumerable runtimeArguments = activity.RuntimeArguments;
 
            foreach (RuntimeArgument runtimeArgument in runtimeArguments)
            { 
                if (!runtimeArgument.OverloadGroupNames.IsNullOrEmpty()) 
                {
                    foreach (string groupName in runtimeArgument.OverloadGroupNames) 
                    {
                        if (overloadGroups == null)
                        {
                            overloadGroups = new Dictionary>(); 
                        }
 
                        List arguments = null; 
                        if (!overloadGroups.TryGetValue(groupName, out arguments))
                        { 
                            arguments = new List();
                            overloadGroups.Add(groupName, arguments);
                        }
                        arguments.Add(runtimeArgument); 
                    }
                } 
                else 
                {
                    if (runtimeArgument.IsRequired) 
                    {
                        if (requiredArgumentsNotInOverloadGroups == null)
                        {
                            requiredArgumentsNotInOverloadGroups = new List(); 
                        }
                        requiredArgumentsNotInOverloadGroups.Add(runtimeArgument); 
                    } 
                }
            } 

            equivalenceInfo = GetOverloadGroupEquivalence(overloadGroups);

            return ValidateOverloadGroupDefinitions(activity, equivalenceInfo, overloadGroups, ref validationErrors); 
        }
 
 
        // This method checks if any of the overload groups are equivalent and/or are a subset/superset of another
        // overload group.  Returns true if there are not any errors. 
        static bool ValidateOverloadGroupDefinitions(Activity activity, OverloadGroupEquivalenceInfo equivalenceInfo, Dictionary> overloadGroups, ref IList validationErrors)
        {
            Fx.Assert(equivalenceInfo != null, "equivalenceInfo should have been setup before calling this method");
 
            bool noErrors = true;
 
            if (!equivalenceInfo.EquivalentGroupsDictionary.IsNullOrEmpty()) 
            {
                Hashtable keysVisited = new Hashtable(equivalenceInfo.EquivalentGroupsDictionary.Count); 
                foreach (KeyValuePair> entry in equivalenceInfo.EquivalentGroupsDictionary)
                {
                    if (!keysVisited.Contains(entry.Key))
                    { 
                        string[] equivalentGroups = new string[entry.Value.Count + 1];
                        equivalentGroups[0] = entry.Key; 
                        entry.Value.CopyTo(equivalentGroups, 1); 

                        IEnumerable sortedList = equivalentGroups.OrderBy((s) => s, StringComparer.Ordinal); 
                        ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.OverloadGroupsAreEquivalent(sortedList.AsCommaSeparatedValues()), false, activity));
                        noErrors = false;

                        for (int i = 0; i < equivalentGroups.Length; i++) 
                        {
                            keysVisited.Add(equivalentGroups[i], null); 
                        } 
                    }
                } 
            }
            else if (!equivalenceInfo.SupersetOfGroupsDictionary.IsNullOrEmpty())
            {
                foreach (KeyValuePair> entry in equivalenceInfo.SupersetOfGroupsDictionary) 
                {
                    IList sortedList = entry.Value.OrderBy((s) => s, StringComparer.Ordinal).ToList(); 
                    string[] subsetGroups = new string[sortedList.Count]; 
                    int index = 0;
 
                    // Select only subsets that have atleast one required argument in them.
                    // We ignore the subsets that have no required arguments in them.
                    foreach (string subsetGroup in sortedList)
                    { 
                        if (overloadGroups[subsetGroup].Any((a) => a.IsRequired))
                        { 
                            subsetGroups[index++] = subsetGroup; 
                        }
                    } 

                    // If there were any subsets with required arguments generate an error.
                    if (index > 0)
                    { 
                        ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.OverloadGroupHasSubsets(entry.Key, subsetGroups.AsCommaSeparatedValues()), false, activity));
                        noErrors = false; 
                    } 
                }
            } 

            return noErrors;
        }
 
        static OverloadGroupEquivalenceInfo GetOverloadGroupEquivalence(Dictionary> groupDefinitions)
        { 
            OverloadGroupEquivalenceInfo overloadGroupsInfo = new OverloadGroupEquivalenceInfo(); 

            if (!groupDefinitions.IsNullOrEmpty()) 
            {
                string[] groupNames = new string[groupDefinitions.Count];
                groupDefinitions.Keys.CopyTo(groupNames, 0);
 
                for (int i = 0; i < groupNames.Length; i++)
                { 
                    string group1 = groupNames[i]; 
                    HashSet group1Args = new HashSet(groupDefinitions[group1]);
                    for (int j = i + 1; j < groupNames.Length; j++) 
                    {
                        string group2 = groupNames[j];
                        HashSet group2Args = new HashSet(groupDefinitions[group2]);
 
                        if (group1Args.IsProperSupersetOf(group2Args))
                        { 
                            overloadGroupsInfo.SetAsSuperset(group1, group2); 
                        }
                        else if (group1Args.IsProperSubsetOf(group2Args)) 
                        {
                            overloadGroupsInfo.SetAsSuperset(group2, group1);
                        }
                        else if (group1Args.SetEquals(group2Args)) 
                        {
                            overloadGroupsInfo.SetAsEquivalent(group1, group2); 
                        } 
                        else if (group1Args.Overlaps(group2Args))
                        { 
                            overloadGroupsInfo.SetAsOverlapping(group1, group2);
                        }
                        else // the groups are disjoint.
                        { 
                            overloadGroupsInfo.SetAsDisjoint(group1, group2);
                        } 
                    } 
                }
            } 

            return overloadGroupsInfo;
        }
 
        static bool CheckIfArgumentIsNotBound(RuntimeArgument argument, IDictionary inputs)
        { 
            if (argument.Owner != null && argument.Owner.Parent == null && ArgumentDirectionHelper.IsOut(argument.Direction)) 
            {
                // Skip the validation for root node's out argument 
                // as it will be added to the output dictionary
                return false;
            }
 
            if (argument.BoundArgument != null && argument.BoundArgument.Expression != null)
            { 
                return false; 
            }
            if (inputs != null) 
            {
                if(inputs.ContainsKey(argument.Name))
                {
                    return false; 
                }
            } 
            return true; 
        }
 
        static bool CheckIfArgumentIsBound(RuntimeArgument argument, IDictionary inputs)
        {
            return !(CheckIfArgumentIsNotBound(argument, inputs));
        } 

        public class OverloadGroupEquivalenceInfo 
        { 
            Dictionary> equivalentGroupsDictionary;
            Dictionary> supersetOfGroupsDictionary; 
            Dictionary> overlappingGroupsDictionary;
            Dictionary> disjointGroupsDictionary;

            public OverloadGroupEquivalenceInfo() 
            {
            } 
 
            public Dictionary> EquivalentGroupsDictionary
            { 
                get
                {
                    return this.equivalentGroupsDictionary;
                } 
            }
 
            public Dictionary> SupersetOfGroupsDictionary 
            {
                get 
                {
                    return this.supersetOfGroupsDictionary;
                }
            } 

            public Dictionary> OverlappingGroupsDictionary 
            { 
                get
                { 
                    return this.overlappingGroupsDictionary;
                }
            }
 
            public Dictionary> DisjointGroupsDictionary
            { 
                get 
                {
                    return this.disjointGroupsDictionary; 
                }
            }

            public void SetAsEquivalent(string group1, string group2) 
            {
                // Setup EquivalentGroups for group1 
                this.AddToDictionary(ref this.equivalentGroupsDictionary, group1, group2); 

                // Setup EquivalentGroups for group2 
                this.AddToDictionary(ref this.equivalentGroupsDictionary, group2, group1);
            }

            public void SetAsSuperset(string group1, string group2) 
            {
                this.AddToDictionary(ref this.supersetOfGroupsDictionary, group1, group2); 
            } 

            public void SetAsOverlapping(string group1, string group2) 
            {
                // Setup OverlapGroups for group1
                this.AddToDictionary(ref this.overlappingGroupsDictionary, group1, group2);
 
                // Setup OverlapGroups for group2
                this.AddToDictionary(ref this.overlappingGroupsDictionary, group2, group1); 
            } 

            public void SetAsDisjoint(string group1, string group2) 
            {
                // Setup DisjointGroups for group1
                this.AddToDictionary(ref this.disjointGroupsDictionary, group1, group2);
 
                // Setup DisjointGroups for group2
                this.AddToDictionary(ref this.disjointGroupsDictionary, group2, group1); 
            } 

            void AddToDictionary(ref Dictionary> dictionary, string dictionaryKey, string listEntry) 
            {
                if (dictionary == null)
                {
                    dictionary = new Dictionary>(); 
                }
 
                List listValues = null; 
                if (!dictionary.TryGetValue(dictionaryKey, out listValues))
                { 
                    listValues = new List { listEntry };
                    dictionary.Add(dictionaryKey, listValues);
                }
                else 
                {
                    Fx.Assert(!listValues.Contains(listEntry), string.Format(CultureInfo.InvariantCulture, "Duplicate group entry '{0}' getting added.", listEntry)); 
                    listValues.Add(listEntry); 
                }
            } 
        }
    }
}

// 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