| File: System\Data\SimpleType.cs | Web Access |
| Project: src\runtime\src\libraries\System.Data.Common\src\System.Data.Common.csproj (System.Data.Common) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; using System.Data.Common; using System.Globalization; using System.Runtime.Serialization; using System.Xml; using System.Xml.Schema; namespace System.Data { internal sealed class SimpleType : ISerializable { private string? _baseType; // base type name private SimpleType? _baseSimpleType; private XmlQualifiedName? _xmlBaseType; // Qualified name of Basetype private string? _name = string.Empty; private int _length = -1; private int _minLength = -1; private int _maxLength = -1; private string? _pattern = string.Empty; private string _ns = string.Empty; // my ns private string? _maxExclusive = string.Empty; private string? _maxInclusive = string.Empty; private string? _minExclusive = string.Empty; private string? _minInclusive = string.Empty; internal string? _enumeration = string.Empty; internal SimpleType(string baseType) { // anonymous simpletype _baseType = baseType; } internal SimpleType(XmlSchemaSimpleType node) { // named simpletype _name = node.Name; _ns = (node.QualifiedName != null) ? node.QualifiedName.Namespace : ""; LoadTypeValues(node); } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { throw new PlatformNotSupportedException(); } internal void LoadTypeValues(XmlSchemaSimpleType node) { if ((node.Content is XmlSchemaSimpleTypeList) || (node.Content is XmlSchemaSimpleTypeUnion)) throw ExceptionBuilder.SimpleTypeNotSupported(); if (node.Content is XmlSchemaSimpleTypeRestriction content) { XmlSchemaSimpleType? ancestor = node.BaseXmlSchemaType as XmlSchemaSimpleType; if ((ancestor != null) && (ancestor.QualifiedName.Namespace != Keywords.XSDNS)) { _baseSimpleType = new SimpleType(ancestor); } // do we need to put qualified name? // for user defined simpletype, always go with qname if (content.BaseTypeName.Namespace == Keywords.XSDNS) _baseType = content.BaseTypeName.Name; else _baseType = content.BaseTypeName.ToString(); if (_baseSimpleType != null && _baseSimpleType.Name != null && _baseSimpleType.Name.Length > 0) { _xmlBaseType = _baseSimpleType.XmlBaseType; // SimpleTypeQualifiedName; } else { _xmlBaseType = content.BaseTypeName; } if (_baseType == null || _baseType.Length == 0) { _baseType = content.BaseType!.Name; _xmlBaseType = null; } if (_baseType == "NOTATION") _baseType = "string"; foreach (XmlSchemaFacet facet in content.Facets) { if (facet is XmlSchemaLengthFacet) _length = Convert.ToInt32(facet.Value, null); if (facet is XmlSchemaMinLengthFacet) _minLength = Convert.ToInt32(facet.Value, null); if (facet is XmlSchemaMaxLengthFacet) _maxLength = Convert.ToInt32(facet.Value, null); if (facet is XmlSchemaPatternFacet) _pattern = facet.Value; if (facet is XmlSchemaEnumerationFacet) _enumeration = !string.IsNullOrEmpty(_enumeration) ? _enumeration + " " + facet.Value : facet.Value; if (facet is XmlSchemaMinExclusiveFacet) _minExclusive = facet.Value; if (facet is XmlSchemaMinInclusiveFacet) _minInclusive = facet.Value; if (facet is XmlSchemaMaxExclusiveFacet) _maxExclusive = facet.Value; if (facet is XmlSchemaMaxInclusiveFacet) _maxInclusive = facet.Value; } } string? tempStr = XSDSchema.GetMsdataAttribute(node, Keywords.TARGETNAMESPACE); if (tempStr != null) _ns = tempStr; } internal bool IsPlainString() { return ( XSDSchema.QualifiedName(_baseType!) == XSDSchema.QualifiedName("string") && string.IsNullOrEmpty(_name) && _length == -1 && _minLength == -1 && _maxLength == -1 && string.IsNullOrEmpty(_pattern) && string.IsNullOrEmpty(_maxExclusive) && string.IsNullOrEmpty(_maxInclusive) && string.IsNullOrEmpty(_minExclusive) && string.IsNullOrEmpty(_minInclusive) && string.IsNullOrEmpty(_enumeration) ); } internal string? BaseType { get { return _baseType; } } internal XmlQualifiedName? XmlBaseType { get { return _xmlBaseType; } } internal string? Name { get { return _name; } } internal string Namespace { get { return _ns; } } internal int Length { get { return _length; } } internal int MaxLength { get { return _maxLength; } set { _maxLength = value; } } internal SimpleType? BaseSimpleType { get { return _baseSimpleType; } } // return qualified name of this simple type public string? SimpleTypeQualifiedName { get { if (_ns.Length == 0) return _name; return (_ns + ":" + _name); } } internal static string QualifiedName(string name) { if (!name.Contains(':')) return Keywords.XSD_PREFIXCOLON + name; else return name; } /* internal XmlNode ToNode(XmlDocument dc) { return ToNode(dc, null, false); } */ internal XmlNode ToNode(XmlDocument dc, Hashtable prefixes, bool inRemoting) { XmlElement typeNode = dc.CreateElement(Keywords.XSD_PREFIX, Keywords.XSD_SIMPLETYPE, Keywords.XSDNS); if (!string.IsNullOrEmpty(_name)) { // this is a global type typeNode.SetAttribute(Keywords.NAME, _name); if (inRemoting) { typeNode.SetAttribute(Keywords.TARGETNAMESPACE, Keywords.MSDNS, Namespace); } } XmlElement type = dc.CreateElement(Keywords.XSD_PREFIX, Keywords.XSD_RESTRICTION, Keywords.XSDNS); if (!inRemoting) { if (_baseSimpleType != null) { if (_baseSimpleType.Namespace != null && _baseSimpleType.Namespace.Length > 0) { string? prefix = (prefixes != null) ? (string?)prefixes[_baseSimpleType.Namespace] : null; if (prefix != null) { type.SetAttribute(Keywords.BASE, (prefix + ":" + _baseSimpleType.Name)); } else { type.SetAttribute(Keywords.BASE, _baseSimpleType.Name); } } else { // amirhmy type.SetAttribute(Keywords.BASE, _baseSimpleType.Name); } } else { type.SetAttribute(Keywords.BASE, QualifiedName(_baseType!)); // has to be xs:SomePrimitiveType } } else { type.SetAttribute(Keywords.BASE, (_baseSimpleType != null) ? _baseSimpleType.Name : QualifiedName(_baseType!)); } XmlElement constraint; if (_length >= 0) { constraint = dc.CreateElement(Keywords.XSD_PREFIX, Keywords.XSD_LENGTH, Keywords.XSDNS); constraint.SetAttribute(Keywords.VALUE, _length.ToString(CultureInfo.InvariantCulture)); type.AppendChild(constraint); } if (_maxLength >= 0) { constraint = dc.CreateElement(Keywords.XSD_PREFIX, Keywords.XSD_MAXLENGTH, Keywords.XSDNS); constraint.SetAttribute(Keywords.VALUE, _maxLength.ToString(CultureInfo.InvariantCulture)); type.AppendChild(constraint); } typeNode.AppendChild(type); return typeNode; } internal static SimpleType CreateEnumeratedType(string values) { SimpleType enumType = new SimpleType("string"); enumType._enumeration = values; return enumType; } internal static SimpleType CreateByteArrayType() { SimpleType byteArrayType = new SimpleType("base64Binary"); return byteArrayType; } internal static SimpleType CreateLimitedStringType(int length) { SimpleType limitedString = new SimpleType("string"); limitedString._maxLength = length; return limitedString; } internal static SimpleType? CreateSimpleType(StorageType typeCode, Type type) { if ((typeCode == StorageType.Char) && (type == typeof(char))) { return new SimpleType("string") { _length = 1 }; } return null; } // Assumption is otherSimpleType and current ST name and NS matches. // if existing simpletype is being redefined with different facets, then it will return no-empty string defining the error internal string HasConflictingDefinition(SimpleType otherSimpleType) { if (otherSimpleType == null) return nameof(otherSimpleType); if (MaxLength != otherSimpleType.MaxLength) return ("MaxLength"); if (!string.Equals(BaseType, otherSimpleType.BaseType, StringComparison.Ordinal)) return ("BaseType"); if ((BaseSimpleType != null && otherSimpleType.BaseSimpleType != null) && (BaseSimpleType.HasConflictingDefinition(otherSimpleType.BaseSimpleType)).Length != 0) return ("BaseSimpleType"); return string.Empty; } // only string types can have MaxLength internal bool CanHaveMaxLength() { SimpleType rootType = this; while (rootType.BaseSimpleType != null) { rootType = rootType.BaseSimpleType; } return string.Equals(rootType.BaseType, "string", StringComparison.OrdinalIgnoreCase); } internal void ConvertToAnnonymousSimpleType() { _name = null; _ns = string.Empty; SimpleType tmpSimpleType = this; while (tmpSimpleType._baseSimpleType != null) { tmpSimpleType = tmpSimpleType._baseSimpleType; } _baseType = tmpSimpleType._baseType; _baseSimpleType = tmpSimpleType._baseSimpleType; _xmlBaseType = tmpSimpleType._xmlBaseType; } } }