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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ConstrainedDataObject.cs
- CaseInsensitiveComparer.cs
- ResXDataNode.cs
- Animatable.cs
- SapiRecoContext.cs
- DocumentViewerBase.cs
- StandardCommands.cs
- ProviderUtil.cs
- RowParagraph.cs
- PropertyChangedEventArgs.cs
- WsdlParser.cs
- LocatorPart.cs
- HuffModule.cs
- TextBounds.cs
- LassoHelper.cs
- SpeechRecognizer.cs
- ProxyOperationRuntime.cs
- LayeredChannelFactory.cs
- HMACMD5.cs
- SerializationInfo.cs
- Util.cs
- GridSplitterAutomationPeer.cs
- ListDependantCardsRequest.cs
- XmlAtomicValue.cs
- DelayDesigner.cs
- StylusPointPropertyUnit.cs
- HwndMouseInputProvider.cs
- CommandPlan.cs
- GatewayDefinition.cs
- InvalidFilterCriteriaException.cs
- RightsManagementErrorHandler.cs
- CryptoStream.cs
- ClientTargetCollection.cs
- OutputScopeManager.cs
- FlagsAttribute.cs
- ReadOnlyDataSourceView.cs
- HijriCalendar.cs
- ExtendedPropertyInfo.cs
- ObservableCollection.cs
- HttpFileCollection.cs
- PageTheme.cs
- OleDbCommand.cs
- Page.cs
- ProtocolsSection.cs
- SqlAggregateChecker.cs
- Matrix.cs
- Latin1Encoding.cs
- ErrorHandler.cs
- DBSqlParserTableCollection.cs
- MenuStrip.cs
- SqlNodeAnnotations.cs
- DataGridItem.cs
- EventWaitHandle.cs
- ExtractedStateEntry.cs
- Line.cs
- UnsafeNativeMethods.cs
- DetailsViewPageEventArgs.cs
- RequestCacheManager.cs
- FlowLayoutSettings.cs
- NodeInfo.cs
- NetTcpSecurityElement.cs
- ViewPort3D.cs
- SocketPermission.cs
- AmbientLight.cs
- PenThread.cs
- RectangleF.cs
- LicFileLicenseProvider.cs
- BindingWorker.cs
- HttpClientChannel.cs
- ParallelDesigner.cs
- TcpClientChannel.cs
- Message.cs
- SiteIdentityPermission.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- XLinq.cs
- SqlDataSourceFilteringEventArgs.cs
- HScrollBar.cs
- ProfileBuildProvider.cs
- __FastResourceComparer.cs
- PublisherIdentityPermission.cs
- TimeSpanSecondsConverter.cs
- Brush.cs
- PenThread.cs
- Color.cs
- DrawingContextDrawingContextWalker.cs
- Rule.cs
- AdRotator.cs
- WrappedIUnknown.cs
- SchemaImporterExtensionElement.cs
- CompilationSection.cs
- CatalogZoneDesigner.cs
- PathBox.cs
- XAMLParseException.cs
- TextBox.cs
- HandlerBase.cs
- GotoExpression.cs
- BitmapVisualManager.cs
- PageParser.cs
- OracleColumn.cs
- DataShape.cs