EdmValidator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Metadata / EdmValidator.cs / 4 / EdmValidator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
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) 
        {
            // Navigation properties are only valid inside classes that support IEntityWithRelationships 
            if (!(typeof(System.Data.Objects.DataClasses.IEntityWithRelationships).IsAssignableFrom(item.DeclaringType.ClrType)))
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_NavPropWithoutIEntityWithRelationships(item.Name, item.DeclaringType.FullName), item));
            } 

            // 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.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
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) 
        {
            // Navigation properties are only valid inside classes that support IEntityWithRelationships 
            if (!(typeof(System.Data.Objects.DataClasses.IEntityWithRelationships).IsAssignableFrom(item.DeclaringType.ClrType)))
            {
                AddError(errors, new EdmItemError(System.Data.Entity.Strings.Validator_NavPropWithoutIEntityWithRelationships(item.Name, item.DeclaringType.FullName), item));
            } 

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