EdmValidator.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 / fx / src / DataEntity / System / Data / Metadata / EdmValidator.cs / 1305376 / EdmValidator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common; 
using System.Diagnostics;
using System.Globalization; 
using System.Text; 

namespace System.Data.Metadata.Edm 
{
    /// 
    /// The validation severity level
    ///  
    internal enum ValidationSeverity
    { 
        ///  
        /// Warning
        ///  
        Warning,

        /// 
        /// Error 
        /// 
        Error, 
 
        /// 
        /// Internal 
        /// 
        Internal
    }
 
    /// 
    /// Class representing a validtion error event args 
    ///  
    internal class ValidationErrorEventArgs : EventArgs
    { 
        private EdmItemError _validationError;

        /// 
        /// Construct the validation error event args with a validation error object 
        /// 
        /// The validation error object for this event args 
        public ValidationErrorEventArgs(EdmItemError validationError) 
        {
            _validationError = validationError; 
        }

        /// 
        /// Gets the validation error object this event args 
        /// 
        public EdmItemError ValidationError 
        { 
            get
            { 
                return _validationError;
            }
        }
    } 

    ///  
    /// Class for representing the validator 
    /// 
    internal class EdmValidator 
    {
        private bool _skipReadOnlyItems;

        ///  
        /// Gets or Sets whether the validator should skip readonly items
        ///  
        internal bool SkipReadOnlyItems 
        {
            get 
            {
                return _skipReadOnlyItems;
            }
            set 
            {
                _skipReadOnlyItems = value; 
            } 
        }
 
        /// 
        /// Validate a collection of items in a batch
        /// 
        /// A collection of items to validate 
        /// List of validation errors that were previously collected by the caller. if it encounters
        /// more errors, it adds them to this list of errors 
        public void Validate(IEnumerable items, List ospaceErrors) 
            where T : EdmType // O-Space only supports EdmType
        { 
            EntityUtil.CheckArgumentNull(items, "items");
            EntityUtil.CheckArgumentNull(items, "ospaceErrors");

            HashSet validatedItems = new HashSet(); 

            foreach (MetadataItem item in items) 
            { 
                // Just call the internal helper method for each item
                InternalValidate(item, ospaceErrors, validatedItems); 
            }
        }

        ///  
        /// Event hook to perform preprocessing on the validation error before it gets added to a list of errors
        ///  
        /// The event args for this event 
        protected virtual void OnValidationError(ValidationErrorEventArgs e)
        { 
        }

        /// 
        /// Invoke the event hook Add an error to the list 
        /// 
        /// The list of errors to add to 
        /// The new error to add 
        private void AddError(List errors, EdmItemError newError)
        { 
            // Create an event args object and call the event hook, the derived class may have changed
            // the validation error to some other object, in which case we add the validation error object
            // coming from the event args
            ValidationErrorEventArgs e = new ValidationErrorEventArgs(newError); 
            OnValidationError(e);
            errors.Add(e.ValidationError); 
        } 

        ///  
        /// Allows derived classes to perform additional validation
        /// 
        /// The item to perform additional validation
        /// A collection of errors 
        protected virtual IEnumerable CustomValidate(MetadataItem item)
        { 
            return null; 
        }
 
