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(Listerrors, 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 IEnumerableCustomValidate(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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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, Listerrors, 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AuthenticationConfig.cs
- SQLBytesStorage.cs
- TextEditorSelection.cs
- Operand.cs
- StringCollection.cs
- CryptoApi.cs
- DelegatingTypeDescriptionProvider.cs
- XmlSchemaCompilationSettings.cs
- WebPartConnectionCollection.cs
- DoubleCollectionConverter.cs
- ChoiceConverter.cs
- SqlAggregateChecker.cs
- UInt32Storage.cs
- RoutedEventArgs.cs
- MsmqHostedTransportManager.cs
- WmfPlaceableFileHeader.cs
- AddingNewEventArgs.cs
- ShaderEffect.cs
- CodeDelegateInvokeExpression.cs
- Mapping.cs
- SqlBuffer.cs
- DataStorage.cs
- BinaryMessageEncodingBindingElement.cs
- BrowserDefinition.cs
- _HeaderInfo.cs
- TypeElement.cs
- StylusPointPropertyId.cs
- IsolatedStorageFile.cs
- FormViewPagerRow.cs
- LayoutEditorPart.cs
- TableLayoutPanelCellPosition.cs
- ButtonBase.cs
- ResourceProviderFactory.cs
- HyperLinkField.cs
- RelationshipManager.cs
- TextComposition.cs
- CatchBlock.cs
- RectangleHotSpot.cs
- Converter.cs
- InvalidPrinterException.cs
- UpdateManifestForBrowserApplication.cs
- NativeMethods.cs
- MSHTMLHostUtil.cs
- DependencyObject.cs
- ValidateNames.cs
- TextTreeRootTextBlock.cs
- RepeatButton.cs
- SoapTypeAttribute.cs
- HttpCacheVaryByContentEncodings.cs
- HttpSessionStateBase.cs
- Compress.cs
- UnhandledExceptionEventArgs.cs
- XmlSerializationGeneratedCode.cs
- DefaultEventAttribute.cs
- AnonymousIdentificationModule.cs
- safelinkcollection.cs
- DefaultPropertyAttribute.cs
- DefaultWorkflowLoaderService.cs
- PowerStatus.cs
- EvidenceTypeDescriptor.cs
- StreamWithDictionary.cs
- TemplateXamlParser.cs
- GacUtil.cs
- Cloud.cs
- FlatButtonAppearance.cs
- ItemCheckEvent.cs
- WebConfigurationHostFileChange.cs
- LoginName.cs
- CacheSection.cs
- fixedPageContentExtractor.cs
- SimpleColumnProvider.cs
- Tracking.cs
- EntityDataSourceEntityTypeFilterItem.cs
- CollectionChangeEventArgs.cs
- ThumbButtonInfo.cs
- CompiledRegexRunnerFactory.cs
- TreeNodeStyleCollection.cs
- SoapInteropTypes.cs
- SafeCryptHandles.cs
- StickyNoteContentControl.cs
- DetailsViewInsertedEventArgs.cs
- TimerElapsedEvenArgs.cs
- ChangeConflicts.cs
- SendKeys.cs
- KeySplineConverter.cs
- MembershipSection.cs
- RelOps.cs
- HandlerWithFactory.cs
- FileAccessException.cs
- ActivityXRefConverter.cs
- DoubleLinkListEnumerator.cs
- RefreshResponseInfo.cs
- ProtocolViolationException.cs
- WebResourceUtil.cs
- XmlEntityReference.cs
- DataGridViewSortCompareEventArgs.cs
- RadioButtonPopupAdapter.cs
- _ListenerAsyncResult.cs
- Formatter.cs
- SyndicationSerializer.cs