Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / TypeUsageBuilder.cs / 4 / 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 ////// 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) { Bid.DASSERT(_element != null); Bid.DASSERT(scalar != null); bool noErrors = true; DictionarydefaultFacets = scalar.Type.GetAssociatedFacetDescriptions().ToDictionary(f => f.FacetName, f => f.DefaultValueFacet); Dictionary 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, scalar.Type.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, scalar.Type.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 (scalar.Type.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, scalar.Type.Name)); } } 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; Bid.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; Bid.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 ////// 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) { Bid.DASSERT(_element != null); Bid.DASSERT(scalar != null); bool noErrors = true; DictionarydefaultFacets = scalar.Type.GetAssociatedFacetDescriptions().ToDictionary(f => f.FacetName, f => f.DefaultValueFacet); Dictionary 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, scalar.Type.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, scalar.Type.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 (scalar.Type.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, scalar.Type.Name)); } } 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; Bid.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; Bid.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
- EmptyStringExpandableObjectConverter.cs
- TextBoxLine.cs
- EntityDataSourceChangedEventArgs.cs
- ForeignConstraint.cs
- HostingEnvironmentSection.cs
- PlacementWorkspace.cs
- DispatcherEventArgs.cs
- ValueType.cs
- FrameworkContentElementAutomationPeer.cs
- Schema.cs
- PrePrepareMethodAttribute.cs
- TypeUtils.cs
- GridSplitter.cs
- InternalBase.cs
- HelpEvent.cs
- RootProfilePropertySettingsCollection.cs
- DayRenderEvent.cs
- TableProviderWrapper.cs
- InvalidDataException.cs
- ToolStripItemTextRenderEventArgs.cs
- DockProviderWrapper.cs
- COM2FontConverter.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- FreezableDefaultValueFactory.cs
- SqlClientPermission.cs
- AnimationClockResource.cs
- Dynamic.cs
- CompilerState.cs
- PagesSection.cs
- BindingCompleteEventArgs.cs
- SqlTransaction.cs
- SqlDelegatedTransaction.cs
- Vector.cs
- RecognitionEventArgs.cs
- EntityClassGenerator.cs
- DetailsViewInsertEventArgs.cs
- DbConnectionStringBuilder.cs
- XmlDataSourceNodeDescriptor.cs
- XmlReaderSettings.cs
- ExtendedPropertyDescriptor.cs
- ImageInfo.cs
- AsnEncodedData.cs
- DbBuffer.cs
- XmlCharCheckingWriter.cs
- ConfigurationStrings.cs
- Site.cs
- RoutedCommand.cs
- KerberosRequestorSecurityTokenAuthenticator.cs
- OperationInvokerBehavior.cs
- RepeatButtonAutomationPeer.cs
- XmlHelper.cs
- WizardPanel.cs
- ManagedWndProcTracker.cs
- AssertHelper.cs
- PersonalizationState.cs
- OraclePermissionAttribute.cs
- ImageCodecInfo.cs
- ProtocolElement.cs
- NavigationProperty.cs
- SqlBulkCopyColumnMappingCollection.cs
- Stackframe.cs
- Mutex.cs
- BrowserCapabilitiesFactoryBase.cs
- UnSafeCharBuffer.cs
- TextFormatterHost.cs
- XmlQueryCardinality.cs
- PersistenceException.cs
- LabelAutomationPeer.cs
- ExecutionEngineException.cs
- ChtmlTextWriter.cs
- CalendarData.cs
- OdbcInfoMessageEvent.cs
- DefaultDiscoveryService.cs
- ObfuscateAssemblyAttribute.cs
- StrokeCollectionDefaultValueFactory.cs
- ToolStrip.cs
- WebPartConnectionsCloseVerb.cs
- TextRunProperties.cs
- GradientStop.cs
- ComPlusDiagnosticTraceRecords.cs
- WebServiceHost.cs
- _SecureChannel.cs
- ResourceLoader.cs
- BitHelper.cs
- DelegateSerializationHolder.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- SerializationInfoEnumerator.cs
- CapabilitiesSection.cs
- AutoSizeComboBox.cs
- DefaultPropertiesToSend.cs
- DataRowCollection.cs
- HitTestWithGeometryDrawingContextWalker.cs
- httpapplicationstate.cs
- GeneralTransform3DCollection.cs
- IssuanceLicense.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- DataGridViewCellStyleChangedEventArgs.cs
- ArgIterator.cs
- DetailsViewUpdateEventArgs.cs
- WebZone.cs