From 6b1eb179d8353628d9ce3f03b6389cdc935e4649 Mon Sep 17 00:00:00 2001 From: samatstarion Date: Sun, 9 Nov 2025 17:33:39 +0100 Subject: [PATCH 1/5] [Refactor] reading xml attributes, set properties to a default value when an overflow exception on XmlConvert is handled; fixes #60 [Update] all int properties to long to harmonize integer properties; as per ReqIF specification integers are mathematically unbounded integer. Practically long is a useful type [Improve] logging when element not know -> include LineNumber and LinePosition --- ReqIFSharp/AccessControlledElement.cs | 26 ++++- .../AttributeDefinitionBoolean.cs | 8 +- .../AttributeDefinitionDate.cs | 8 +- .../AttributeDefinitionEnumeration.cs | 50 +++++--- .../AttributeDefinitionInteger.cs | 8 +- .../AttributeDefinitionReal.cs | 8 +- .../AttributeDefinitionString.cs | 8 +- .../AttributeDefinitionXHTML.cs | 8 +- ReqIFSharp/AttributeValue/AttributeValue.cs | 4 +- .../AttributeValue/AttributeValueBoolean.cs | 58 ++++++++-- .../AttributeValue/AttributeValueDate.cs | 57 +++++++-- .../AttributeValueEnumeration.cs | 8 +- .../AttributeValue/AttributeValueInteger.cs | 58 ++++++++-- .../AttributeValue/AttributeValueReal.cs | 57 +++++++-- .../AttributeValue/AttributeValueString.cs | 17 ++- .../AttributeValue/AttributeValueXHTML.cs | 47 ++++++-- .../Datatype/DatatypeDefinitionEnumeration.cs | 8 +- .../Datatype/DatatypeDefinitionInteger.cs | 82 ++++++++++--- ReqIFSharp/Datatype/DatatypeDefinitionReal.cs | 108 +++++++++++++----- .../Datatype/DatatypeDefinitionSimple.cs | 2 +- .../Datatype/DatatypeDefinitionString.cs | 64 ++++++++--- ReqIFSharp/Datatype/EmbeddedValue.cs | 49 +++++++- ReqIFSharp/Identifiable.cs | 23 +++- ReqIFSharp/ReqIF.cs | 8 +- ReqIFSharp/ReqIFContent.cs | 12 +- ReqIFSharp/ReqIFHeader.cs | 56 +++++++-- .../RelationGroup.cs | 8 +- .../SpecElementWithAttributes.cs | 8 +- .../SpecHierarchy.cs | 10 +- .../SpecElementWithAttributes/SpecRelation.cs | 8 +- ReqIFSharp/SpecType/SpecType.cs | 8 +- 31 files changed, 697 insertions(+), 187 deletions(-) diff --git a/ReqIFSharp/AccessControlledElement.cs b/ReqIFSharp/AccessControlledElement.cs index 6454edc..c186d13 100644 --- a/ReqIFSharp/AccessControlledElement.cs +++ b/ReqIFSharp/AccessControlledElement.cs @@ -20,22 +20,31 @@ namespace ReqIFSharp { + using System; + using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The is the base class for classes that may restrict user access to their information. /// public abstract class AccessControlledElement : Identifiable { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class /// protected AccessControlledElement() { + this.logger = NullLogger.Instance; } /// @@ -47,6 +56,7 @@ protected AccessControlledElement() protected AccessControlledElement(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -68,11 +78,21 @@ internal override void ReadXml(XmlReader reader) { base.ReadXml(reader); - var isEditable = reader.GetAttribute("IS-EDITABLE"); + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading IS-EDITABLE at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - if (isEditable != null) + var isEditable = reader.GetAttribute("IS-EDITABLE"); + if (!string.IsNullOrWhiteSpace(isEditable)) { - this.IsEditable = XmlConvert.ToBoolean(isEditable); + try + { + this.IsEditable = XmlConvert.ToBoolean(isEditable); + } + catch (Exception e) + { + throw new SerializationException($"The AccessControlledElement.IS-EDITABLE {isEditable} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a BOOLEAN", e); + } } } diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionBoolean.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionBoolean.cs index a6bffbb..76e47f7 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionBoolean.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionBoolean.cs @@ -137,6 +137,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -162,7 +164,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -191,6 +193,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -216,7 +220,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionDate.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionDate.cs index 4cf102f..3a29c66 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionDate.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionDate.cs @@ -138,6 +138,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -162,7 +164,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -191,6 +193,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -215,7 +219,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionEnumeration.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionEnumeration.cs index 4009a98..ba8c807 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionEnumeration.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionEnumeration.cs @@ -22,8 +22,8 @@ namespace ReqIFSharp { using System; using System.Linq; - using System.Threading; using System.Runtime.Serialization; + using System.Threading; using System.Threading.Tasks; using System.Xml; @@ -31,7 +31,7 @@ namespace ReqIFSharp using Microsoft.Extensions.Logging.Abstractions; /// - /// The purpose of the class is to define a enumeration attribute. + /// The purpose of the class is to define an enumeration attribute. /// /// /// An element relates an element to a @@ -130,7 +130,7 @@ protected override void SetDatatypeDefinition(DatatypeDefinition datatypeDefinit /// If set to true, this means that the user of a requirements authoring tool can pick one or more than one of the values in /// the set of specified values as an enumeration attribute value. /// - /// + /// /// If set to false, this means that the user of a requirements authoring tool can pick exactly one of the values in the set of /// specified values as an enumeration attribute value. /// @@ -146,15 +146,14 @@ internal override void ReadXml(XmlReader reader) { base.ReadXml(reader); - if (reader.GetAttribute("MULTI-VALUED") == "true") - { - this.IsMultiValued = true; - } + this.ReadXmlAttributes(reader); while (reader.Read()) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -180,7 +179,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -200,10 +199,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to { base.ReadXml(reader); - if (reader.GetAttribute("MULTI-VALUED") == "true") - { - this.IsMultiValued = true; - } + this.ReadXmlAttributes(reader); while (await reader.ReadAsync()) { @@ -214,6 +210,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -239,13 +237,39 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } } } + /// + /// Reads the properties that are defined as XML Attributes (MULTI-VALUED) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading MULTI-VALUED at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var multiValuedValue = reader.GetAttribute("MULTI-VALUED"); + if (!string.IsNullOrWhiteSpace(multiValuedValue)) + { + try + { + this.IsMultiValued = XmlConvert.ToBoolean(multiValuedValue); + } + catch (Exception e) + { + throw new SerializationException($"The AttributeDefinitionEnumeration.MULTI-VALUED {multiValuedValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a BOOLEAN", e); + } + } + } + /// /// Converts a object into its XML representation. /// diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionInteger.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionInteger.cs index b126bb4..93306b3 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionInteger.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionInteger.cs @@ -139,6 +139,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -164,7 +166,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -193,6 +195,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -218,7 +222,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionReal.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionReal.cs index 3c9ed4e..a9f658b 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionReal.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionReal.cs @@ -138,6 +138,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -163,7 +165,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -192,6 +194,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -217,7 +221,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionString.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionString.cs index 062adb0..76e0a27 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionString.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionString.cs @@ -137,6 +137,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -162,7 +164,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -191,6 +193,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -216,7 +220,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeDefinition/AttributeDefinitionXHTML.cs b/ReqIFSharp/AttributeDefinition/AttributeDefinitionXHTML.cs index 7b745d4..fb94a88 100644 --- a/ReqIFSharp/AttributeDefinition/AttributeDefinitionXHTML.cs +++ b/ReqIFSharp/AttributeDefinition/AttributeDefinitionXHTML.cs @@ -137,6 +137,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -162,7 +164,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -191,6 +193,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -216,7 +220,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeValue/AttributeValue.cs b/ReqIFSharp/AttributeValue/AttributeValue.cs index 7f7b25d..3ac1b2b 100644 --- a/ReqIFSharp/AttributeValue/AttributeValue.cs +++ b/ReqIFSharp/AttributeValue/AttributeValue.cs @@ -113,7 +113,7 @@ public AttributeDefinition AttributeDefinition public abstract object ObjectValue { get; set; } /// - /// Gets the from the sub class + /// Gets the from the subclass /// /// /// an instance of @@ -121,7 +121,7 @@ public AttributeDefinition AttributeDefinition protected abstract AttributeDefinition GetAttributeDefinition(); /// - /// Sets the to the sub class + /// Sets the to the subclass /// /// /// The to set. diff --git a/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs b/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs index 02777be..3943ede 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs @@ -28,17 +28,24 @@ namespace ReqIFSharp using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The purpose of the class is to define a attribute value. /// public class AttributeValueBoolean : AttributeValueSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public AttributeValueBoolean() { + this.logger = NullLogger.Instance; } /// @@ -49,6 +56,7 @@ public AttributeValueBoolean() /// public AttributeValueBoolean(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -64,6 +72,8 @@ public AttributeValueBoolean(ILoggerFactory loggerFactory) : base(loggerFactory) internal AttributeValueBoolean(AttributeDefinitionBoolean attributeDefinition, ILoggerFactory loggerFactory) : base(attributeDefinition, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); + this.OwningDefinition = attributeDefinition; } @@ -79,6 +89,7 @@ internal AttributeValueBoolean(AttributeDefinitionBoolean attributeDefinition, I internal AttributeValueBoolean(SpecElementWithAttributes specElAt, ILoggerFactory loggerFactory) : base(specElAt, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -156,12 +167,7 @@ protected override void SetAttributeDefinition(AttributeDefinition attributeDefi /// internal override void ReadXml(XmlReader reader) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToBoolean(value); - } + this.ReadXmlAttributes(reader); while (reader.Read()) { @@ -189,12 +195,7 @@ internal override void ReadXml(XmlReader reader) /// internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToBoolean(value); - } + this.ReadXmlAttributes(reader); while (await reader.ReadAsync()) { @@ -216,6 +217,39 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } } + /// + /// Reads the properties that are defined as XML Attributes (THE-VALUE) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading THE-VALUE at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var theValue = reader.GetAttribute("THE-VALUE"); + if (!string.IsNullOrWhiteSpace(theValue)) + { + try + { + this.TheValue = XmlConvert.ToBoolean(theValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The AttributeValueBoolean.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to false", + theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.TheValue = default; + } + catch (Exception e) + { + throw new SerializationException($"The AttributeValueBoolean.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a BOOLEAN", e); + } + } + } + /// /// Converts a object into its XML representation. /// diff --git a/ReqIFSharp/AttributeValue/AttributeValueDate.cs b/ReqIFSharp/AttributeValue/AttributeValueDate.cs index 3e216c6..bad9fec 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueDate.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueDate.cs @@ -29,17 +29,24 @@ namespace ReqIFSharp using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The purpose of the class is to define a attribute value. /// public class AttributeValueDate : AttributeValueSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public AttributeValueDate() { + this.logger = NullLogger.Instance; } /// @@ -55,6 +62,8 @@ public AttributeValueDate() internal AttributeValueDate(AttributeDefinitionDate attributeDefinition, ILoggerFactory loggerFactory) : base(attributeDefinition, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); + this.OwningDefinition = attributeDefinition; } @@ -70,6 +79,7 @@ internal AttributeValueDate(AttributeDefinitionDate attributeDefinition, ILogger internal AttributeValueDate(SpecElementWithAttributes specElAt, ILoggerFactory loggerFactory) : base(specElAt, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -147,13 +157,8 @@ protected override void SetAttributeDefinition(AttributeDefinition attributeDefi /// internal override void ReadXml(XmlReader reader) { - var value = reader["THE-VALUE"]; + this.ReadXmlAttributes(reader); - if (value != null) - { - this.TheValue = XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.RoundtripKind); - } - while (reader.Read()) { if (reader.ReadToDescendant("ATTRIBUTE-DEFINITION-DATE-REF")) @@ -180,12 +185,7 @@ internal override void ReadXml(XmlReader reader) /// internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.RoundtripKind); - } + this.ReadXmlAttributes(reader); while (await reader.ReadAsync()) { @@ -207,6 +207,39 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } } + /// + /// Reads the properties that are defined as XML Attributes (THE-VALUE) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading THE-VALUE at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var theValue = reader.GetAttribute("THE-VALUE"); + if (!string.IsNullOrWhiteSpace(theValue)) + { + try + { + this.TheValue = XmlConvert.ToDateTime(theValue, XmlDateTimeSerializationMode.RoundtripKind); + } + catch (OverflowException) + { + this.logger.LogWarning("The AttributeValueDate.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to DateTime.MinValue", + theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.TheValue = default; + } + catch (Exception e) + { + throw new SerializationException($"The AttributeValueDate.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); + } + } + } + /// /// Converts a object into its XML representation. /// diff --git a/ReqIFSharp/AttributeValue/AttributeValueEnumeration.cs b/ReqIFSharp/AttributeValue/AttributeValueEnumeration.cs index e048a9b..e96e8e0 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueEnumeration.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueEnumeration.cs @@ -180,6 +180,8 @@ internal override void ReadXml(XmlReader reader) { if (subtree.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + string reference; switch (subtree.LocalName) @@ -203,7 +205,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", subtree.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", subtree.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -233,6 +235,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await subtree.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + string reference; switch (subtree.LocalName) @@ -256,7 +260,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } break; default: - this.logger.LogWarning("The {LocalName} is not supported", subtree.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", subtree.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/AttributeValue/AttributeValueInteger.cs b/ReqIFSharp/AttributeValue/AttributeValueInteger.cs index 12af668..afe2392 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueInteger.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueInteger.cs @@ -29,6 +29,7 @@ namespace ReqIFSharp using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The purpose of the class is to define an Integer attribute value. @@ -38,11 +39,17 @@ namespace ReqIFSharp /// public class AttributeValueInteger : AttributeValueSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public AttributeValueInteger() { + this.logger = NullLogger.Instance; } /// @@ -53,6 +60,7 @@ public AttributeValueInteger() /// public AttributeValueInteger(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -68,6 +76,8 @@ public AttributeValueInteger(ILoggerFactory loggerFactory) : base(loggerFactory) internal AttributeValueInteger(AttributeDefinitionInteger attributeDefinition, ILoggerFactory loggerFactory) : base(attributeDefinition, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); + this.OwningDefinition = attributeDefinition; } @@ -83,6 +93,7 @@ internal AttributeValueInteger(AttributeDefinitionInteger attributeDefinition, I internal AttributeValueInteger(SpecElementWithAttributes specElAt, ILoggerFactory loggerFactory) : base(specElAt, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -160,12 +171,7 @@ protected override void SetAttributeDefinition(AttributeDefinition attributeDefi /// internal override void ReadXml(XmlReader reader) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToInt64(value); - } + this.ReadXmlAttributes(reader); while (reader.Read()) { @@ -193,12 +199,7 @@ internal override void ReadXml(XmlReader reader) /// internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToInt64(value); - } + this.ReadXmlAttributes(reader); while (await reader.ReadAsync()) { @@ -220,6 +221,39 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } } + /// + /// Reads the properties that are defined as XML Attributes (THE-VALUE) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading THE-VALUE at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var theValue = reader.GetAttribute("THE-VALUE"); + if (!string.IsNullOrWhiteSpace(theValue)) + { + try + { + this.TheValue = XmlConvert.ToInt64(theValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The AttributeValueInteger.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to 0", + theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.TheValue = default; + } + catch (Exception e) + { + throw new SerializationException($"The AttributeValueInteger.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to an INTEGER", e); + } + } + } + /// /// Converts a object into its XML representation. /// diff --git a/ReqIFSharp/AttributeValue/AttributeValueReal.cs b/ReqIFSharp/AttributeValue/AttributeValueReal.cs index 8962cde..0f3c2fc 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueReal.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueReal.cs @@ -36,11 +36,17 @@ namespace ReqIFSharp /// public class AttributeValueReal : AttributeValueSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public AttributeValueReal() { + this.logger = NullLogger.Instance; } /// @@ -51,6 +57,7 @@ public AttributeValueReal() /// public AttributeValueReal(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -66,6 +73,8 @@ public AttributeValueReal(ILoggerFactory loggerFactory) : base(loggerFactory) internal AttributeValueReal(AttributeDefinitionReal attributeDefinition, ILoggerFactory loggerFactory) : base(attributeDefinition, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); + this.OwningDefinition = attributeDefinition; } @@ -81,6 +90,7 @@ internal AttributeValueReal(AttributeDefinitionReal attributeDefinition, ILogger internal AttributeValueReal(SpecElementWithAttributes specElAt, ILoggerFactory loggerFactory) : base(specElAt, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -158,12 +168,7 @@ protected override void SetAttributeDefinition(AttributeDefinition attributeDefi /// internal override void ReadXml(XmlReader reader) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToDouble(value); - } + this.ReadXmlAttributes(reader); while (reader.Read()) { @@ -191,12 +196,7 @@ internal override void ReadXml(XmlReader reader) /// internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { - var value = reader["THE-VALUE"]; - - if (value != null) - { - this.TheValue = XmlConvert.ToDouble(value); - } + this.ReadXmlAttributes(reader); while (await reader.ReadAsync()) { @@ -218,6 +218,39 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } } + /// + /// Reads the properties that are defined as XML Attributes (THE-VALUE) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading THE-VALUE at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var theValue = reader.GetAttribute("THE-VALUE"); + if (!string.IsNullOrWhiteSpace(theValue)) + { + try + { + this.TheValue = XmlConvert.ToDouble(theValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The AttributeValueReal.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to 0", + theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.TheValue = default; + } + catch (Exception e) + { + throw new SerializationException($"The AttributeValueReal.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a REAL", e); + } + } + } + /// /// Converts a object into its XML representation. /// diff --git a/ReqIFSharp/AttributeValue/AttributeValueString.cs b/ReqIFSharp/AttributeValue/AttributeValueString.cs index 285c413..f5b29ab 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueString.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueString.cs @@ -28,17 +28,24 @@ namespace ReqIFSharp using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The purpose of the class is to define a attribute value. /// public class AttributeValueString : AttributeValueSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public AttributeValueString() { + this.logger = NullLogger.Instance; } /// @@ -49,6 +56,7 @@ public AttributeValueString() /// public AttributeValueString(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -64,6 +72,8 @@ public AttributeValueString(ILoggerFactory loggerFactory) : base(loggerFactory) internal AttributeValueString(AttributeDefinitionString attributeDefinition, ILoggerFactory loggerFactory) : base(attributeDefinition, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); + this.OwningDefinition = attributeDefinition; } @@ -79,6 +89,7 @@ internal AttributeValueString(AttributeDefinitionString attributeDefinition, ILo internal AttributeValueString(SpecElementWithAttributes specElAt, ILoggerFactory loggerFactory) : base(specElAt, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -148,8 +159,7 @@ protected override void SetAttributeDefinition(AttributeDefinition attributeDefi /// internal override void ReadXml(XmlReader reader) { - var value = reader["THE-VALUE"]; - this.TheValue = value; + this.TheValue = reader.GetAttribute("THE-VALUE"); while (reader.Read()) { @@ -177,8 +187,7 @@ internal override void ReadXml(XmlReader reader) /// internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { - var value = reader["THE-VALUE"]; - this.TheValue = value; + this.TheValue = reader.GetAttribute("THE-VALUE"); while (await reader.ReadAsync()) { diff --git a/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs b/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs index 6cbfd32..69c6c61 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs @@ -229,11 +229,7 @@ public string ExtractUnformattedTextFromValue() /// internal override void ReadXml(XmlReader reader) { - var isSimplified = reader["IS-SIMPLIFIED"]; - if (!string.IsNullOrEmpty(isSimplified)) - { - this.IsSimplified = XmlConvert.ToBoolean(isSimplified); - } + this.ReadXmlAttributes(reader); using (var subtree = reader.ReadSubtree()) { @@ -274,12 +270,8 @@ internal override void ReadXml(XmlReader reader) /// internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { - var isSimplified = reader["IS-SIMPLIFIED"]; - if (!string.IsNullOrEmpty(isSimplified)) - { - this.IsSimplified = XmlConvert.ToBoolean(isSimplified); - } - + this.ReadXmlAttributes(reader); + using (var subtree = reader.ReadSubtree()) { while (await subtree.ReadAsync()) @@ -313,6 +305,39 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to } } + /// + /// Reads the properties that are defined as XML Attributes (IS-SIMPLIFIED) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading IS-SIMPLIFIED at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var isSimplified = reader.GetAttribute("IS-SIMPLIFIED"); + if (!string.IsNullOrWhiteSpace(isSimplified)) + { + try + { + this.IsSimplified = XmlConvert.ToBoolean(isSimplified); + } + catch (OverflowException) + { + this.logger.LogWarning("The AttributeValueXHTML.IS-SIMPLIFIED: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. IsSimplified is set to false", + isSimplified, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.IsSimplified = default; + } + catch (Exception e) + { + throw new SerializationException($"The AttributeValueXHTML.IS-SIMPLIFIED {isSimplified} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a BOOLEAN", e); + } + } + } + /// /// Creates s from provided XHTML /// diff --git a/ReqIFSharp/Datatype/DatatypeDefinitionEnumeration.cs b/ReqIFSharp/Datatype/DatatypeDefinitionEnumeration.cs index b6db7da..2fe8297 100644 --- a/ReqIFSharp/Datatype/DatatypeDefinitionEnumeration.cs +++ b/ReqIFSharp/Datatype/DatatypeDefinitionEnumeration.cs @@ -105,6 +105,8 @@ internal override void ReadXml(XmlReader reader) { if (subtree.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (subtree.LocalName) { case "ALTERNATIVE-ID": @@ -115,7 +117,7 @@ internal override void ReadXml(XmlReader reader) enumValue.ReadXml(subtree); break; default: - this.logger.LogWarning("The {LocalName} is not supported", subtree.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", subtree.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -152,6 +154,8 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to if (await subtree.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (subtree.LocalName) { case "ALTERNATIVE-ID": @@ -162,7 +166,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to await enumValue.ReadXmlAsync(subtree, token); break; default: - this.logger.LogWarning("The {LocalName} is not supported", subtree.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", subtree.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/Datatype/DatatypeDefinitionInteger.cs b/ReqIFSharp/Datatype/DatatypeDefinitionInteger.cs index 1a71260..e531600 100644 --- a/ReqIFSharp/Datatype/DatatypeDefinitionInteger.cs +++ b/ReqIFSharp/Datatype/DatatypeDefinitionInteger.cs @@ -20,11 +20,14 @@ namespace ReqIFSharp { + using System; + using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The purpose of the class is to define the primitive Integer data type @@ -32,15 +35,21 @@ namespace ReqIFSharp /// /// This element defines a data type for the representation of Integer data values in the Exchange Document. /// The representation of data values shall comply with the definitions in http://www.w3.org/TR/xmlschema-2/#integer - /// ReqIfSharp supports 64 bit signed integers (long) with the following range: -9223372036854775808 to 9223372036854775807 + /// ReqIfSharp supports 64-bit signed integers (long) with the following range: -9223372036854775808 to 9223372036854775807 /// public class DatatypeDefinitionInteger : DatatypeDefinitionSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public DatatypeDefinitionInteger() { + this.logger = NullLogger.Instance; } /// @@ -52,6 +61,7 @@ public DatatypeDefinitionInteger() public DatatypeDefinitionInteger(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -66,6 +76,7 @@ public DatatypeDefinitionInteger(ILoggerFactory loggerFactory) internal DatatypeDefinitionInteger(ReqIFContent reqIfContent, ILoggerFactory loggerFactory) : base(reqIfContent, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -88,17 +99,7 @@ internal override void ReadXml(XmlReader reader) { base.ReadXml(reader); - var maxValue = reader.GetAttribute("MAX"); - if (!string.IsNullOrEmpty(maxValue)) - { - this.Max = XmlConvert.ToInt64(maxValue); - } - - var minValue = reader.GetAttribute("MIN"); - if (!string.IsNullOrEmpty(minValue)) - { - this.Min = XmlConvert.ToInt64(minValue); - } + this.ReadXmlAttributes(reader); this.ReadAlternativeId(reader); } @@ -116,19 +117,64 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to { base.ReadXml(reader); + this.ReadXmlAttributes(reader); + + await this.ReadAlternativeIdAsync(reader, token); + } + + /// + /// Reads the properties that are defined as XML Attributes (MAX, MIN) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading MAX at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + var maxValue = reader.GetAttribute("MAX"); - if (!string.IsNullOrEmpty(maxValue)) + if (!string.IsNullOrWhiteSpace(maxValue)) { - this.Max = XmlConvert.ToInt64(maxValue); + try + { + this.Max = XmlConvert.ToInt64(maxValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The DatatypeDefinitionInteger.MAX: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Max is set to Int64.MaxValue", + maxValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.Max = long.MaxValue; + } + catch (Exception e) + { + throw new SerializationException($"The DatatypeDefinitionInteger.MAX {maxValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to an INTEGER", e); + } } + this.logger.LogTrace("reading MIN at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + var minValue = reader.GetAttribute("MIN"); - if (!string.IsNullOrEmpty(minValue)) + if (!string.IsNullOrWhiteSpace(minValue)) { - this.Min = XmlConvert.ToInt64(minValue); + try + { + this.Min = XmlConvert.ToInt64(minValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The DatatypeDefinitionInteger.MIN: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Min is set to Int64.MinValue", + minValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.Min = long.MinValue; + } + catch (Exception e) + { + throw new SerializationException($"The DatatypeDefinitionInteger.MIN {minValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to an INTEGER", e); + } } - - await this.ReadAlternativeIdAsync(reader, token); } /// diff --git a/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs b/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs index e129ef1..a4b3fd1 100644 --- a/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs +++ b/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs @@ -20,22 +20,31 @@ namespace ReqIFSharp { + using System; + using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// This element defines a data type for the representation of Real data values in the Exchange Document. /// public class DatatypeDefinitionReal : DatatypeDefinitionSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public DatatypeDefinitionReal() { + this.logger = NullLogger.Instance; } /// @@ -47,6 +56,7 @@ public DatatypeDefinitionReal() public DatatypeDefinitionReal(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -61,12 +71,13 @@ public DatatypeDefinitionReal(ILoggerFactory loggerFactory) internal DatatypeDefinitionReal(ReqIFContent reqIfContent, ILoggerFactory loggerFactory) : base(reqIfContent, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// /// Gets or sets a value that Denotes the supported maximum precision of real numbers represented by this data type. /// - public int Accuracy { get; set; } + public long Accuracy { get; set; } /// /// Gets or sets a value that denotes the largest negative data value representable by this data type. @@ -88,23 +99,7 @@ internal override void ReadXml(XmlReader reader) { base.ReadXml(reader); - var accuracyValue = reader.GetAttribute("ACCURACY"); - if (!string.IsNullOrEmpty(accuracyValue)) - { - this.Accuracy = XmlConvert.ToInt32(accuracyValue); - } - - var maxValue = reader.GetAttribute("MAX"); - if (!string.IsNullOrEmpty(maxValue)) - { - this.Max = XmlConvert.ToDouble(maxValue); - } - - var minValue = reader.GetAttribute("MIN"); - if (!string.IsNullOrEmpty(minValue)) - { - this.Min = XmlConvert.ToDouble(minValue); - } + this.ReadXmlAttributes(reader); this.ReadAlternativeId(reader); } @@ -122,25 +117,86 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to { base.ReadXml(reader); + this.ReadXmlAttributes(reader); + + await this.ReadAlternativeIdAsync(reader, token); + } + + /// + /// Reads the properties that are defined as XML Attributes (ACCURACY, MAX, MIN) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading DatatypeDefinitionReal.ACCURACY at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + var accuracyValue = reader.GetAttribute("ACCURACY"); - if (!string.IsNullOrEmpty(accuracyValue)) + if (!string.IsNullOrWhiteSpace(accuracyValue)) { - this.Accuracy = XmlConvert.ToInt32(accuracyValue); + try + { + this.Accuracy = XmlConvert.ToInt64(accuracyValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The DatatypeDefinitionReal.ACCURACY: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Accuracy is set to Int64.MaxValue", + accuracyValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.Accuracy = long.MaxValue; + } + catch (Exception e) + { + throw new SerializationException($"The DatatypeDefinitionReal.ACCURACY {accuracyValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to an INTEGER", e); + } } + this.logger.LogTrace("reading DatatypeDefinitionReal.MAX at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + var maxValue = reader.GetAttribute("MAX"); - if (!string.IsNullOrEmpty(maxValue)) + if (!string.IsNullOrWhiteSpace(maxValue)) { - this.Max = XmlConvert.ToDouble(maxValue); + try + { + this.Max = XmlConvert.ToDouble(maxValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The DatatypeDefinitionReal.MAX: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Max is set to Int64.MaxValue", + maxValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.Max = double.MaxValue; + } + catch (Exception e) + { + throw new SerializationException($"The DatatypeDefinitionReal.MAX {maxValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a REAL", e); + } } + this.logger.LogTrace("reading DatatypeDefinitionReal.MIN at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + var minValue = reader.GetAttribute("MIN"); - if (!string.IsNullOrEmpty(minValue)) + if (!string.IsNullOrWhiteSpace(minValue)) { - this.Min = XmlConvert.ToDouble(minValue); + try + { + this.Min = XmlConvert.ToDouble(minValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The DatatypeDefinitionReal.MIN: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Min is set to Int64.MinValue", + minValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.Min = double.MinValue; + } + catch (Exception e) + { + throw new SerializationException($"The DatatypeDefinitionReal.MIN {minValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a REAL", e); + } } - - await this.ReadAlternativeIdAsync(reader, token); } /// diff --git a/ReqIFSharp/Datatype/DatatypeDefinitionSimple.cs b/ReqIFSharp/Datatype/DatatypeDefinitionSimple.cs index 276b5b2..8b656e2 100644 --- a/ReqIFSharp/Datatype/DatatypeDefinitionSimple.cs +++ b/ReqIFSharp/Datatype/DatatypeDefinitionSimple.cs @@ -41,7 +41,7 @@ protected DatatypeDefinitionSimple() /// The (injected) used to set up logging /// protected DatatypeDefinitionSimple(ILoggerFactory loggerFactory) - : base( loggerFactory) + : base(loggerFactory) { } diff --git a/ReqIFSharp/Datatype/DatatypeDefinitionString.cs b/ReqIFSharp/Datatype/DatatypeDefinitionString.cs index 60398d2..aaeba16 100644 --- a/ReqIFSharp/Datatype/DatatypeDefinitionString.cs +++ b/ReqIFSharp/Datatype/DatatypeDefinitionString.cs @@ -20,11 +20,14 @@ namespace ReqIFSharp { + using System; + using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The purpose of the class is to define the primitive data type @@ -34,11 +37,17 @@ namespace ReqIFSharp /// public class DatatypeDefinitionString : DatatypeDefinitionSimple { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public DatatypeDefinitionString() { + this.logger = NullLogger.Instance; } /// @@ -50,6 +59,7 @@ public DatatypeDefinitionString() public DatatypeDefinitionString(ILoggerFactory loggerFactory) : base(loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -64,12 +74,13 @@ public DatatypeDefinitionString(ILoggerFactory loggerFactory) internal DatatypeDefinitionString(ReqIFContent reqIfContent, ILoggerFactory loggerFactory) : base(reqIfContent, loggerFactory) { + this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// /// Gets or sets the maximum permissible string length - /// - public int MaxLength { get; set; } + /// + public long MaxLength { get; set; } /// /// Generates a object from its XML representation. @@ -78,14 +89,10 @@ internal DatatypeDefinitionString(ReqIFContent reqIfContent, ILoggerFactory logg /// an instance of /// internal override void ReadXml(XmlReader reader) - { + { base.ReadXml(reader); - var value = reader.GetAttribute("MAX-LENGTH"); - if ( !string.IsNullOrEmpty(value)) - { - this.MaxLength = XmlConvert.ToInt32(value); - } + this.ReadXmlAttributes(reader); this.ReadAlternativeId(reader); } @@ -103,15 +110,44 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to { base.ReadXml(reader); - var value = reader.GetAttribute("MAX-LENGTH"); - if (!string.IsNullOrEmpty(value)) - { - this.MaxLength = XmlConvert.ToInt32(value); - } + this.ReadXmlAttributes(reader); await this.ReadAlternativeIdAsync(reader, token); } + /// + /// Reads the properties that are defined as XML Attributes (MAX-LENGTH) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading MAX-LENGTH at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var maxLength = reader.GetAttribute("MAX-LENGTH"); + if (!string.IsNullOrWhiteSpace(maxLength)) + { + try + { + this.MaxLength = XmlConvert.ToInt64(maxLength); + } + catch (OverflowException) + { + this.logger.LogWarning("The DatatypeDefinitionString.MAX-LENGTH: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. MaxLength is set to Int64.MaxValue", + maxLength, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.MaxLength = long.MaxValue; + } + catch (Exception e) + { + throw new SerializationException($"The DatatypeDefinitionString.MAX-LENGTH: {maxLength} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to an INTEGER", e); + } + } + } + /// /// Converts a object into its XML representation. /// @@ -119,7 +155,7 @@ internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken to /// an instance of /// internal override void WriteXml(XmlWriter writer) - { + { writer.WriteAttributeString("MAX-LENGTH", XmlConvert.ToString(this.MaxLength)); base.WriteXml(writer); diff --git a/ReqIFSharp/Datatype/EmbeddedValue.cs b/ReqIFSharp/Datatype/EmbeddedValue.cs index 283ab49..dc871ae 100644 --- a/ReqIFSharp/Datatype/EmbeddedValue.cs +++ b/ReqIFSharp/Datatype/EmbeddedValue.cs @@ -20,22 +20,31 @@ namespace ReqIFSharp { + using System; + using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; /// /// The class represents additional information related to enumeration literals. /// public class EmbeddedValue { + /// + /// The used to log + /// + private readonly ILogger logger; + /// /// Initializes a new instance of the class. /// public EmbeddedValue() { + this.logger = NullLogger.Instance; } /// @@ -49,6 +58,8 @@ public EmbeddedValue() /// internal EmbeddedValue(EnumValue enumValue, ILoggerFactory loggerFactory) { + this.logger = loggerFactory == null ? NullLogger.Instance : loggerFactory.CreateLogger(); + this.EnumValue = enumValue; this.EnumValue.Properties = this; } @@ -56,7 +67,7 @@ internal EmbeddedValue(EnumValue enumValue, ILoggerFactory loggerFactory) /// /// Gets or sets the numerical value corresponding to the enumeration literal. /// - public int Key { get; set; } + public long Key { get; set; } /// /// Gets or sets Arbitrary additional information related to the enumeration literal. @@ -79,13 +90,43 @@ internal EmbeddedValue(EnumValue enumValue, ILoggerFactory loggerFactory) /// internal void ReadXml(XmlReader reader) { - var key = reader.GetAttribute("KEY"); + this.ReadXmlAttributes(reader); + } - if (key != null) + /// + /// Reads the properties that are defined as XML Attributes (KEY, OTHER-CONTENT) + /// + /// + /// an instance of + /// + private void ReadXmlAttributes(XmlReader reader) + { + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("reading KEY at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + var keyValue = reader.GetAttribute("KEY"); + if (!string.IsNullOrWhiteSpace(keyValue)) { - this.Key = XmlConvert.ToInt32(key); + try + { + this.Key = XmlConvert.ToInt64(keyValue); + } + catch (OverflowException) + { + this.logger.LogWarning("The EmbeddedValue.KEY: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Key is set to 0 (default)", + keyValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.Key = default; + } + catch (Exception e) + { + throw new SerializationException($"The EmbeddedValue.KEY {keyValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to an INTEGER", e); + } } + this.logger.LogTrace("reading OTHER-CONTENT at line:position {LineNumber}:{LinePosition}", xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + this.OtherContent = reader.GetAttribute("OTHER-CONTENT"); } diff --git a/ReqIFSharp/Identifiable.cs b/ReqIFSharp/Identifiable.cs index d42861d..34259f2 100644 --- a/ReqIFSharp/Identifiable.cs +++ b/ReqIFSharp/Identifiable.cs @@ -117,10 +117,29 @@ internal virtual void ReadXml(XmlReader reader) { this.Identifier = reader.GetAttribute("IDENTIFIER"); - this.logger.LogTrace("read xml of {Typename}:{Identifier}", this.GetType().Name, this.Identifier); + var xmlLineInfo = reader as IXmlLineInfo; + + this.logger.LogTrace("read xml of {Typename}:{Identifier} at line:position {LineNumber}:{LinePosition}", this.GetType().Name, this.Identifier, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); var lastChange = reader.GetAttribute("LAST-CHANGE"); - this.LastChange = XmlConvert.ToDateTime(lastChange, XmlDateTimeSerializationMode.RoundtripKind); + if (!string.IsNullOrWhiteSpace(lastChange)) + { + try + { + this.LastChange = XmlConvert.ToDateTime(lastChange, XmlDateTimeSerializationMode.RoundtripKind); + } + catch (OverflowException) + { + this.logger.LogWarning("The Identifiable.LAST-CHANGE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. LAST-CHANGE is set to DateTime.MinValue", + lastChange, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.LastChange = default; + } + catch (Exception e) + { + throw new SerializationException($"The Identifiable.LAST-CHANGE {lastChange} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); + } + } this.Description = reader.GetAttribute("DESC"); this.LongName = reader.GetAttribute("LONG-NAME"); diff --git a/ReqIFSharp/ReqIF.cs b/ReqIFSharp/ReqIF.cs index 5232bce..e01b29d 100644 --- a/ReqIFSharp/ReqIF.cs +++ b/ReqIFSharp/ReqIF.cs @@ -122,6 +122,8 @@ internal void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "THE-HEADER": @@ -150,7 +152,7 @@ internal void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -199,6 +201,8 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "THE-HEADER": @@ -227,7 +231,7 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/ReqIFContent.cs b/ReqIFSharp/ReqIFContent.cs index 89e08a8..c4497c0 100644 --- a/ReqIFSharp/ReqIFContent.cs +++ b/ReqIFSharp/ReqIFContent.cs @@ -97,12 +97,12 @@ internal ReqIFContent(ILoggerFactory loggerFactory) /// /// Gets the s - /// + /// public List DataTypes => this.dataTypes; /// /// Gets the s - /// + /// public List SpecTypes => this.specTypes; /// @@ -142,6 +142,8 @@ internal void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "DATATYPES": @@ -187,7 +189,7 @@ internal void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -214,6 +216,8 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "DATATYPES": @@ -259,7 +263,7 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/ReqIFHeader.cs b/ReqIFSharp/ReqIFHeader.cs index d5c6dcb..4fb4271 100644 --- a/ReqIFSharp/ReqIFHeader.cs +++ b/ReqIFSharp/ReqIFHeader.cs @@ -20,14 +20,14 @@ namespace ReqIFSharp { + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; using System; + using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using System.Xml; - using Microsoft.Extensions.Logging; - using Microsoft.Extensions.Logging.Abstractions; - /// /// The class holds metadata relevant to a ReqIF Exchange Document content. /// @@ -129,6 +129,8 @@ internal void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "REQ-IF-HEADER": @@ -138,7 +140,25 @@ internal void ReadXml(XmlReader reader) this.Comment = reader.ReadElementContentAsString(); break; case "CREATION-TIME": - this.CreationTime = XmlConvert.ToDateTime(reader.ReadElementContentAsString(), XmlDateTimeSerializationMode.RoundtripKind); + var creationTimeValue = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(creationTimeValue)) + { + try + { + this.CreationTime = XmlConvert.ToDateTime(creationTimeValue, XmlDateTimeSerializationMode.RoundtripKind); + } + catch (OverflowException) + { + this.logger.LogWarning("The ReqIFHeader.CREATION-TIME: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to ReqIFHeader.CREATION-TIME", + creationTimeValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.CreationTime = default; + } + catch (Exception e) + { + throw new SerializationException($"The ReqIFHeader.CREATION-TIME {creationTimeValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); + } + } break; case "REPOSITORY-ID": this.RepositoryId = reader.ReadElementContentAsString(); @@ -156,7 +176,7 @@ internal void ReadXml(XmlReader reader) this.Title = reader.ReadElementContentAsString(); break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -183,6 +203,8 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "REQ-IF-HEADER": @@ -192,7 +214,25 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) this.Comment = await reader.ReadElementContentAsStringAsync(); break; case "CREATION-TIME": - this.CreationTime = XmlConvert.ToDateTime(await reader.ReadElementContentAsStringAsync(), XmlDateTimeSerializationMode.RoundtripKind); + var creationTimeValue = await reader.ReadElementContentAsStringAsync(); + if (!string.IsNullOrWhiteSpace(creationTimeValue)) + { + try + { + this.CreationTime = XmlConvert.ToDateTime(creationTimeValue, XmlDateTimeSerializationMode.RoundtripKind); + } + catch (OverflowException) + { + this.logger.LogWarning("The ReqIFHeader.CREATION-TIME: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to ReqIFHeader.CREATION-TIME", + creationTimeValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); + + this.CreationTime = default; + } + catch (Exception e) + { + throw new SerializationException($"The ReqIFHeader.CREATION-TIME {creationTimeValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); + } + } break; case "REPOSITORY-ID": this.RepositoryId = await reader.ReadElementContentAsStringAsync(); @@ -210,7 +250,7 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) this.Title = await reader.ReadElementContentAsStringAsync(); break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -268,7 +308,7 @@ internal async Task WriteXmlAsync(XmlWriter writer, CancellationToken token) await writer.WriteElementStringAsync(null, "COMMENT",null, this.Comment); } - await writer.WriteElementStringAsync(null, "CREATION-TIME", null ,XmlConvert.ToString(this.CreationTime, XmlDateTimeSerializationMode.RoundtripKind)); + await writer.WriteElementStringAsync(null, "CREATION-TIME", null, XmlConvert.ToString(this.CreationTime, XmlDateTimeSerializationMode.RoundtripKind)); if (!string.IsNullOrEmpty(this.RepositoryId)) { diff --git a/ReqIFSharp/SpecElementWithAttributes/RelationGroup.cs b/ReqIFSharp/SpecElementWithAttributes/RelationGroup.cs index 3afca44..e66927d 100644 --- a/ReqIFSharp/SpecElementWithAttributes/RelationGroup.cs +++ b/ReqIFSharp/SpecElementWithAttributes/RelationGroup.cs @@ -163,6 +163,8 @@ protected override void ReadObjectSpecificElements(XmlReader reader) if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.Name) { case "SOURCE-SPECIFICATION": @@ -209,7 +211,7 @@ protected override void ReadObjectSpecificElements(XmlReader reader) reader.ReadEndElement(); break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -254,6 +256,8 @@ private async Task ReadObjectSpecificElementsInternalAsync(XmlReader reader, Can { if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.Name) { case "SOURCE-SPECIFICATION": @@ -298,7 +302,7 @@ private async Task ReadObjectSpecificElementsInternalAsync(XmlReader reader, Can reader.ReadEndElement(); break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/SpecElementWithAttributes/SpecElementWithAttributes.cs b/ReqIFSharp/SpecElementWithAttributes/SpecElementWithAttributes.cs index ebb01b4..f267064 100644 --- a/ReqIFSharp/SpecElementWithAttributes/SpecElementWithAttributes.cs +++ b/ReqIFSharp/SpecElementWithAttributes/SpecElementWithAttributes.cs @@ -136,6 +136,8 @@ internal override void ReadXml(XmlReader reader) { while (specElementWithAttributesReader.Read()) { + var xmlLineInfo = reader as IXmlLineInfo; + if (specElementWithAttributesReader.MoveToContent() == XmlNodeType.Element) { switch (specElementWithAttributesReader.LocalName) @@ -214,7 +216,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", specElementWithAttributesReader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", specElementWithAttributesReader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -248,6 +250,8 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) if (await specElementWithAttributesReader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (specElementWithAttributesReader.LocalName) { case "ALTERNATIVE-ID": @@ -324,7 +328,7 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", specElementWithAttributesReader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", specElementWithAttributesReader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/SpecElementWithAttributes/SpecHierarchy.cs b/ReqIFSharp/SpecElementWithAttributes/SpecHierarchy.cs index 35d740d..9cf6bc9 100644 --- a/ReqIFSharp/SpecElementWithAttributes/SpecHierarchy.cs +++ b/ReqIFSharp/SpecElementWithAttributes/SpecHierarchy.cs @@ -178,6 +178,8 @@ internal override void ReadXml(XmlReader reader) { if (specHierarchySubtree.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (specHierarchySubtree.LocalName) { case "ALTERNATIVE-ID": @@ -198,7 +200,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", specHierarchySubtree.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", specHierarchySubtree.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -228,6 +230,8 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -248,7 +252,7 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -319,7 +323,7 @@ internal override async Task WriteXmlAsync(XmlWriter writer, CancellationToken t } /// - /// The initialize. + /// Initializes the properties of the current instance /// /// /// The container. diff --git a/ReqIFSharp/SpecElementWithAttributes/SpecRelation.cs b/ReqIFSharp/SpecElementWithAttributes/SpecRelation.cs index d7a6108..5cef2af 100644 --- a/ReqIFSharp/SpecElementWithAttributes/SpecRelation.cs +++ b/ReqIFSharp/SpecElementWithAttributes/SpecRelation.cs @@ -108,6 +108,8 @@ protected override void ReadObjectSpecificElements(XmlReader reader) if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "SOURCE": @@ -147,7 +149,7 @@ protected override void ReadObjectSpecificElements(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -189,6 +191,8 @@ private async Task ReadObjectSpecificElementsInternalAsync(XmlReader reader) { if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "SOURCE": @@ -228,7 +232,7 @@ private async Task ReadObjectSpecificElementsInternalAsync(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } diff --git a/ReqIFSharp/SpecType/SpecType.cs b/ReqIFSharp/SpecType/SpecType.cs index 2079af5..3e8645f 100644 --- a/ReqIFSharp/SpecType/SpecType.cs +++ b/ReqIFSharp/SpecType/SpecType.cs @@ -112,6 +112,8 @@ internal override void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -130,7 +132,7 @@ internal override void ReadXml(XmlReader reader) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } @@ -159,6 +161,8 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) if (await reader.MoveToContentAsync() == XmlNodeType.Element) { + var xmlLineInfo = reader as IXmlLineInfo; + switch (reader.LocalName) { case "ALTERNATIVE-ID": @@ -183,7 +187,7 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) } break; default: - this.logger.LogWarning("The {LocalName} is not supported", reader.LocalName); + this.logger.LogWarning("The {LocalName} element at line:position {LineNumber}:{LinePosition} is not supported", reader.LocalName, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); break; } } From b6b74dafebc4a2f3d446dc75d0629233d3206c30 Mon Sep 17 00:00:00 2001 From: samatstarion Date: Sun, 9 Nov 2025 18:57:06 +0100 Subject: [PATCH 2/5] [Add] unit tests --- ...tributeDefinitionEnumerationTestFixture.cs | 25 ++- .../AttributeValueBooleanTestFixture.cs | 17 ++ .../AttributeValueDateTestFixture.cs | 38 +++++ .../AttributeValueIntegerTestFixture.cs | 42 ++++- .../AttributeValueRealTestFixture.cs | 39 +++++ .../DatatypeDefinitionIntegerTestFixture.cs | 117 +++++++++++++ .../DatatypeDefinitionRealTestFixture.cs | 156 ++++++++++++++++++ .../DatatypeDefinitionStringTestFixture.cs | 76 +++++++++ .../Datatype/EmbeddedValueTestFixture.cs | 37 ++++- .../AttributeValue/AttributeValueBoolean.cs | 7 - .../AttributeValue/AttributeValueDate.cs | 7 - .../AttributeValue/AttributeValueReal.cs | 7 - .../AttributeValue/AttributeValueXHTML.cs | 7 - ReqIFSharp/Datatype/DatatypeDefinitionReal.cs | 14 -- ReqIFSharp/Identifiable.cs | 7 - ReqIFSharp/ReqIFHeader.cs | 14 -- 16 files changed, 541 insertions(+), 69 deletions(-) create mode 100644 ReqIFSharp.Tests/Datatype/DatatypeDefinitionIntegerTestFixture.cs create mode 100644 ReqIFSharp.Tests/Datatype/DatatypeDefinitionRealTestFixture.cs create mode 100644 ReqIFSharp.Tests/Datatype/DatatypeDefinitionStringTestFixture.cs diff --git a/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs b/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs index df75fe6..edd110a 100644 --- a/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs +++ b/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs @@ -18,18 +18,18 @@ // // ------------------------------------------------------------------------------------------------ +using Microsoft.Extensions.Logging.Abstractions; + namespace ReqIFSharp.Tests { + using NUnit.Framework; + using ReqIFSharp; using System; using System.IO; using System.Runtime.Serialization; using System.Threading; using System.Xml; - using NUnit.Framework; - - using ReqIFSharp; - /// /// Suite of tests for the /// @@ -86,5 +86,22 @@ public void Verify_That_WriteXmlAsync_Throws_Exception_When_Type_I_sNull() Assert.That(async () => await attributeDefinitionEnumeration.WriteXmlAsync(writer, cancellationTokenSource.Token), Throws.Exception.TypeOf()); } + + [Test] + public void Verify_that_when_invalid_IsMultiValued_Exception_is_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinitionEnumeration = new AttributeDefinitionEnumeration(specType, NullLoggerFactory.Instance); + + Assert.That(() => attributeDefinitionEnumeration.ReadXml(xmlReader), + Throws.InstanceOf()); + } } } diff --git a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueBooleanTestFixture.cs b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueBooleanTestFixture.cs index f9bd68b..8ec6d67 100644 --- a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueBooleanTestFixture.cs +++ b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueBooleanTestFixture.cs @@ -26,6 +26,8 @@ namespace ReqIFSharp.Tests using System.Threading; using System.Xml; + using Microsoft.Extensions.Logging.Abstractions; + using NUnit.Framework; using ReqIFSharp; @@ -159,5 +161,20 @@ public void Verify_that_ReadXmlAsync_throws_exception_when_cancelled() Assert.That(async () => await attributeValueBoolean.ReadXmlAsync(xmlReader, cts.Token), Throws.Exception.TypeOf()); } + + [Test] + public void Verify_that_when_invalid_IsMultiValued_Exception_is_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var attributeValueBoolean = new AttributeValueBoolean(NullLoggerFactory.Instance); + + Assert.That(() => attributeValueBoolean.ReadXml(xmlReader), Throws.InstanceOf()); + } } } diff --git a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueDateTestFixture.cs b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueDateTestFixture.cs index d03eb2b..b9978c9 100644 --- a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueDateTestFixture.cs +++ b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueDateTestFixture.cs @@ -26,6 +26,8 @@ namespace ReqIFSharp.Tests using System.Threading; using System.Xml; + using Microsoft.Extensions.Logging.Abstractions; + using NUnit.Framework; using ReqIFSharp; @@ -160,5 +162,41 @@ public void Verify_that_ReadXmlAsync_throws_exception_when_cancelled() Assert.That(async () => await attributeValueDate.ReadXmlAsync(xmlReader, cts.Token), Throws.Exception.TypeOf()); } + + [Test] + public void Verify_that_when_invalid_Value_Exception_is_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinition = new AttributeDefinitionDate { SpecType = specType }; + + var attributeValueDate = new AttributeValueDate(attributeDefinition, NullLoggerFactory.Instance); + + Assert.That(() => attributeValueDate.ReadXml(xmlReader), Throws.InstanceOf()); + } + + [Test] + public void Verify_that_when_too_large_small_Value_Exception_is_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinition = new AttributeDefinitionDate { SpecType = specType }; + + var attributeValueDate = new AttributeValueDate(attributeDefinition, NullLoggerFactory.Instance); + + Assert.That(() => attributeValueDate.ReadXml(xmlReader), Throws.InstanceOf()); + } } } diff --git a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueIntegerTestFixture.cs b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueIntegerTestFixture.cs index 64ce493..5ef8d7a 100644 --- a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueIntegerTestFixture.cs +++ b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueIntegerTestFixture.cs @@ -22,10 +22,12 @@ namespace ReqIFSharp.Tests { using System; using System.IO; - using System.Threading; using System.Runtime.Serialization; + using System.Threading; using System.Xml; + using Microsoft.Extensions.Logging.Abstractions; + using NUnit.Framework; using ReqIFSharp; @@ -158,5 +160,43 @@ public void Verify_that_ReadXmlAsync_throws_exception_when_cancelled() Assert.That(async () => await attributeValueInteger.ReadXmlAsync(xmlReader, cts.Token), Throws.Exception.TypeOf()); } + + [Test] + public void Verify_that_when_too_large_Value_Exception_is_not_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinition = new AttributeDefinitionInteger() { SpecType = specType }; + + var attributeValueInteger = new AttributeValueInteger(attributeDefinition, NullLoggerFactory.Instance); + + Assert.That(() => attributeValueInteger.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(attributeValueInteger.TheValue, Is.EqualTo(0)); + } + + [Test] + public void Verify_that_when_too_invalid_Value_Exception_is_not_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinition = new AttributeDefinitionInteger() { SpecType = specType }; + + var attributeValueInteger = new AttributeValueInteger(attributeDefinition, NullLoggerFactory.Instance); + + Assert.That(() => attributeValueInteger.ReadXml(xmlReader), Throws.InstanceOf()); + } } } \ No newline at end of file diff --git a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueRealTestFixture.cs b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueRealTestFixture.cs index cc67c17..3b8565c 100644 --- a/ReqIFSharp.Tests/AttributeValueTests/AttributeValueRealTestFixture.cs +++ b/ReqIFSharp.Tests/AttributeValueTests/AttributeValueRealTestFixture.cs @@ -27,6 +27,7 @@ namespace ReqIFSharp.Tests using System.Xml; using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; using NUnit.Framework; @@ -181,5 +182,43 @@ public void Verify_that_ReadXmlAsync_throws_exception_when_cancelled() Assert.That(async () => await attributeValueReal.ReadXmlAsync(xmlReader, cts.Token), Throws.Exception.TypeOf()); } + + [Test] + public void Verify_that_when_too_large_Value_Exception_is_not_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinition = new AttributeDefinitionReal() { SpecType = specType }; + + var attributeValueReal = new AttributeValueReal(attributeDefinition, NullLoggerFactory.Instance); + + Assert.That(() => attributeValueReal.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(attributeValueReal.TheValue, Is.EqualTo(double.PositiveInfinity)); + } + + [Test] + public void Verify_that_when_too_invalid_Value_Exception_is_not_raised() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var specType = new SpecificationType { ReqIFContent = new ReqIFContent() }; + var attributeDefinition = new AttributeDefinitionReal() { SpecType = specType }; + + var attributeValueReal = new AttributeValueReal(attributeDefinition, NullLoggerFactory.Instance); + + Assert.That(() => attributeValueReal.ReadXml(xmlReader), Throws.InstanceOf()); + } } } diff --git a/ReqIFSharp.Tests/Datatype/DatatypeDefinitionIntegerTestFixture.cs b/ReqIFSharp.Tests/Datatype/DatatypeDefinitionIntegerTestFixture.cs new file mode 100644 index 0000000..06d6076 --- /dev/null +++ b/ReqIFSharp.Tests/Datatype/DatatypeDefinitionIntegerTestFixture.cs @@ -0,0 +1,117 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2017-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------- + +namespace ReqIFSharp.Tests +{ + using System; + using System.IO; + using System.Runtime.Serialization; + using System.Xml; + + using Microsoft.Extensions.Logging.Abstractions; + + using NUnit.Framework; + + using ReqIFSharp; + + [TestFixture] + public class DatatypeDefinitionIntegerTestFixture + { + [Test] + public void Verify_that_when_MAX_is_too_large_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionInteger = new DatatypeDefinitionInteger(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionInteger.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(datatypeDefinitionInteger.Max, Is.EqualTo(Int64.MaxValue)); + } + + [Test] + public void Verify_that_when_MAX_is_invalid_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionInteger = new DatatypeDefinitionInteger(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionInteger.ReadXml(xmlReader), Throws.InstanceOf()); + } + + [Test] + public void Verify_that_when_MIN_is_too_large_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionInteger = new DatatypeDefinitionInteger(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionInteger.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(datatypeDefinitionInteger.Min, Is.EqualTo(Int64.MinValue)); + } + + [Test] + public void Verify_that_when_MIN_is_invalid_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionInteger = new DatatypeDefinitionInteger(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionInteger.ReadXml(xmlReader), Throws.InstanceOf()); + } + } +} diff --git a/ReqIFSharp.Tests/Datatype/DatatypeDefinitionRealTestFixture.cs b/ReqIFSharp.Tests/Datatype/DatatypeDefinitionRealTestFixture.cs new file mode 100644 index 0000000..a183867 --- /dev/null +++ b/ReqIFSharp.Tests/Datatype/DatatypeDefinitionRealTestFixture.cs @@ -0,0 +1,156 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2017-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------- + +namespace ReqIFSharp.Tests +{ + using System.IO; + using System.Runtime.Serialization; + using System.Xml; + + using Microsoft.Extensions.Logging.Abstractions; + + using NUnit.Framework; + + using ReqIFSharp; + + [TestFixture] + public class DatatypeDefinitionRealTestFixture + { + [Test] + public void Verify_that_when_MAX_LENGTH_is_too_large_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionReal = new DatatypeDefinitionReal(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionReal.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(datatypeDefinitionReal.Max, Is.EqualTo(double.PositiveInfinity)); + } + + [Test] + public void Verify_that_when_MAX_LENGTH_is_invalid_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionReal = new DatatypeDefinitionReal(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionReal.ReadXml(xmlReader), Throws.InstanceOf()); + } + + [Test] + public void Verify_that_when_MIN_is_too_large_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionReal = new DatatypeDefinitionReal(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionReal.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(datatypeDefinitionReal.Min, Is.EqualTo(double.NegativeInfinity)); + } + + [Test] + public void Verify_that_when_MIN_is_invalid_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionReal = new DatatypeDefinitionReal(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionReal.ReadXml(xmlReader), Throws.InstanceOf()); + } + + [Test] + public void Verify_that_when_ACCURACY_is_too_large_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionReal = new DatatypeDefinitionReal(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionReal.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(datatypeDefinitionReal.Accuracy, Is.EqualTo(long.MaxValue)); + } + + [Test] + public void Verify_that_when_ACCURACY_is_invalid_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionReal = new DatatypeDefinitionReal(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionReal.ReadXml(xmlReader), Throws.InstanceOf()); + } + } +} diff --git a/ReqIFSharp.Tests/Datatype/DatatypeDefinitionStringTestFixture.cs b/ReqIFSharp.Tests/Datatype/DatatypeDefinitionStringTestFixture.cs new file mode 100644 index 0000000..63977f4 --- /dev/null +++ b/ReqIFSharp.Tests/Datatype/DatatypeDefinitionStringTestFixture.cs @@ -0,0 +1,76 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2017-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------- + +namespace ReqIFSharp.Tests +{ + using System.IO; + using System.Runtime.Serialization; + using System.Xml; + + using Microsoft.Extensions.Logging.Abstractions; + + using NUnit.Framework; + + using ReqIFSharp; + + [TestFixture] + public class DatatypeDefinitionStringTestFixture + { + [Test] + public void Verify_that_when_MAX_LENGTH_is_too_large_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionString = new DatatypeDefinitionString(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionString.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(datatypeDefinitionString.MaxLength, Is.EqualTo(long.MaxValue)); + } + + [Test] + public void Verify_that_when_MAX_LENGTH_is_invalid_exception_is_thrown() + { + var xml = """ + + + + + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionString = new DatatypeDefinitionString(NullLoggerFactory.Instance); + + Assert.That(() => datatypeDefinitionString.ReadXml(xmlReader), Throws.InstanceOf()); + } + } +} diff --git a/ReqIFSharp.Tests/Datatype/EmbeddedValueTestFixture.cs b/ReqIFSharp.Tests/Datatype/EmbeddedValueTestFixture.cs index bd9db05..329642d 100644 --- a/ReqIFSharp.Tests/Datatype/EmbeddedValueTestFixture.cs +++ b/ReqIFSharp.Tests/Datatype/EmbeddedValueTestFixture.cs @@ -22,13 +22,16 @@ namespace ReqIFSharp.Tests { using System; using System.IO; + using System.Runtime.Serialization; using System.Threading; using System.Xml; + using Microsoft.Extensions.Logging.Abstractions; + using NUnit.Framework; using ReqIFSharp; - + /// /// Suite of tests for the /// @@ -50,5 +53,37 @@ public void Verify_That_WriteXmlAsync_throws_exception_when_cancelled() async () => await embeddedValue.WriteXmlAsync(writer, cts.Token), Throws.Exception.TypeOf()); } + + [Test] + public void Verify_that_when_KEY_is_too_large_exception_is_thrown() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var embeddedValue = new EmbeddedValue(); + + Assert.That(() => embeddedValue.ReadXml(xmlReader), Throws.Nothing); + + Assert.That(embeddedValue.Key, Is.EqualTo(0)); + } + + [Test] + public void Verify_that_when_KEY_is_invalid_exception_is_thrown() + { + var xml = """ + + """; + + var xmlReader = XmlReader.Create(new StringReader(xml)); + xmlReader.MoveToContent(); + + var datatypeDefinitionString = new EmbeddedValue(); + + Assert.That(() => datatypeDefinitionString.ReadXml(xmlReader), Throws.InstanceOf()); + } } } diff --git a/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs b/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs index 3943ede..039b4ff 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueBoolean.cs @@ -236,13 +236,6 @@ private void ReadXmlAttributes(XmlReader reader) { this.TheValue = XmlConvert.ToBoolean(theValue); } - catch (OverflowException) - { - this.logger.LogWarning("The AttributeValueBoolean.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to false", - theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.TheValue = default; - } catch (Exception e) { throw new SerializationException($"The AttributeValueBoolean.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a BOOLEAN", e); diff --git a/ReqIFSharp/AttributeValue/AttributeValueDate.cs b/ReqIFSharp/AttributeValue/AttributeValueDate.cs index bad9fec..422e986 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueDate.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueDate.cs @@ -226,13 +226,6 @@ private void ReadXmlAttributes(XmlReader reader) { this.TheValue = XmlConvert.ToDateTime(theValue, XmlDateTimeSerializationMode.RoundtripKind); } - catch (OverflowException) - { - this.logger.LogWarning("The AttributeValueDate.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to DateTime.MinValue", - theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.TheValue = default; - } catch (Exception e) { throw new SerializationException($"The AttributeValueDate.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); diff --git a/ReqIFSharp/AttributeValue/AttributeValueReal.cs b/ReqIFSharp/AttributeValue/AttributeValueReal.cs index 0f3c2fc..44efd4f 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueReal.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueReal.cs @@ -237,13 +237,6 @@ private void ReadXmlAttributes(XmlReader reader) { this.TheValue = XmlConvert.ToDouble(theValue); } - catch (OverflowException) - { - this.logger.LogWarning("The AttributeValueReal.THE-VALUE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to 0", - theValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.TheValue = default; - } catch (Exception e) { throw new SerializationException($"The AttributeValueReal.THE-VALUE {theValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a REAL", e); diff --git a/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs b/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs index 69c6c61..f74a193 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueXHTML.cs @@ -324,13 +324,6 @@ private void ReadXmlAttributes(XmlReader reader) { this.IsSimplified = XmlConvert.ToBoolean(isSimplified); } - catch (OverflowException) - { - this.logger.LogWarning("The AttributeValueXHTML.IS-SIMPLIFIED: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. IsSimplified is set to false", - isSimplified, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.IsSimplified = default; - } catch (Exception e) { throw new SerializationException($"The AttributeValueXHTML.IS-SIMPLIFIED {isSimplified} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a BOOLEAN", e); diff --git a/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs b/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs index a4b3fd1..98f13e1 100644 --- a/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs +++ b/ReqIFSharp/Datatype/DatatypeDefinitionReal.cs @@ -163,13 +163,6 @@ private void ReadXmlAttributes(XmlReader reader) { this.Max = XmlConvert.ToDouble(maxValue); } - catch (OverflowException) - { - this.logger.LogWarning("The DatatypeDefinitionReal.MAX: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Max is set to Int64.MaxValue", - maxValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.Max = double.MaxValue; - } catch (Exception e) { throw new SerializationException($"The DatatypeDefinitionReal.MAX {maxValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a REAL", e); @@ -185,13 +178,6 @@ private void ReadXmlAttributes(XmlReader reader) { this.Min = XmlConvert.ToDouble(minValue); } - catch (OverflowException) - { - this.logger.LogWarning("The DatatypeDefinitionReal.MIN: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. Min is set to Int64.MinValue", - minValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.Min = double.MinValue; - } catch (Exception e) { throw new SerializationException($"The DatatypeDefinitionReal.MIN {minValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a REAL", e); diff --git a/ReqIFSharp/Identifiable.cs b/ReqIFSharp/Identifiable.cs index 34259f2..4788bca 100644 --- a/ReqIFSharp/Identifiable.cs +++ b/ReqIFSharp/Identifiable.cs @@ -128,13 +128,6 @@ internal virtual void ReadXml(XmlReader reader) { this.LastChange = XmlConvert.ToDateTime(lastChange, XmlDateTimeSerializationMode.RoundtripKind); } - catch (OverflowException) - { - this.logger.LogWarning("The Identifiable.LAST-CHANGE: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. LAST-CHANGE is set to DateTime.MinValue", - lastChange, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.LastChange = default; - } catch (Exception e) { throw new SerializationException($"The Identifiable.LAST-CHANGE {lastChange} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); diff --git a/ReqIFSharp/ReqIFHeader.cs b/ReqIFSharp/ReqIFHeader.cs index 4fb4271..9bc4f8c 100644 --- a/ReqIFSharp/ReqIFHeader.cs +++ b/ReqIFSharp/ReqIFHeader.cs @@ -147,13 +147,6 @@ internal void ReadXml(XmlReader reader) { this.CreationTime = XmlConvert.ToDateTime(creationTimeValue, XmlDateTimeSerializationMode.RoundtripKind); } - catch (OverflowException) - { - this.logger.LogWarning("The ReqIFHeader.CREATION-TIME: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to ReqIFHeader.CREATION-TIME", - creationTimeValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.CreationTime = default; - } catch (Exception e) { throw new SerializationException($"The ReqIFHeader.CREATION-TIME {creationTimeValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); @@ -221,13 +214,6 @@ internal async Task ReadXmlAsync(XmlReader reader, CancellationToken token) { this.CreationTime = XmlConvert.ToDateTime(creationTimeValue, XmlDateTimeSerializationMode.RoundtripKind); } - catch (OverflowException) - { - this.logger.LogWarning("The ReqIFHeader.CREATION-TIME: {Value} at line:position {LineNumber}:{LinePosition} could not be processed. TheValue is set to ReqIFHeader.CREATION-TIME", - creationTimeValue, xmlLineInfo?.LineNumber, xmlLineInfo?.LinePosition); - - this.CreationTime = default; - } catch (Exception e) { throw new SerializationException($"The ReqIFHeader.CREATION-TIME {creationTimeValue} at line:position {xmlLineInfo?.LineNumber}:{xmlLineInfo?.LinePosition} could not be converted to a DATE", e); From 55dcc0b3f1288b1ffd48eceaf1515ba4294d25a2 Mon Sep 17 00:00:00 2001 From: samatstarion Date: Sun, 9 Nov 2025 19:03:11 +0100 Subject: [PATCH 3/5] [cleanup] code --- .../AttributeDefinitionEnumerationTestFixture.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs b/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs index edd110a..2b8d413 100644 --- a/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs +++ b/ReqIFSharp.Tests/AttributeDefinitionTests/AttributeDefinitionEnumerationTestFixture.cs @@ -18,18 +18,20 @@ // // ------------------------------------------------------------------------------------------------ -using Microsoft.Extensions.Logging.Abstractions; - namespace ReqIFSharp.Tests { - using NUnit.Framework; - using ReqIFSharp; using System; using System.IO; using System.Runtime.Serialization; using System.Threading; using System.Xml; + using Microsoft.Extensions.Logging.Abstractions; + + using NUnit.Framework; + + using ReqIFSharp; + /// /// Suite of tests for the /// From d27f4b95b1aa0b32aff6f396a4bd4d01c458b4ff Mon Sep 17 00:00:00 2001 From: samatstarion Date: Sun, 9 Nov 2025 19:15:47 +0100 Subject: [PATCH 4/5] [Improve] coverage --- .../SpecType/SpecObjectTypeTestFixture.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 ReqIFSharp.Tests/SpecType/SpecObjectTypeTestFixture.cs diff --git a/ReqIFSharp.Tests/SpecType/SpecObjectTypeTestFixture.cs b/ReqIFSharp.Tests/SpecType/SpecObjectTypeTestFixture.cs new file mode 100644 index 0000000..e369024 --- /dev/null +++ b/ReqIFSharp.Tests/SpecType/SpecObjectTypeTestFixture.cs @@ -0,0 +1,50 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2017-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------- + +namespace ReqIFSharp.Tests.SpecTypes +{ + using Microsoft.Extensions.Logging.Abstractions; + + using NUnit.Framework; + + using ReqIFSharp; + + [TestFixture] + public class SpecObjectTypeTestFixture + { + [Test] + public void Verify_that_when_argument_null_exception_is_thrown() + { + ReqIFContent content = null; + + Assert.That(() => new SpecObjectType(content, NullLoggerFactory.Instance), Throws.ArgumentNullException); + } + + [Test] + public void Verify_that_when_constructed_no_exception_is_thrown() + { + var content = new ReqIFContent(); + + Assert.That(() => new SpecObjectType(content, NullLoggerFactory.Instance), Throws.Nothing); + + Assert.That(() => new SpecObjectType(NullLoggerFactory.Instance), Throws.Nothing); + } + } +} From 2e06c366077a34f10168a78928637534c2fc14ec Mon Sep 17 00:00:00 2001 From: samatstarion Date: Mon, 10 Nov 2025 07:04:16 +0100 Subject: [PATCH 5/5] remove unused logger --- ReqIFSharp/AttributeValue/AttributeValueString.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ReqIFSharp/AttributeValue/AttributeValueString.cs b/ReqIFSharp/AttributeValue/AttributeValueString.cs index f5b29ab..a7577c1 100644 --- a/ReqIFSharp/AttributeValue/AttributeValueString.cs +++ b/ReqIFSharp/AttributeValue/AttributeValueString.cs @@ -35,17 +35,11 @@ namespace ReqIFSharp /// public class AttributeValueString : AttributeValueSimple { - /// - /// The used to log - /// - private readonly ILogger logger; - /// /// Initializes a new instance of the class. /// public AttributeValueString() { - this.logger = NullLogger.Instance; } /// @@ -56,7 +50,6 @@ public AttributeValueString() /// public AttributeValueString(ILoggerFactory loggerFactory) : base(loggerFactory) { - this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } /// @@ -72,8 +65,6 @@ public AttributeValueString(ILoggerFactory loggerFactory) : base(loggerFactory) internal AttributeValueString(AttributeDefinitionString attributeDefinition, ILoggerFactory loggerFactory) : base(attributeDefinition, loggerFactory) { - this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); - this.OwningDefinition = attributeDefinition; } @@ -89,7 +80,6 @@ internal AttributeValueString(AttributeDefinitionString attributeDefinition, ILo internal AttributeValueString(SpecElementWithAttributes specElAt, ILoggerFactory loggerFactory) : base(specElAt, loggerFactory) { - this.logger = this.loggerFactory == null ? NullLogger.Instance : this.loggerFactory.CreateLogger(); } ///