Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / TypeUsageBuilder.cs / 1305376 / TypeUsageBuilder.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Xml; using System.Data.Entity; using System.Linq; namespace System.Data.EntityModel.SchemaObjectModel { ////// Supports the construction of a type usage instance for a Scalar/Primitive /// Type. /// internal class TypeUsageBuilder { #region Fields private readonly Dictionary_facetValues; /// /// Element generating the TypeUsage (e.g. StructuredProperty) /// private readonly SchemaElement _element; private string _default = null; private object _defaultObject = null; private bool? _nullable; private TypeUsage _typeUsage; private bool _hasUserDefinedFacets; #endregion #region Constructors internal TypeUsageBuilder(SchemaElement element) { _element = element; _facetValues = new Dictionary(); } #endregion #region Properties /// /// Gets the TypeUsage generated by this builder. /// internal TypeUsage TypeUsage { get { return _typeUsage; } } ////// Gets the nullability of the type usage. /// internal bool Nullable { get { if (_nullable.HasValue) { return _nullable.Value; } return true; } } ////// Gets default. /// internal string Default { get { return _default; } } ////// Gets parsed default value. /// internal object DefaultAsObject { get { return _defaultObject; } } ////// Indicates whether this usage has any user defined facets. /// internal bool HasUserDefinedFacets { get { return _hasUserDefinedFacets; } } #endregion #region Methods private bool TryGetFacets(EdmType edmType, bool complainOnMissingFacet, out DictionarycalculatedFacets) { bool noErrors = true; Dictionary defaultFacets = edmType.GetAssociatedFacetDescriptions().ToDictionary(f => f.FacetName, f => f.DefaultValueFacet); calculatedFacets = new Dictionary (); foreach (Facet defaultFacet in defaultFacets.Values) { object value; if (_facetValues.TryGetValue(defaultFacet.Name, out value)) { // If the facet is a constant facet, then the facet must not be specified in the schema if (defaultFacet.Description.IsConstant) { _element.AddError(ErrorCode.ConstantFacetSpecifiedInSchema, EdmSchemaErrorSeverity.Error, _element, System.Data.Entity.Strings.ConstantFacetSpecifiedInSchema(defaultFacet.Name, edmType.Name)); noErrors = false; } else { calculatedFacets.Add(defaultFacet.Name, Facet.Create(defaultFacet.Description, value)); } // remove the used facet // so we know which ones we need to add below _facetValues.Remove(defaultFacet.Name); } else if (complainOnMissingFacet && defaultFacet.Description.IsRequired) { // Throw missing facet exception _element.AddError(ErrorCode.RequiredFacetMissing, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.RequiredFacetMissing( defaultFacet.Name, edmType.Name)); noErrors = false; } else { calculatedFacets.Add(defaultFacet.Name, defaultFacet); } } foreach (KeyValuePair value in _facetValues) { if (value.Key == EdmProviderManifest.StoreGeneratedPatternFacetName) { Facet facet = Facet.Create(Converter.StoreGeneratedPatternFacet, value.Value); calculatedFacets.Add(facet.Name, facet); } else if (value.Key == EdmProviderManifest.ConcurrencyModeFacetName) { Facet facet = Facet.Create(Converter.ConcurrencyModeFacet, value.Value); calculatedFacets.Add(facet.Name, facet); } else if (edmType is PrimitiveType && (edmType as PrimitiveType).PrimitiveTypeKind == PrimitiveTypeKind.String && value.Key == EdmProviderManifest.CollationFacetName) { Facet facet = Facet.Create(Converter.CollationFacet, value.Value); calculatedFacets.Add(facet.Name, facet); } else { _element.AddError(ErrorCode.FacetNotAllowedByType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FacetNotAllowed(value.Key, edmType.Name)); } } return noErrors; } internal void ValidateAndSetTypeUsage(EdmType edmType, bool complainOnMissingFacet) { Dictionary calculatedFacets; TryGetFacets(edmType, complainOnMissingFacet, out calculatedFacets); _typeUsage = TypeUsage.Create(edmType, calculatedFacets.Values); } /// /// effects: adds errors to _element if there are any; creates a TypeUsage instance using the /// facet values aggregated by this builder and the given scalar type /// /// Scalar type for the type usage internal void ValidateAndSetTypeUsage(ScalarType scalar, bool complainOnMissingFacet) { EntityBid.DASSERT(_element != null); EntityBid.DASSERT(scalar != null); DictionarycalculatedFacets; bool noErrors = TryGetFacets(scalar.Type, complainOnMissingFacet, out calculatedFacets); if (noErrors) { // Only validate the values if there are no errros encountered in the above functions. // If there are errors encountered (like for e.g. precision switch (scalar.TypeKind) { case PrimitiveTypeKind.Binary: ValidateAndSetBinaryFacets(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.String: ValidateAndSetStringFacets(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.Decimal: ValidateAndSetDecimalFacets(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.DateTime: case PrimitiveTypeKind.Time: case PrimitiveTypeKind.DateTimeOffset: ValidatePrecisionFacetsForDateTimeFamily(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.Int16: case PrimitiveTypeKind.Int32: case PrimitiveTypeKind.Int64: case PrimitiveTypeKind.Boolean: case PrimitiveTypeKind.Byte: case PrimitiveTypeKind.SByte: case PrimitiveTypeKind.Double: case PrimitiveTypeKind.Guid: case PrimitiveTypeKind.Single: break; default: Debug.Fail("Did you miss a value"); break; } } _typeUsage = TypeUsage.Create(scalar.Type, calculatedFacets.Values); } /// /// Handles concurrency attributes. /// internal bool HandleAttribute(XmlReader reader) { bool result = InternalHandleAttribute(reader); _hasUserDefinedFacets |= result; return result; } private bool InternalHandleAttribute(XmlReader reader) { if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.NullableFacetName)) { HandleNullableAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, XmlConstants.DefaultValueAttribute)) { HandleDefaultAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.PrecisionFacetName)) { HandlePrecisionAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.ScaleFacetName)) { HandleScaleAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.StoreGeneratedPatternFacetName)) { HandleStoreGeneratedPatternAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.ConcurrencyModeFacetName)) { HandleConcurrencyModeAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.MaxLengthFacetName)) { HandleMaxLengthAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.UnicodeFacetName)) { HandleUnicodeAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.CollationFacetName)) { HandleCollationAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.FixedLengthFacetName)) { HandleIsFixedLengthAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.NullableFacetName)) { HandleNullableAttribute(reader); return true; } return false; } private void ValidateAndSetBinaryFacets(EdmType type, Dictionaryfacets) { // Validate the right facets ValidateLengthFacets(type, facets); } private void ValidateAndSetDecimalFacets(EdmType type, Dictionary facets) { PrimitiveType primitiveType = (PrimitiveType)type; EntityBid.DASSERT(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Decimal); Facet precisionFacet; byte? precision = new byte?(); if (facets.TryGetValue(EdmProviderManifest.PrecisionFacetName, out precisionFacet) && precisionFacet.Value != null) { precision = (byte)precisionFacet.Value; FacetDescription precisionFacetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.PrecisionFacetName); if (precision < precisionFacetDescription.MinValue.Value || precision > precisionFacetDescription.MaxValue.Value) { _element.AddError(ErrorCode.PrecisionOutOfRange, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.PrecisionOutOfRange( precision, precisionFacetDescription.MinValue.Value, precisionFacetDescription.MaxValue.Value, primitiveType.Name)); } } Facet scaleFacet; if (facets.TryGetValue(EdmProviderManifest.ScaleFacetName, out scaleFacet) && scaleFacet.Value != null) { byte scale = (byte)scaleFacet.Value; FacetDescription scaleFacetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.ScaleFacetName); if (scale < scaleFacetDescription.MinValue.Value || scale > scaleFacetDescription.MaxValue.Value) { _element.AddError(ErrorCode.ScaleOutOfRange, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.ScaleOutOfRange( scale, scaleFacetDescription.MinValue.Value, scaleFacetDescription.MaxValue.Value, primitiveType.Name)); } else if (precision.HasValue) { if (precision < scale) { _element.AddError(ErrorCode.BadPrecisionAndScale, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.BadPrecisionAndScale(precision, scale)); } } } } /// /// Validates the Precision value for DateTime family of types since the Min and Max allowed values for Precision for these types are same. /// /// private void ValidatePrecisionFacetsForDateTimeFamily(EdmType type, Dictionaryfacets) { PrimitiveType primitiveType = (PrimitiveType)type; Debug.Assert( (primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.DateTime) ||(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.DateTimeOffset)||(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Time)) ; Facet precisionFacet; byte? precision = new byte?(); if (facets.TryGetValue(EdmProviderManifest.PrecisionFacetName, out precisionFacet) && precisionFacet.Value != null) { precision = (byte)precisionFacet.Value; FacetDescription precisionFacetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.PrecisionFacetName); if (precision < precisionFacetDescription.MinValue.Value || precision > precisionFacetDescription.MaxValue.Value) { _element.AddError(ErrorCode.PrecisionOutOfRange, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.PrecisionOutOfRange( precision, precisionFacetDescription.MinValue.Value, precisionFacetDescription.MaxValue.Value, primitiveType.Name)); } } } private void ValidateAndSetStringFacets(EdmType type, Dictionary facets) { ValidateLengthFacets(type, facets); } private void ValidateLengthFacets(EdmType type, Dictionary facets) { PrimitiveType primitiveType = (PrimitiveType)type; EntityBid.DASSERT(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary || primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.String); // Validate the length facet, if specified Facet maxLenFacet; //here we are assuming if the facet should be here or not is already get checked before if (!facets.TryGetValue(EdmProviderManifest.MaxLengthFacetName, out maxLenFacet) || maxLenFacet.Value == null) { return; } if (Helper.IsUnboundedFacetValue(maxLenFacet)) { return; } int length = (int)maxLenFacet.Value; FacetDescription facetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.MaxLengthFacetName); int maxLength = (int)facetDescription.MaxValue; int minLength = (int)facetDescription.MinValue; if (length < minLength || length > maxLength) { _element.AddError(ErrorCode.InvalidSize, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidSize(length, minLength, maxLength, primitiveType.Name)); } } internal void HandleMaxLengthAttribute(XmlReader reader) { Debug.Assert(reader.LocalName == EdmProviderManifest.MaxLengthFacetName); string value = reader.Value; if (value.Trim() == XmlConstants.Max) { _facetValues.Add(EdmProviderManifest.MaxLengthFacetName, EdmConstants.UnboundedValue); return; } int size = 0; if (!_element.HandleIntAttribute(reader, ref size)) { return; } _facetValues.Add(EdmProviderManifest.MaxLengthFacetName, size); } private void HandleNullableAttribute(XmlReader reader) { bool nullable = false; if (_element.HandleBoolAttribute(reader, ref nullable)) { _facetValues.Add(EdmProviderManifest.NullableFacetName, nullable); _nullable = nullable; } } internal void HandleStoreGeneratedPatternAttribute(XmlReader reader) { string value = reader.Value; StoreGeneratedPattern storeGeneratedPattern; if (value == XmlConstants.None) { storeGeneratedPattern = StoreGeneratedPattern.None; } else if (value == XmlConstants.Identity) { storeGeneratedPattern = StoreGeneratedPattern.Identity; } else if (value == XmlConstants.Computed) { storeGeneratedPattern = StoreGeneratedPattern.Computed; } else { // the error is already added by the schema validation event SchemaElement.AssertReaderConsidersSchemaInvalid(reader); return; } _facetValues.Add(EdmProviderManifest.StoreGeneratedPatternFacetName, storeGeneratedPattern); } internal void HandleConcurrencyModeAttribute(XmlReader reader) { string value = reader.Value; ConcurrencyMode concurrencyMode; if (value == XmlConstants.None) { concurrencyMode = ConcurrencyMode.None; } else if (value == XmlConstants.Fixed) { concurrencyMode = ConcurrencyMode.Fixed; } else { SchemaElement.AssertReaderConsidersSchemaInvalid(reader); // the error is already added by the schema validation event return; } _facetValues.Add(EdmProviderManifest.ConcurrencyModeFacetName, concurrencyMode); } private void HandleDefaultAttribute(XmlReader reader) { _default = reader.Value; } private void HandlePrecisionAttribute(XmlReader reader) { byte precision = 0; if (_element.HandleByteAttribute(reader, ref precision)) { _facetValues.Add(EdmProviderManifest.PrecisionFacetName, precision); } } private void HandleScaleAttribute(XmlReader reader) { byte scale = 0; if (_element.HandleByteAttribute(reader, ref scale)) { _facetValues.Add(EdmProviderManifest.ScaleFacetName, scale); } } private void HandleUnicodeAttribute(XmlReader reader) { bool isUnicode = false; if (_element.HandleBoolAttribute(reader, ref isUnicode)) { _facetValues.Add(EdmProviderManifest.UnicodeFacetName, isUnicode); } } private void HandleCollationAttribute(XmlReader reader) { if (String.IsNullOrEmpty(reader.Value)) { return; } _facetValues.Add(EdmProviderManifest.CollationFacetName, reader.Value); } private void HandleIsFixedLengthAttribute(XmlReader reader) { bool isFixedLength = false; if (_element.HandleBoolAttribute(reader, ref isFixedLength)) { _facetValues.Add(EdmProviderManifest.FixedLengthFacetName, isFixedLength); } } #region Default value validation methods internal void ValidateDefaultValue(SchemaType type) { if (null == _default) { return; } ScalarType scalar = type as ScalarType; if (null != scalar) { ValidateScalarMemberDefaultValue(scalar); } else { _element.AddError(ErrorCode.DefaultNotAllowed, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.DefaultNotAllowed); } } private void ValidateScalarMemberDefaultValue(ScalarType scalar) { Debug.Assert(_default != null); if (scalar != null) { switch (scalar.TypeKind) { case PrimitiveTypeKind.Binary: // required format 0xhexdegits, no more than 2*maxSize digits ValidateBinaryDefaultValue(scalar); return; case PrimitiveTypeKind.Boolean: // required true or false (case sensitive?) ValidateBooleanDefaultValue(scalar); return; case PrimitiveTypeKind.Byte: // integer between byte.MinValue and byteMaxValue; ValidateIntegralDefaultValue(scalar, byte.MinValue, byte.MaxValue); return; case PrimitiveTypeKind.DateTime: // valid datetime parsable using the format in _dateTimeFormat in the SqlDateTime range ValidateDateTimeDefaultValue(scalar); return; case PrimitiveTypeKind.Time: // valid time parsable using the format in _timeFormat in the SqlTime range ValidateTimeDefaultValue(scalar); return; case PrimitiveTypeKind.DateTimeOffset: // valid time parsable using the format in _datetimeoffsetFormat in the SqlDateTimeOffset range ValidateDateTimeOffsetDefaultValue(scalar); return; case PrimitiveTypeKind.Decimal: // valid decimal value (optionally with M) with scale and precision in range ValidateDecimalDefaultValue(scalar); return; case PrimitiveTypeKind.Double: // valid double constant ValidateFloatingPointDefaultValue(scalar, double.MinValue, double.MaxValue); return; case PrimitiveTypeKind.Guid: // valid string parsable by Guid.ctor ValidateGuidDefaultValue(scalar); return; case PrimitiveTypeKind.Int16: // integer between short.MinValue and short.MaxValue ValidateIntegralDefaultValue(scalar, short.MinValue, short.MaxValue); return; case PrimitiveTypeKind.Int32: // integer between int.MinValue and int.MaxValue ValidateIntegralDefaultValue(scalar, int.MinValue, int.MaxValue); return; case PrimitiveTypeKind.Int64: // integer between long.MinValue and long.MaxValue ValidateIntegralDefaultValue(scalar, long.MinValue, long.MaxValue); return; case PrimitiveTypeKind.Single: // valid single value ValidateFloatingPointDefaultValue(scalar, float.MinValue, float.MaxValue); return; case PrimitiveTypeKind.String: // the default is already a string, no parsing check necessary _defaultObject = _default; return; default: _element.AddError(ErrorCode.DefaultNotAllowed, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.DefaultNotAllowed); return; } } } private void ValidateBinaryDefaultValue(ScalarType scalar) { if (scalar.TryParse(_default, out _defaultObject)) { return; } string errorMessage = Strings.InvalidDefaultBinaryWithNoMaxLength(_default); _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, errorMessage); } private void ValidateBooleanDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultBoolean(_default)); } private void ValidateIntegralDefaultValue(ScalarType scalar, long minValue, long maxValue) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultIntegral(_default, minValue, maxValue)); } private void ValidateDateTimeDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) { _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, Strings.InvalidDefaultDateTime(_default, ScalarType.DateTimeFormat.Replace(@"\", ""))); } } private void ValidateTimeDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) { _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, Strings.InvalidDefaultTime(_default, ScalarType.TimeFormat.Replace(@"\", ""))); } } private void ValidateDateTimeOffsetDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) { _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, Strings.InvalidDefaultDateTimeOffset(_default, ScalarType.DateTimeOffsetFormat.Replace(@"\", ""))); } } private void ValidateDecimalDefaultValue(ScalarType scalar) { if (scalar.TryParse(_default, out _defaultObject)) { return; } _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultDecimal(_default, 38, 38)); } private void ValidateFloatingPointDefaultValue(ScalarType scalar, double minValue, double maxValue) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultFloatingPoint(_default, minValue, maxValue)); } private void ValidateGuidDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultGuid(_default)); } #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Xml; using System.Data.Entity; using System.Linq; namespace System.Data.EntityModel.SchemaObjectModel { ////// Supports the construction of a type usage instance for a Scalar/Primitive /// Type. /// internal class TypeUsageBuilder { #region Fields private readonly Dictionary_facetValues; /// /// Element generating the TypeUsage (e.g. StructuredProperty) /// private readonly SchemaElement _element; private string _default = null; private object _defaultObject = null; private bool? _nullable; private TypeUsage _typeUsage; private bool _hasUserDefinedFacets; #endregion #region Constructors internal TypeUsageBuilder(SchemaElement element) { _element = element; _facetValues = new Dictionary(); } #endregion #region Properties /// /// Gets the TypeUsage generated by this builder. /// internal TypeUsage TypeUsage { get { return _typeUsage; } } ////// Gets the nullability of the type usage. /// internal bool Nullable { get { if (_nullable.HasValue) { return _nullable.Value; } return true; } } ////// Gets default. /// internal string Default { get { return _default; } } ////// Gets parsed default value. /// internal object DefaultAsObject { get { return _defaultObject; } } ////// Indicates whether this usage has any user defined facets. /// internal bool HasUserDefinedFacets { get { return _hasUserDefinedFacets; } } #endregion #region Methods private bool TryGetFacets(EdmType edmType, bool complainOnMissingFacet, out DictionarycalculatedFacets) { bool noErrors = true; Dictionary defaultFacets = edmType.GetAssociatedFacetDescriptions().ToDictionary(f => f.FacetName, f => f.DefaultValueFacet); calculatedFacets = new Dictionary (); foreach (Facet defaultFacet in defaultFacets.Values) { object value; if (_facetValues.TryGetValue(defaultFacet.Name, out value)) { // If the facet is a constant facet, then the facet must not be specified in the schema if (defaultFacet.Description.IsConstant) { _element.AddError(ErrorCode.ConstantFacetSpecifiedInSchema, EdmSchemaErrorSeverity.Error, _element, System.Data.Entity.Strings.ConstantFacetSpecifiedInSchema(defaultFacet.Name, edmType.Name)); noErrors = false; } else { calculatedFacets.Add(defaultFacet.Name, Facet.Create(defaultFacet.Description, value)); } // remove the used facet // so we know which ones we need to add below _facetValues.Remove(defaultFacet.Name); } else if (complainOnMissingFacet && defaultFacet.Description.IsRequired) { // Throw missing facet exception _element.AddError(ErrorCode.RequiredFacetMissing, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.RequiredFacetMissing( defaultFacet.Name, edmType.Name)); noErrors = false; } else { calculatedFacets.Add(defaultFacet.Name, defaultFacet); } } foreach (KeyValuePair value in _facetValues) { if (value.Key == EdmProviderManifest.StoreGeneratedPatternFacetName) { Facet facet = Facet.Create(Converter.StoreGeneratedPatternFacet, value.Value); calculatedFacets.Add(facet.Name, facet); } else if (value.Key == EdmProviderManifest.ConcurrencyModeFacetName) { Facet facet = Facet.Create(Converter.ConcurrencyModeFacet, value.Value); calculatedFacets.Add(facet.Name, facet); } else if (edmType is PrimitiveType && (edmType as PrimitiveType).PrimitiveTypeKind == PrimitiveTypeKind.String && value.Key == EdmProviderManifest.CollationFacetName) { Facet facet = Facet.Create(Converter.CollationFacet, value.Value); calculatedFacets.Add(facet.Name, facet); } else { _element.AddError(ErrorCode.FacetNotAllowedByType, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.FacetNotAllowed(value.Key, edmType.Name)); } } return noErrors; } internal void ValidateAndSetTypeUsage(EdmType edmType, bool complainOnMissingFacet) { Dictionary calculatedFacets; TryGetFacets(edmType, complainOnMissingFacet, out calculatedFacets); _typeUsage = TypeUsage.Create(edmType, calculatedFacets.Values); } /// /// effects: adds errors to _element if there are any; creates a TypeUsage instance using the /// facet values aggregated by this builder and the given scalar type /// /// Scalar type for the type usage internal void ValidateAndSetTypeUsage(ScalarType scalar, bool complainOnMissingFacet) { EntityBid.DASSERT(_element != null); EntityBid.DASSERT(scalar != null); DictionarycalculatedFacets; bool noErrors = TryGetFacets(scalar.Type, complainOnMissingFacet, out calculatedFacets); if (noErrors) { // Only validate the values if there are no errros encountered in the above functions. // If there are errors encountered (like for e.g. precision switch (scalar.TypeKind) { case PrimitiveTypeKind.Binary: ValidateAndSetBinaryFacets(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.String: ValidateAndSetStringFacets(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.Decimal: ValidateAndSetDecimalFacets(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.DateTime: case PrimitiveTypeKind.Time: case PrimitiveTypeKind.DateTimeOffset: ValidatePrecisionFacetsForDateTimeFamily(scalar.Type, calculatedFacets); break; case PrimitiveTypeKind.Int16: case PrimitiveTypeKind.Int32: case PrimitiveTypeKind.Int64: case PrimitiveTypeKind.Boolean: case PrimitiveTypeKind.Byte: case PrimitiveTypeKind.SByte: case PrimitiveTypeKind.Double: case PrimitiveTypeKind.Guid: case PrimitiveTypeKind.Single: break; default: Debug.Fail("Did you miss a value"); break; } } _typeUsage = TypeUsage.Create(scalar.Type, calculatedFacets.Values); } /// /// Handles concurrency attributes. /// internal bool HandleAttribute(XmlReader reader) { bool result = InternalHandleAttribute(reader); _hasUserDefinedFacets |= result; return result; } private bool InternalHandleAttribute(XmlReader reader) { if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.NullableFacetName)) { HandleNullableAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, XmlConstants.DefaultValueAttribute)) { HandleDefaultAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.PrecisionFacetName)) { HandlePrecisionAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.ScaleFacetName)) { HandleScaleAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.StoreGeneratedPatternFacetName)) { HandleStoreGeneratedPatternAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.ConcurrencyModeFacetName)) { HandleConcurrencyModeAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.MaxLengthFacetName)) { HandleMaxLengthAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.UnicodeFacetName)) { HandleUnicodeAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.CollationFacetName)) { HandleCollationAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.FixedLengthFacetName)) { HandleIsFixedLengthAttribute(reader); return true; } else if (SchemaElement.CanHandleAttribute(reader, EdmProviderManifest.NullableFacetName)) { HandleNullableAttribute(reader); return true; } return false; } private void ValidateAndSetBinaryFacets(EdmType type, Dictionaryfacets) { // Validate the right facets ValidateLengthFacets(type, facets); } private void ValidateAndSetDecimalFacets(EdmType type, Dictionary facets) { PrimitiveType primitiveType = (PrimitiveType)type; EntityBid.DASSERT(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Decimal); Facet precisionFacet; byte? precision = new byte?(); if (facets.TryGetValue(EdmProviderManifest.PrecisionFacetName, out precisionFacet) && precisionFacet.Value != null) { precision = (byte)precisionFacet.Value; FacetDescription precisionFacetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.PrecisionFacetName); if (precision < precisionFacetDescription.MinValue.Value || precision > precisionFacetDescription.MaxValue.Value) { _element.AddError(ErrorCode.PrecisionOutOfRange, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.PrecisionOutOfRange( precision, precisionFacetDescription.MinValue.Value, precisionFacetDescription.MaxValue.Value, primitiveType.Name)); } } Facet scaleFacet; if (facets.TryGetValue(EdmProviderManifest.ScaleFacetName, out scaleFacet) && scaleFacet.Value != null) { byte scale = (byte)scaleFacet.Value; FacetDescription scaleFacetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.ScaleFacetName); if (scale < scaleFacetDescription.MinValue.Value || scale > scaleFacetDescription.MaxValue.Value) { _element.AddError(ErrorCode.ScaleOutOfRange, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.ScaleOutOfRange( scale, scaleFacetDescription.MinValue.Value, scaleFacetDescription.MaxValue.Value, primitiveType.Name)); } else if (precision.HasValue) { if (precision < scale) { _element.AddError(ErrorCode.BadPrecisionAndScale, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.BadPrecisionAndScale(precision, scale)); } } } } /// /// Validates the Precision value for DateTime family of types since the Min and Max allowed values for Precision for these types are same. /// /// private void ValidatePrecisionFacetsForDateTimeFamily(EdmType type, Dictionaryfacets) { PrimitiveType primitiveType = (PrimitiveType)type; Debug.Assert( (primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.DateTime) ||(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.DateTimeOffset)||(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Time)) ; Facet precisionFacet; byte? precision = new byte?(); if (facets.TryGetValue(EdmProviderManifest.PrecisionFacetName, out precisionFacet) && precisionFacet.Value != null) { precision = (byte)precisionFacet.Value; FacetDescription precisionFacetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.PrecisionFacetName); if (precision < precisionFacetDescription.MinValue.Value || precision > precisionFacetDescription.MaxValue.Value) { _element.AddError(ErrorCode.PrecisionOutOfRange, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.PrecisionOutOfRange( precision, precisionFacetDescription.MinValue.Value, precisionFacetDescription.MaxValue.Value, primitiveType.Name)); } } } private void ValidateAndSetStringFacets(EdmType type, Dictionary facets) { ValidateLengthFacets(type, facets); } private void ValidateLengthFacets(EdmType type, Dictionary facets) { PrimitiveType primitiveType = (PrimitiveType)type; EntityBid.DASSERT(primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary || primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.String); // Validate the length facet, if specified Facet maxLenFacet; //here we are assuming if the facet should be here or not is already get checked before if (!facets.TryGetValue(EdmProviderManifest.MaxLengthFacetName, out maxLenFacet) || maxLenFacet.Value == null) { return; } if (Helper.IsUnboundedFacetValue(maxLenFacet)) { return; } int length = (int)maxLenFacet.Value; FacetDescription facetDescription = Helper.GetFacet(primitiveType.FacetDescriptions, EdmProviderManifest.MaxLengthFacetName); int maxLength = (int)facetDescription.MaxValue; int minLength = (int)facetDescription.MinValue; if (length < minLength || length > maxLength) { _element.AddError(ErrorCode.InvalidSize, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidSize(length, minLength, maxLength, primitiveType.Name)); } } internal void HandleMaxLengthAttribute(XmlReader reader) { Debug.Assert(reader.LocalName == EdmProviderManifest.MaxLengthFacetName); string value = reader.Value; if (value.Trim() == XmlConstants.Max) { _facetValues.Add(EdmProviderManifest.MaxLengthFacetName, EdmConstants.UnboundedValue); return; } int size = 0; if (!_element.HandleIntAttribute(reader, ref size)) { return; } _facetValues.Add(EdmProviderManifest.MaxLengthFacetName, size); } private void HandleNullableAttribute(XmlReader reader) { bool nullable = false; if (_element.HandleBoolAttribute(reader, ref nullable)) { _facetValues.Add(EdmProviderManifest.NullableFacetName, nullable); _nullable = nullable; } } internal void HandleStoreGeneratedPatternAttribute(XmlReader reader) { string value = reader.Value; StoreGeneratedPattern storeGeneratedPattern; if (value == XmlConstants.None) { storeGeneratedPattern = StoreGeneratedPattern.None; } else if (value == XmlConstants.Identity) { storeGeneratedPattern = StoreGeneratedPattern.Identity; } else if (value == XmlConstants.Computed) { storeGeneratedPattern = StoreGeneratedPattern.Computed; } else { // the error is already added by the schema validation event SchemaElement.AssertReaderConsidersSchemaInvalid(reader); return; } _facetValues.Add(EdmProviderManifest.StoreGeneratedPatternFacetName, storeGeneratedPattern); } internal void HandleConcurrencyModeAttribute(XmlReader reader) { string value = reader.Value; ConcurrencyMode concurrencyMode; if (value == XmlConstants.None) { concurrencyMode = ConcurrencyMode.None; } else if (value == XmlConstants.Fixed) { concurrencyMode = ConcurrencyMode.Fixed; } else { SchemaElement.AssertReaderConsidersSchemaInvalid(reader); // the error is already added by the schema validation event return; } _facetValues.Add(EdmProviderManifest.ConcurrencyModeFacetName, concurrencyMode); } private void HandleDefaultAttribute(XmlReader reader) { _default = reader.Value; } private void HandlePrecisionAttribute(XmlReader reader) { byte precision = 0; if (_element.HandleByteAttribute(reader, ref precision)) { _facetValues.Add(EdmProviderManifest.PrecisionFacetName, precision); } } private void HandleScaleAttribute(XmlReader reader) { byte scale = 0; if (_element.HandleByteAttribute(reader, ref scale)) { _facetValues.Add(EdmProviderManifest.ScaleFacetName, scale); } } private void HandleUnicodeAttribute(XmlReader reader) { bool isUnicode = false; if (_element.HandleBoolAttribute(reader, ref isUnicode)) { _facetValues.Add(EdmProviderManifest.UnicodeFacetName, isUnicode); } } private void HandleCollationAttribute(XmlReader reader) { if (String.IsNullOrEmpty(reader.Value)) { return; } _facetValues.Add(EdmProviderManifest.CollationFacetName, reader.Value); } private void HandleIsFixedLengthAttribute(XmlReader reader) { bool isFixedLength = false; if (_element.HandleBoolAttribute(reader, ref isFixedLength)) { _facetValues.Add(EdmProviderManifest.FixedLengthFacetName, isFixedLength); } } #region Default value validation methods internal void ValidateDefaultValue(SchemaType type) { if (null == _default) { return; } ScalarType scalar = type as ScalarType; if (null != scalar) { ValidateScalarMemberDefaultValue(scalar); } else { _element.AddError(ErrorCode.DefaultNotAllowed, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.DefaultNotAllowed); } } private void ValidateScalarMemberDefaultValue(ScalarType scalar) { Debug.Assert(_default != null); if (scalar != null) { switch (scalar.TypeKind) { case PrimitiveTypeKind.Binary: // required format 0xhexdegits, no more than 2*maxSize digits ValidateBinaryDefaultValue(scalar); return; case PrimitiveTypeKind.Boolean: // required true or false (case sensitive?) ValidateBooleanDefaultValue(scalar); return; case PrimitiveTypeKind.Byte: // integer between byte.MinValue and byteMaxValue; ValidateIntegralDefaultValue(scalar, byte.MinValue, byte.MaxValue); return; case PrimitiveTypeKind.DateTime: // valid datetime parsable using the format in _dateTimeFormat in the SqlDateTime range ValidateDateTimeDefaultValue(scalar); return; case PrimitiveTypeKind.Time: // valid time parsable using the format in _timeFormat in the SqlTime range ValidateTimeDefaultValue(scalar); return; case PrimitiveTypeKind.DateTimeOffset: // valid time parsable using the format in _datetimeoffsetFormat in the SqlDateTimeOffset range ValidateDateTimeOffsetDefaultValue(scalar); return; case PrimitiveTypeKind.Decimal: // valid decimal value (optionally with M) with scale and precision in range ValidateDecimalDefaultValue(scalar); return; case PrimitiveTypeKind.Double: // valid double constant ValidateFloatingPointDefaultValue(scalar, double.MinValue, double.MaxValue); return; case PrimitiveTypeKind.Guid: // valid string parsable by Guid.ctor ValidateGuidDefaultValue(scalar); return; case PrimitiveTypeKind.Int16: // integer between short.MinValue and short.MaxValue ValidateIntegralDefaultValue(scalar, short.MinValue, short.MaxValue); return; case PrimitiveTypeKind.Int32: // integer between int.MinValue and int.MaxValue ValidateIntegralDefaultValue(scalar, int.MinValue, int.MaxValue); return; case PrimitiveTypeKind.Int64: // integer between long.MinValue and long.MaxValue ValidateIntegralDefaultValue(scalar, long.MinValue, long.MaxValue); return; case PrimitiveTypeKind.Single: // valid single value ValidateFloatingPointDefaultValue(scalar, float.MinValue, float.MaxValue); return; case PrimitiveTypeKind.String: // the default is already a string, no parsing check necessary _defaultObject = _default; return; default: _element.AddError(ErrorCode.DefaultNotAllowed, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.DefaultNotAllowed); return; } } } private void ValidateBinaryDefaultValue(ScalarType scalar) { if (scalar.TryParse(_default, out _defaultObject)) { return; } string errorMessage = Strings.InvalidDefaultBinaryWithNoMaxLength(_default); _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, errorMessage); } private void ValidateBooleanDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultBoolean(_default)); } private void ValidateIntegralDefaultValue(ScalarType scalar, long minValue, long maxValue) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultIntegral(_default, minValue, maxValue)); } private void ValidateDateTimeDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) { _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, Strings.InvalidDefaultDateTime(_default, ScalarType.DateTimeFormat.Replace(@"\", ""))); } } private void ValidateTimeDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) { _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, Strings.InvalidDefaultTime(_default, ScalarType.TimeFormat.Replace(@"\", ""))); } } private void ValidateDateTimeOffsetDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) { _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, Strings.InvalidDefaultDateTimeOffset(_default, ScalarType.DateTimeOffsetFormat.Replace(@"\", ""))); } } private void ValidateDecimalDefaultValue(ScalarType scalar) { if (scalar.TryParse(_default, out _defaultObject)) { return; } _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultDecimal(_default, 38, 38)); } private void ValidateFloatingPointDefaultValue(ScalarType scalar, double minValue, double maxValue) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultFloatingPoint(_default, minValue, maxValue)); } private void ValidateGuidDefaultValue(ScalarType scalar) { if (!scalar.TryParse(_default, out _defaultObject)) _element.AddError(ErrorCode.InvalidDefault, EdmSchemaErrorSeverity.Error, System.Data.Entity.Strings.InvalidDefaultGuid(_default)); } #endregion #endregion } } // 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
- FontStyle.cs
- ObjectQueryState.cs
- TemplateBindingExtensionConverter.cs
- ActionNotSupportedException.cs
- OuterGlowBitmapEffect.cs
- SoapEnumAttribute.cs
- HasCopySemanticsAttribute.cs
- AsyncResult.cs
- PropertyFilterAttribute.cs
- InputLanguageSource.cs
- SQLSingleStorage.cs
- xml.cs
- ReadContentAsBinaryHelper.cs
- ProviderCommandInfoUtils.cs
- ToolBarButtonClickEvent.cs
- UnsafeNativeMethods.cs
- ObjectSecurity.cs
- GeometryConverter.cs
- RowVisual.cs
- Mapping.cs
- XmlObjectSerializerReadContext.cs
- DropShadowBitmapEffect.cs
- RegexWorker.cs
- JoinGraph.cs
- SafeFreeMibTable.cs
- OleDbCommand.cs
- RequestQueryProcessor.cs
- SiteIdentityPermission.cs
- control.ime.cs
- EntityModelSchemaGenerator.cs
- FormClosingEvent.cs
- TimelineGroup.cs
- SiteMapNodeItemEventArgs.cs
- StylusTip.cs
- OutputCacheProfile.cs
- TemplateManager.cs
- XamlVector3DCollectionSerializer.cs
- Classification.cs
- InteropBitmapSource.cs
- SqlTrackingWorkflowInstance.cs
- TypeResolvingOptionsAttribute.cs
- UrlMapping.cs
- RegexCompiler.cs
- TemplateBuilder.cs
- AsyncCompletedEventArgs.cs
- RenderOptions.cs
- DeadCharTextComposition.cs
- RootNamespaceAttribute.cs
- ModelTreeManager.cs
- Point3DAnimationBase.cs
- WebWorkflowRole.cs
- DataSourceXmlSerializationAttribute.cs
- EntityProviderFactory.cs
- SimpleBitVector32.cs
- UpdateExpressionVisitor.cs
- ObjectNotFoundException.cs
- Expression.cs
- ServiceRoute.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- DesigntimeLicenseContextSerializer.cs
- CqlLexerHelpers.cs
- ScrollData.cs
- XDRSchema.cs
- HttpListenerResponse.cs
- ClassData.cs
- ToolStripItemTextRenderEventArgs.cs
- _ScatterGatherBuffers.cs
- LinkedResource.cs
- XmlHierarchicalDataSourceView.cs
- TextContainerChangedEventArgs.cs
- WSSecurityPolicy.cs
- RMEnrollmentPage1.cs
- WebPartAddingEventArgs.cs
- QueryPageSettingsEventArgs.cs
- DynamicMethod.cs
- AnnotationAdorner.cs
- Journaling.cs
- CommandDevice.cs
- Stacktrace.cs
- WsdlInspector.cs
- DefaultParameterValueAttribute.cs
- Parameter.cs
- CharacterString.cs
- _ScatterGatherBuffers.cs
- ObjectDataSource.cs
- ServiceAuthorizationElement.cs
- TextModifier.cs
- RoutedEventConverter.cs
- RegexInterpreter.cs
- CurrencyManager.cs
- SqlConnectionStringBuilder.cs
- StructuralObject.cs
- NegationPusher.cs
- EllipseGeometry.cs
- Compilation.cs
- UnSafeCharBuffer.cs
- storepermission.cs
- WebPartConnectionsConfigureVerb.cs
- NameHandler.cs
- GeneralTransform2DTo3DTo2D.cs