        /// 
        /// Validate an item object
        /// 
        /// The item to validate 
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void InternalValidate(MetadataItem item, List errors, HashSet validatedItems) 
        {
            Debug.Assert(item != null, "InternalValidate is called with a null item, the caller should check for null first"); 

            // If the item has already been validated or we need to skip readonly items, then skip
            if ( (item.IsReadOnly && SkipReadOnlyItems) || validatedItems.Contains(item) )
            { 
                return;
            } 
 
            // Add this item to the dictionary so we won't validate this again.  Note that we only do this
            // in this function because every other function should eventually delegate to here 
            validatedItems.Add(item);

            // Check to make sure the item has an identity
            if (string.IsNullOrEmpty(item.Identity)) 
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_EmptyIdentity,item)); 
            } 

            switch (item.BuiltInTypeKind) 
            {
                case BuiltInTypeKind.CollectionType:
                    ValidateCollectionType((CollectionType)item, errors, validatedItems);
                    break; 
                case BuiltInTypeKind.ComplexType:
                    ValidateComplexType((ComplexType)item, errors, validatedItems); 
                    break; 
                case BuiltInTypeKind.EntityType:
                    ValidateEntityType((EntityType)item, errors, validatedItems); 
                    break;
                case BuiltInTypeKind.Facet:
                    ValidateFacet((Facet)item, errors, validatedItems);
                    break; 
                case BuiltInTypeKind.MetadataProperty:
                    ValidateMetadataProperty((MetadataProperty)item, errors, validatedItems); 
                    break; 
                case BuiltInTypeKind.NavigationProperty:
                    ValidateNavigationProperty((NavigationProperty)item, errors, validatedItems); 
                    break;
                case BuiltInTypeKind.PrimitiveType:
                    ValidatePrimitiveType((PrimitiveType)item, errors, validatedItems);
                    break; 
                case BuiltInTypeKind.EdmProperty:
                    ValidateEdmProperty((EdmProperty)item, errors, validatedItems); 
                    break; 
                case BuiltInTypeKind.RefType:
                    ValidateRefType((RefType)item, errors, validatedItems); 
                    break;
                case BuiltInTypeKind.TypeUsage:
                    ValidateTypeUsage((TypeUsage)item, errors, validatedItems);
                    break; 

                // Abstract classes 
                case BuiltInTypeKind.EntityTypeBase: 
                case BuiltInTypeKind.EdmType:
                case BuiltInTypeKind.MetadataItem: 
                case BuiltInTypeKind.EdmMember:
                case BuiltInTypeKind.RelationshipEndMember:
                case BuiltInTypeKind.RelationshipType:
                case BuiltInTypeKind.SimpleType: 
                case BuiltInTypeKind.StructuralType:
                    Debug.Assert(false, "An instance with a built in type kind refering to the abstract type " + item.BuiltInTypeKind + " is encountered"); 
                    break; 

                default: 
                    //Debug.Assert(false, String.Format(CultureInfo.InvariantCulture, "Validate not implemented for {0}", item.BuiltInTypeKind));
                    break;
            }
 
            // Performs other custom validation
            IEnumerable customErrors = CustomValidate(item); 
            if (customErrors != null) 
            {
                errors.AddRange(customErrors); 
            }
        }

        ///  
        /// Validate an CollectionType object
        ///  
        /// The CollectionType object to validate 
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void ValidateCollectionType(CollectionType item, List errors, HashSet validatedItems)
        {
            ValidateEdmType(item, errors, validatedItems);
 
            // Check that it doesn't have a base type
            if (item.BaseType != null) 
            { 
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_CollectionTypesCannotHaveBaseType, item));
            } 

            if (item.TypeUsage == null)
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_CollectionHasNoTypeUsage, item)); 
            }
            else 
            { 
                // Just validate the element type, there is nothing on the collection itself to validate
                InternalValidate(item.TypeUsage, errors, validatedItems); 
            }
        }

        ///  
        /// Validate an ComplexType object
        ///  
        /// The ComplexType object to validate 
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void ValidateComplexType(ComplexType item, List errors, HashSet validatedItems)
        {
            ValidateStructuralType(item, errors, validatedItems);
        } 

        ///  
        /// Validate an EdmType object 
        /// 
        /// The EdmType object to validate 
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated
        private void ValidateEdmType(EdmType item, List errors, HashSet validatedItems)
        { 
            ValidateItem(item, errors, validatedItems);
 
            // Check that this type has a name and namespace 
            if (string.IsNullOrEmpty(item.Name))
            { 
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_TypeHasNoName, item));
            }
            if (null == item.NamespaceName ||
                item.DataSpace != DataSpace.OSpace && string.Empty == item.NamespaceName) 
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_TypeHasNoNamespace, item)); 
            } 

            // We don't need to verify that the base type chain eventually gets to null because 
            // the CLR doesn't allow loops in class hierarchies.
            if (item.BaseType != null)
            {
                // Validate the base type 
                InternalValidate(item.BaseType, errors, validatedItems);
            } 
        } 

        ///  
        /// Validate an EntityType object
        /// 
        /// The EntityType object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated
        private void ValidateEntityType(EntityType item, List errors, HashSet validatedItems) 
        { 
            // Verify that no key properties are marked as nullable
            if (item.BaseType == null) 
            {
                // Check that there is at least one key member
                if (item.KeyMembers.Count < 1)
                { 
                    AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_NoKeyMembers, item));
                } 
                else 
                {
                    foreach (EdmProperty keyProperty in item.KeyMembers) 
                    {
                        if (keyProperty.Nullable)
                        {
                            AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_NullableEntityKeyProperty(keyProperty.Name, item.FullName), keyProperty)); 
                        }
                    } 
                } 
            }
            else 
            {
                // Continue to process the entity to see if there are other errors. This allows the user to
                // fix as much as possible at the same time.
                ValidateStructuralType(item, errors, validatedItems); 
            }
        } 
 
        /// 
        /// Validate an Facet object 
        /// 
        /// The Facet object to validate
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void ValidateFacet(Facet item, List errors, HashSet validatedItems)
        { 
            ValidateItem(item, errors, validatedItems); 

            // Check that this facet has a name 
            if (string.IsNullOrEmpty(item.Name))
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_FacetHasNoName, item));
            } 

            // Validate the type 
            if (item.FacetType == null) 
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_FacetTypeIsNull, item)); 
            }
            else
            {
                InternalValidate(item.FacetType, errors, validatedItems); 
            }
        } 
 
        /// 
        /// Validate an MetadataItem object 
        /// 
        /// The MetadataItem object to validate
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void ValidateItem(MetadataItem item, List errors, HashSet validatedItems)
        { 
            // In here, we look at RawMetadataProperties because it dynamically add MetadataProperties when you access the 
            // normal MetadataProperties property. This avoids needless validation and infinite recursion
            if (item.RawMetadataProperties != null) 
            {
                foreach (MetadataProperty itemAttribute in item.MetadataProperties)
                {
                    InternalValidate(itemAttribute, errors, validatedItems); 
                }
            } 
        } 

        ///  
        /// Validate an EdmMember object
        /// 
        /// The item object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated
        private void ValidateEdmMember(EdmMember item, List errors, HashSet validatedItems) 
        { 
            ValidateItem(item, errors, validatedItems);
 
            // Check that this member has a name
            if (string.IsNullOrEmpty(item.Name))
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_MemberHasNoName, item)); 
            }
 
            if (item.DeclaringType == null) 
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_MemberHasNullDeclaringType, item)); 
            }
            else
            {
                InternalValidate(item.DeclaringType, errors, validatedItems); 
            }
 
            if (item.TypeUsage == null) 
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_MemberHasNullTypeUsage, item)); 
            }
            else
            {
                InternalValidate(item.TypeUsage, errors, validatedItems); 
            }
        } 
 
        /// 
        /// Validate an MetadataProperty object 
        /// 
        /// The MetadataProperty object to validate
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void ValidateMetadataProperty(MetadataProperty item, List errors, HashSet validatedItems)
        { 
            // Validate only for user added item attributes, for system attributes, we can skip validation 
            if (item.PropertyKind == PropertyKind.Extended)
            { 
                ValidateItem(item, errors, validatedItems);

                // Check that this member has a name
                if (string.IsNullOrEmpty(item.Name)) 
                {
                    AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_MetadataPropertyHasNoName, item)); 
                } 

                if (item.TypeUsage == null) 
                {
                    AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_ItemAttributeHasNullTypeUsage, item));
                }
                else 
                {
                    InternalValidate(item.TypeUsage, errors, validatedItems); 
                } 
            }
        } 

        /// 
        /// Validate an NavigationProperty object
        ///  
        /// The NavigationProperty object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated 
        private void ValidateNavigationProperty(NavigationProperty item, List errors, HashSet validatedItems)
        { 
            // Continue to process the property to see if there are other errors. This allows the user to fix as much as possible at the same time.
            ValidateEdmMember(item, errors, validatedItems);
        }
 
        /// 
        /// Validate an GetPrimitiveType object 
        ///  
        /// The GetPrimitiveType object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated
        private void ValidatePrimitiveType(PrimitiveType item, List errors, HashSet validatedItems)
        {
            ValidateSimpleType(item, errors, validatedItems); 
        }
 
        ///  
        /// Validate an EdmProperty object
        ///  
        /// The EdmProperty object to validate
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated
        private void ValidateEdmProperty(EdmProperty item, List errors, HashSet validatedItems) 
        {
            ValidateEdmMember(item, errors, validatedItems); 
        } 

        ///  
        /// Validate an RefType object
        /// 
        /// The RefType object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated
        private void ValidateRefType(RefType item, List errors, HashSet validatedItems) 
        { 
            ValidateEdmType(item, errors, validatedItems);
 
            // Check that it doesn't have a base type
            if (item.BaseType != null)
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_RefTypesCannotHaveBaseType, item)); 
            }
 
            // Just validate the element type, there is nothing on the collection itself to validate 
            if (item.ElementType == null)
            { 
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_RefTypeHasNullEntityType, null));
            }
            else
            { 
                InternalValidate(item.ElementType, errors, validatedItems);
            } 
        } 

        ///  
        /// Validate an SimpleType object
        /// 
        /// The SimpleType object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated
        private void ValidateSimpleType(SimpleType item, List errors, HashSet validatedItems) 
        { 
            ValidateEdmType(item, errors, validatedItems);
        } 

        /// 
        /// Validate an StructuralType object
        ///  
        /// The StructuralType object to validate
        /// An error collection for adding validation errors 
        /// A dictionary keeping track of items that have been validated 
        private void ValidateStructuralType(StructuralType item, List errors, HashSet validatedItems)
        { 
            ValidateEdmType(item, errors, validatedItems);

            // Just validate each member, the collection already guaranteed that there aren't any nulls in the collection
            Dictionary allMembers = new Dictionary(); 
            foreach (EdmMember member in item.Members)
            { 
                // Check if the base type already has a member of the same name 
                EdmMember baseMember = null;
                if (allMembers.TryGetValue(member.Name, out baseMember)) 
                {
                    AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_BaseTypeHasMemberOfSameName, item));
                }
                else 
                {
                    allMembers.Add(member.Name, member); 
                } 

                InternalValidate(member, errors, validatedItems); 
            }
        }

        ///  
        /// Validate an TypeUsage object
        ///  
        /// The TypeUsage object to validate 
        /// An error collection for adding validation errors
        /// A dictionary keeping track of items that have been validated 
        private void ValidateTypeUsage(TypeUsage item, List errors, HashSet validatedItems)
        {
            ValidateItem(item, errors, validatedItems);
 
            if (item.EdmType == null)
            { 
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_TypeUsageHasNullEdmType, item)); 
            }
            else 
            {
                InternalValidate(item.EdmType, errors, validatedItems);
            }
 
            foreach (Facet facet in item.Facets)
            { 
                InternalValidate(facet, errors, validatedItems); 
            }
        } 
    }
}

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