Skip to content

Commit

Permalink
Updated xsd at version 0.9.7
Browse files Browse the repository at this point in the history
  • Loading branch information
CBenghi committed Feb 5, 2024
1 parent 358507e commit 40e9de0
Show file tree
Hide file tree
Showing 64 changed files with 691 additions and 567 deletions.
1 change: 1 addition & 0 deletions ids-lib.codegen/IfcSchema_MeasureNamesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ private static IEnumerable<string> GetAllDatatypeNames()
return GetDocumentationMeasureNames()
.Concat(GetExtraMeasureNames())
.Concat(GetPropsDatatypes())
.Select(x => x.ToUpperInvariant())
.Distinct();
}

Expand Down
123 changes: 62 additions & 61 deletions ids-lib.codegen/buildingSMART/units.md

Large diffs are not rendered by default.

20 changes: 7 additions & 13 deletions ids-lib/Audit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ private static async Task<Status> AuditStreamAsync(Stream theStream, IdsLib.Audi
var elementsStack = new Stack<IdsXmlNode>(); // prepare the stack to evaluate the IDS content
int iSpecification = 1;
IdsXmlNode? current = null;
var prevSchemaStatus = auditSettings.SchemaStatus;
AuditStateInformation stateInfo = new();
try
{
Expand Down Expand Up @@ -278,19 +277,10 @@ private static async Task<Status> AuditStreamAsync(Stream theStream, IdsLib.Audi
// parents of IdsSpecification do not retain children for Garbage Collection purposes
// so we need to set the positional index manually
spec.PositionalIndex = iSpecification++;

while (auditSettings.BufferedValidationIssues.Any())
{
var queuedIssue = auditSettings.BufferedValidationIssues.Dequeue();
if (
newContext.type == "attribute"
&&
(queuedIssue.Message.Contains("minOccurs") || queuedIssue.Message.Contains("maxOccurs"))
)
{
// this could fail under some circumstances, but it's a temporary workaround
auditSettings.SchemaStatus = prevSchemaStatus;
continue;
}
queuedIssue.Notify(logger, newContext);
}

Expand All @@ -314,17 +304,21 @@ private static async Task<Status> AuditStreamAsync(Stream theStream, IdsLib.Audi
case XmlNodeType.EndElement:
// Debug.WriteLine($"End Element {reader.LocalName}");
var closing = elementsStack.Pop();
while (auditSettings.BufferedValidationIssues.Any())
{
var queuedIssue = auditSettings.BufferedValidationIssues.Dequeue();
queuedIssue.Notify(logger, closing);
}
// Debug.WriteLine($" auditing {closing.type} on end element");
if (!auditSettings.Options.OmitIdsContentAudit)
{
contentStatus |= closing.PerformAudit(stateInfo, logger); // invoking audit on end of element
contentStatus |= closing.PerformAudit(stateInfo, logger); // invoking audit happens on end of element normally
}
break;
default:
// Debug.WriteLine("Other node {0} with value '{1}'.", reader.NodeType, reader.Value);
break;
}
prevSchemaStatus = auditSettings.SchemaStatus;
}
IdsToolMessages.InformReadCount(logger, cntRead);
}
Expand Down
36 changes: 36 additions & 0 deletions ids-lib/IdsSchema/Cardinality/ConditionalCardinality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace IdsLib.IdsSchema.Cardinality
{
internal class ConditionalCardinality : ICardinality
{
private readonly string enumerationValue;

public ConditionalCardinality(XmlReader reader)
{
enumerationValue = reader.GetAttribute("cardinality") ?? "Required";
}

public bool IsRequired => enumerationValue == "Required";

public Audit.Status Audit(out string errorMessage)
{
switch (enumerationValue)
{
case "Required":
case "Prohibited":
case "Optional":
errorMessage = string.Empty;
return IdsLib.Audit.Status.Ok;
default:
errorMessage = $"Invalid cardinality '{enumerationValue}'";
return MinMaxCardinality.CardinalityErrorStatus;
}
}
}
}
9 changes: 9 additions & 0 deletions ids-lib/IdsSchema/Cardinality/ICardinality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace IdsLib.IdsSchema.Cardinality
{
internal interface ICardinality
{
bool IsRequired { get; }

Audit.Status Audit(out string errorMessage);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System.Xml;

namespace IdsLib.IdsSchema;
namespace IdsLib.IdsSchema.Cardinality;

internal class MinMaxCardinality
internal class MinMaxCardinality : ICardinality
{
private readonly string minString;
private readonly string maxString;
Expand All @@ -12,49 +12,49 @@ public override string ToString()
return $"[{minString}..{maxString}]";
}

internal bool IsRequired => minString == "1";
public bool IsRequired => minString == "1";

public MinMaxCardinality(XmlReader reader)
{
// both default to "1" according to xml:xs specifications
minString = reader.GetAttribute("minOccurs") ?? "1";
maxString = reader.GetAttribute("maxOccurs") ?? "1";
minString = reader.GetAttribute("minOccurs") ?? "1";
maxString = reader.GetAttribute("maxOccurs") ?? "1";
}

internal const Audit.Status ErrorStatus = IdsLib.Audit.Status.IdsContentError;
internal const Audit.Status CardinalityErrorStatus = IdsLib.Audit.Status.IdsContentError;

/// <summary>
/// Audits the validity of an occurrence setting.
/// </summary>
/// <param name="errorMessage">if invalid returns an errors string without punctuation.</param>
/// <returns>the evaluated status</returns>
internal Audit.Status Audit(out string errorMessage)
public Audit.Status Audit(out string errorMessage)
{
uint max;
if (maxString == "unbounded")
max = uint.MaxValue;
else if (!uint.TryParse(maxString, out max))
{
errorMessage = $"Invalid maxOccurs '{maxString}'";
return ErrorStatus;
return CardinalityErrorStatus;
}
if (!uint.TryParse(minString, out var min))
{
errorMessage = $"Invalid minOccurs '{minString}'";
return ErrorStatus;
return CardinalityErrorStatus;
}
if (max < min)
{
errorMessage = $"Invalid range '{minString}' to `{maxString}`";
return ErrorStatus;
return CardinalityErrorStatus;
}
if (
min > 1 ||
(max != 0 && max != uint.MaxValue)
max != 0 && max != uint.MaxValue
)
{
errorMessage = $"Invalid configuration for IDS implementation agreements {this}";
return ErrorStatus;
return CardinalityErrorStatus;
}

errorMessage = string.Empty;
Expand Down
35 changes: 35 additions & 0 deletions ids-lib/IdsSchema/Cardinality/SimpleCardinality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace IdsLib.IdsSchema.Cardinality
{
internal class SimpleCardinality : ICardinality
{
private readonly string enumerationValue;

public SimpleCardinality(XmlReader reader)
{
enumerationValue = reader.GetAttribute("cardinality") ?? "Required";
}

public bool IsRequired => enumerationValue == "Required";

public Audit.Status Audit(out string errorMessage)
{
switch (enumerationValue)
{
case "Required":
case "Prohibited":
errorMessage = string.Empty;
return IdsLib.Audit.Status.Ok;
default:
errorMessage = $"Invalid cardinality '{enumerationValue}'";
return MinMaxCardinality.CardinalityErrorStatus;
}
}
}
}
35 changes: 28 additions & 7 deletions ids-lib/IdsSchema/IdsNodes/Facets/IdsAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using IdsLib.IfcSchema;
using IdsLib.IdsSchema.Cardinality;
using IdsLib.IfcSchema;
using IdsLib.IfcSchema.TypeFilters;
using IdsLib.Messages;
using Microsoft.Extensions.Logging;
Expand All @@ -9,19 +10,26 @@

namespace IdsLib.IdsSchema.IdsNodes;

internal class IdsAttribute : IdsXmlNode, IIdsFacet, IIfcTypeConstraintProvider
{
internal class IdsAttribute : IdsXmlNode, IIdsFacet, IIfcTypeConstraintProvider, IIdsCardinalityFacet
{

private readonly ICardinality cardinality;

public IdsAttribute(System.Xml.XmlReader reader, IdsXmlNode? parent) : base(reader, parent)
{
IsValid = false;
cardinality = new ConditionalCardinality(reader);
}

public bool IsValid { get; private set; }

/// <summary>
/// prepared typefilters per schema version
/// </summary>
private readonly Dictionary<SchemaInfo, IIfcTypeConstraint> typeFilters = new();
/// <inheritdoc />
public bool IsRequired => cardinality.IsRequired;

/// <summary>
/// prepared typefilters per schema version
/// </summary>
private readonly Dictionary<SchemaInfo, IIfcTypeConstraint> typeFilters = new();

/// <inheritdoc />
public IIfcTypeConstraint? GetTypesFilter(SchemaInfo schema)
Expand Down Expand Up @@ -66,4 +74,17 @@ private Audit.Status SetInvalid()
IsValid = false;
return Audit.Status.IdsContentError;
}

/// <inheritdoc />
public Audit.Status PerformCardinalityAudit(ILogger? logger)
{
var ret = Audit.Status.Ok;
if (cardinality.Audit(out var _) != Audit.Status.Ok)
{
IdsErrorMessages.Report301InvalidCardinality(logger, this, cardinality);
ret |= MinMaxCardinality.CardinalityErrorStatus;
IsValid = false;
}
return ret;
}
}
10 changes: 6 additions & 4 deletions ids-lib/IdsSchema/IdsNodes/Facets/IdsEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public IdsEntity(System.Xml.XmlReader reader, IdsXmlNode? parent) : base(reader,
IsValid = false;
}

private const string PRED_TYPE = "subType";

public bool IsValid {get; private set;}

internal protected override Audit.Status PerformAudit(AuditStateInformation stateInfo, ILogger? logger)
Expand Down Expand Up @@ -60,13 +62,13 @@ internal protected override Audit.Status PerformAudit(AuditStateInformation stat
typeFilters.Add(schema, new IfcConcreteTypeList(possibleClasses));

// predefined types that are common for the possibleClasses across defined schemas
var predefinedType = GetChildNodes("predefinedType").FirstOrDefault();
var predefinedType = GetChildNodes(PRED_TYPE).FirstOrDefault();
if (predefinedType is null)
continue;

var predefinedTypeMatcher = predefinedType.GetListMatcher();
if (predefinedTypeMatcher is null)
return IdsErrorMessages.Report102NoStringMatcher(logger, this, "predefinedType");
return IdsErrorMessages.Report102NoStringMatcher(logger, this, PRED_TYPE);


List<string>? possiblePredefined = null;
Expand All @@ -85,12 +87,12 @@ internal protected override Audit.Status PerformAudit(AuditStateInformation stat
}

if (possiblePredefined == null)
ret |= IdsErrorMessages.Report105InvalidDataConfiguration(logger, this, "predefinedType");
ret |= IdsErrorMessages.Report105InvalidDataConfiguration(logger, this, PRED_TYPE);
else if (possiblePredefined.Contains("USERDEFINED")) // if a user defined option is available then any value is acceptable
return ret;
else
// todo: ensure that this notifies an error and that error cases are added for multiple enumeration values
ret |= predefinedTypeMatcher.DoesMatch(possiblePredefined, false, logger, out var matches, "PredefinedType", schema.Version);
ret |= predefinedTypeMatcher.DoesMatch(possiblePredefined, false, logger, out var matches, PRED_TYPE, schema.Version);
}
return ret;
}
Expand Down
15 changes: 8 additions & 7 deletions ids-lib/IdsSchema/IdsNodes/Facets/IdsFacet.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using IdsLib.IfcSchema;
using IdsLib.IdsSchema.Cardinality;
using IdsLib.IfcSchema;
using IdsLib.IfcSchema.TypeFilters;
using IdsLib.Messages;
using Microsoft.Extensions.Logging;
Expand All @@ -12,18 +13,18 @@ namespace IdsLib.IdsSchema.IdsNodes;
/// </summary>
internal class IdsFacet : IdsXmlNode, IIdsCardinalityFacet, IIfcTypeConstraintProvider
{
private readonly MinMaxCardinality minMaxOccurr;
private readonly ICardinality cardinality;

public IdsFacet(System.Xml.XmlReader reader, IdsXmlNode? parent) : base(reader, parent)
{
minMaxOccurr = new MinMaxCardinality(reader);
cardinality = new ConditionalCardinality(reader);
}

/// <inheritdoc />
public bool IsValid { get; private set; } = true;

/// <inheritdoc />
public bool IsRequired => minMaxOccurr.IsRequired;
public bool IsRequired => cardinality.IsRequired;

/// <inheritdoc />
public IIfcTypeConstraint? GetTypesFilter(SchemaInfo schema)
Expand All @@ -45,10 +46,10 @@ protected internal override Audit.Status PerformAudit(AuditStateInformation stat
public Audit.Status PerformCardinalityAudit(ILogger? logger)
{
var ret = Audit.Status.Ok;
if (minMaxOccurr.Audit(out var _) != Audit.Status.Ok)
if (cardinality.Audit(out var _) != Audit.Status.Ok)
{
IdsErrorMessages.Report301InvalidCardinality(logger, this, minMaxOccurr);
ret |= MinMaxCardinality.ErrorStatus;
IdsErrorMessages.Report301InvalidCardinality(logger, this, cardinality);
ret |= MinMaxCardinality.CardinalityErrorStatus;
IsValid = false;
}
return ret;
Expand Down
Loading

0 comments on commit 40e9de0

Please sign in to comment.