Skip to content

Commit

Permalink
Multiple fixes
Browse files Browse the repository at this point in the history
- Added test and (closes #30)
- date, time and duration types added (closes #31)
- public method for attributes (closes #33)
  • Loading branch information
CBenghi committed Apr 2, 2024
1 parent 931cdd2 commit 42c168b
Show file tree
Hide file tree
Showing 20 changed files with 401 additions and 174 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
basic constructor

```csharp
public IfcMeasureInformation(string measure, string description, string unit, string symbol,
public IfcMeasureInformation(string measureId, string description, string unit, string unitSymbol,
string defDisplayUnit, string exponents, string unitTypeEnum)
```

Expand Down
1 change: 1 addition & 0 deletions ids-lib-documentation/IdsLib.IfcSchema/SchemaInfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class SchemaInfo : IEnumerable<ClassInfo>
| static [AllAttributes](SchemaInfo/AllAttributes.md) { get; } | The names of all attributes across all schemas. |
| static [AllConcreteClasses](SchemaInfo/AllConcreteClasses.md) { get; } | The names of all concrete classes across known IFC schemas. |
| static [AllDataTypes](SchemaInfo/AllDataTypes.md) { get; } | The names of dataType classes across all schemas. |
| static [AllMeasureInformation](SchemaInfo/AllMeasureInformation.md) { get; } | A selection of all the measures available in [`AllDataTypes`](./SchemaInfo/AllDataTypes.md). |
| static [GetConcreteClassesFrom](SchemaInfo/GetConcreteClassesFrom.md)(…) | Returns a list of the concrete class names that implement a given top class. When multiple schema flags are passed the list is the non-repeating union of the values of each schema |
| static [GetSchemas](SchemaInfo/GetSchemas.md)(…) | Returns the schema metadata information for the required versions. |
| static [TryParseIfcDataType](SchemaInfo/TryParseIfcDataType.md)(…) | Attempts to convert a string value to an instance of the IfcMeasureInformation |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SchemaInfo.AllMeasureInformation property

A selection of all the measures available in [`AllDataTypes`](./AllDataTypes.md).

```csharp
public static IEnumerable<IfcMeasureInformation> AllMeasureInformation { get; }
```

## See Also

* struct [IfcMeasureInformation](../IfcMeasureInformation.md)
* class [SchemaInfo](../SchemaInfo.md)
* namespace [IdsLib.IfcSchema](../../ids-lib.md)

<!-- DO NOT EDIT: generated by xmldocmd for ids-lib.dll -->
15 changes: 13 additions & 2 deletions ids-lib.codegen/IfcSchema_MeasureNamesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ internal static string Execute(out Dictionary<string, typeMetadata> dataTypeDict
}
else
{
xmlType = MapToXml(tmpType.UnderlyingType);
xmlType = MapToXml(tmpType.UnderlyingType, daDataType);
if (daDataType == "IFCCOUNTMEASURE") // exception for Xbim implementation quirkiness
xmlType = "xs:integer";
}
Expand Down Expand Up @@ -131,8 +131,19 @@ internal static string Execute(out Dictionary<string, typeMetadata> dataTypeDict

}

private static string MapToXml(Type underlyingType)
private static string MapToXml(Type underlyingType, string daDataType)
{
switch (daDataType)
{
case "IFCDURATION":
return "xs:duration";
case "IFCDATETIME":
return "xs:dateTime";
case "IFCDATE":
return "xs:date";
case "IFCTIME":
return "xs:time";
}
switch (underlyingType.Name)
{
case "Int64":
Expand Down
39 changes: 22 additions & 17 deletions ids-lib/IdsSchema/XsNodes/XsEnumeration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public bool TryMatch(IEnumerable<string> candidateStrings, bool ignoreCase, out
return matches.Any();
}

readonly Regex regexInteger = new(@"^[+-]?(\d+)$", RegexOptions.Compiled);
readonly Regex regexFloating = new(@"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$", RegexOptions.Compiled);


public string Value => value;

Expand All @@ -56,30 +55,36 @@ protected internal override Audit.Status PerformAudit(AuditStateInformation stat

switch (restriction.Base)
{
case XsRestriction.BaseTypes.Invalid: // notified in the the restriction already, do nothing here
case XsRestriction.BaseTypes.Undefined: // todo: to be discussed in group
case XsRestriction.BaseTypes.XsString: // nothing
case XsTypes.BaseTypes.XsAnyUri: // todo: implement Uri value filter
case XsTypes.BaseTypes.Invalid: // notified in the the restriction already, do nothing here
case XsTypes.BaseTypes.Undefined: // todo: to be discussed in group
case XsTypes.BaseTypes.XsString: // nothing
break;
case XsRestriction.BaseTypes.XsBoolean:
case XsTypes.BaseTypes.XsBoolean:
if (value != "false" && value != "true")
ret |= IdsErrorMessages.Report305BadConstraintValue(logger, this, value, restriction.Base);
break;
case XsRestriction.BaseTypes.XsInteger:
if (!regexInteger.IsMatch(value))
case XsTypes.BaseTypes.XsInteger:
if (!XsTypes.IsValid(value, restriction.Base))
ret |= IdsErrorMessages.Report305BadConstraintValue(logger, this, value, restriction.Base);
break;
case XsRestriction.BaseTypes.XsDouble:
case XsRestriction.BaseTypes.XsFloat:
case XsRestriction.BaseTypes.XsDecimal:
if (!regexFloating.IsMatch(value))
case XsTypes.BaseTypes.XsDouble:
case XsTypes.BaseTypes.XsFloat:
case XsTypes.BaseTypes.XsDecimal:
if (!XsTypes.IsValid(value, restriction.Base))
ret |= IdsErrorMessages.Report305BadConstraintValue(logger, this, value, restriction.Base);
break;
case XsRestriction.BaseTypes.XsDuration: // todo: implement duration, discuss
case XsRestriction.BaseTypes.XsDateTime: // todo: implement date time value filter
case XsRestriction.BaseTypes.XsDate: // todo: implement date value filter
case XsRestriction.BaseTypes.XsAnyUri: // todo: implement Uri value filter
case XsTypes.BaseTypes.XsDuration:
case XsTypes.BaseTypes.XsDateTime:
case XsTypes.BaseTypes.XsDate:
case XsTypes.BaseTypes.XsTime:
if (!XsTypes.IsValid(value, restriction.Base))
ret |= IdsErrorMessages.Report305BadConstraintValue(logger, this, value, restriction.Base);
break;


default:
ret |= IdsErrorMessages.Report501UnexpectedScenario(logger, "base type evaluation not implemented.", this);
ret |= IdsErrorMessages.Report501UnexpectedScenario(logger, $"type evaluation not implemented for `{restriction.Base}`", this);
break;
}
return ret;
Expand Down
41 changes: 4 additions & 37 deletions ids-lib/IdsSchema/XsNodes/XsRestriction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,8 @@ namespace IdsLib.IdsSchema.XsNodes;

internal class XsRestriction : IdsXmlNode, IStringListMatcher, IStringPrefixMatcher, IFiniteStringMatcher
{
internal enum BaseTypes
{
Invalid,
Undefined,
XsString,
XsBoolean,
XsInteger,
XsDouble,
XsFloat,
XsDecimal,
XsDuration,
XsDateTime,
XsDate,
XsAnyUri,
}

internal string BaseAsString { get; init; }
internal BaseTypes Base { get; init; }
internal XsTypes.BaseTypes Base { get; init; }

public string Value => string.Join(",", GetDicreteValues());

Expand All @@ -39,27 +23,10 @@ internal enum BaseTypes
public XsRestriction(XmlReader reader, IdsXmlNode? parent) : base(reader, parent)
{
BaseAsString = reader.GetAttribute("base") ?? string.Empty;
Base = GetBaseFrom(BaseAsString);
Base = XsTypes.GetBaseFrom(BaseAsString);
}

private static BaseTypes GetBaseFrom(string baseAsString)
{
return baseAsString switch
{
"" => BaseTypes.Undefined,
"xs:string" => BaseTypes.XsString,
"xs:boolean" => BaseTypes.XsBoolean,
"xs:integer" => BaseTypes.XsInteger,
"xs:double" => BaseTypes.XsDouble,
"xs:float" => BaseTypes.XsFloat,
"xs:decimal" => BaseTypes.XsDecimal,
"xs:duration" => BaseTypes.XsDuration,
"xs:dateTime" => BaseTypes.XsDateTime,
"xs:date" => BaseTypes.XsDate,
"xs:anyUri" => BaseTypes.XsAnyUri,
_ => BaseTypes.Invalid
};
}


public Audit.Status DoesMatch(IEnumerable<string> candidateStrings, bool ignoreCase, ILogger? logger, out IEnumerable<string> matches, string variableName, IfcSchema.IfcSchemaVersions schemaContext)
{
Expand Down Expand Up @@ -128,7 +95,7 @@ public bool TryMatch(IEnumerable<string> candidateStrings, bool ignoreCase, out
protected internal override Audit.Status PerformAudit(AuditStateInformation stateInfo, ILogger? logger)
{
var ret = Audit.Status.Ok;
if (Base == BaseTypes.Invalid)
if (Base == XsTypes.BaseTypes.Invalid)
ret |= IdsErrorMessages.Report303RestrictionBadType(logger, this, BaseAsString);
if (!Children.Any())
ret |= IdsErrorMessages.Report304RestrictionEmptyContent(logger, this);
Expand Down
132 changes: 132 additions & 0 deletions ids-lib/IdsSchema/XsNodes/XsTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace IdsLib.IdsSchema.XsNodes
{
/// <summary>
/// Utility class for XSD type management
/// </summary>
public static class XsTypes
{
private readonly static Regex regexInteger = new(@"^[+-]?(\d+)$", RegexOptions.Compiled);
private readonly static Regex regexFloating = new(@"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$", RegexOptions.Compiled);
private readonly static Regex regexDuration = new(@"^[-+]?P(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$", RegexOptions.Compiled);
private readonly static Regex regexDate = new(@"^\d{4}-\d{2}-\d{2}(Z|([+-]\d{2}:\d{2}))?$", RegexOptions.Compiled);
private readonly static Regex regexTime = new(@"^\d{2}:\d{2}:\d{2}(\.\d+)?(Z|([+-]\d{2}:\d{2}))?$", RegexOptions.Compiled);
private readonly static Regex regexDateTime = new(@"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|([+-]\d{2}:\d{2}))?$", RegexOptions.Compiled);

/// <summary>
/// Determines if a string value is compatible with a given type
/// </summary>
/// <param name="valueString">the string value to parse</param>
/// <param name="base">The expected base type</param>
/// <returns>TRUE if compatible, false otherwise</returns>
public static bool IsValid(string valueString, BaseTypes @base)
{
switch(@base)
{
case BaseTypes.XsInteger:
return regexInteger.IsMatch(valueString);
case BaseTypes.XsDouble:
case BaseTypes.XsFloat:
case BaseTypes.XsDecimal:
return regexFloating.IsMatch(valueString);
case BaseTypes.XsDate:
return regexDate.IsMatch(valueString);
case BaseTypes.XsTime:
return regexTime.IsMatch(valueString);
case BaseTypes.XsDateTime:
return regexDateTime.IsMatch(valueString);
case BaseTypes.XsDuration:
return regexDuration.IsMatch(valueString);
}
return false;
}

/// <summary>
/// Utility function to evaluate the type enumeration from a string
/// </summary>
/// <param name="baseAsString">the string value to parse</param>
/// <returns>the resolved enumeration result.</returns>
public static BaseTypes GetBaseFrom(string baseAsString)
{
return baseAsString switch
{
"" => BaseTypes.Undefined,
"xs:string" => BaseTypes.XsString,
"xs:boolean" => BaseTypes.XsBoolean,
"xs:integer" => BaseTypes.XsInteger,
"xs:double" => BaseTypes.XsDouble,
"xs:float" => BaseTypes.XsFloat,
"xs:decimal" => BaseTypes.XsDecimal,
"xs:duration" => BaseTypes.XsDuration,
"xs:dateTime" => BaseTypes.XsDateTime,
"xs:date" => BaseTypes.XsDate,
"xs:anyUri" => BaseTypes.XsAnyUri,
_ => BaseTypes.Invalid
};
}

/// <summary>
///
/// </summary>
public enum BaseTypes
{
/// <summary>
/// A an attempted conversion from string was unsuccesful
/// </summary>
Invalid,
/// <summary>
/// The value has not been assigned yet
/// </summary>
Undefined,
/// <summary>
/// String value
/// </summary>
XsString,
/// <summary>
/// Boiolean value
/// </summary>
XsBoolean,
/// <summary>
/// Integer value
/// </summary>
XsInteger,
/// <summary>
/// Double precision floating point value
/// </summary>
XsDouble,
/// <summary>
/// Floating point value
/// </summary>
XsFloat,
/// <summary>
/// Decimal precision value
/// </summary>
XsDecimal,
/// <summary>
/// Time duration value
/// </summary>
XsDuration,
/// <summary>
/// Date and time value (with optional time zone offset)
/// </summary>
XsDateTime,
/// <summary>
/// Date only value (with optional time zone offset)
/// </summary>
XsDate,
/// <summary>
/// Time only value (with optional time zone offset)
/// </summary>
XsTime,
/// <summary>
/// URI value
/// </summary>
XsAnyUri,
}

}
}
Loading

0 comments on commit 42c168b

Please sign in to comment.