Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions FluentAAS/FluentAAS.Builder/AasBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,15 @@
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="id"/> or <paramref name="idShort"/> is null, empty, or whitespace.
/// </exception>
/// <summary>
/// Begins registering a new Asset Administration Shell with the specified identifier and short name.
/// </summary>
/// <param name="id">The unique identifier for the shell; must not be null, empty, or whitespace.</param>
/// <param name="idShort">A short, human-readable name for the shell; must not be null, empty, or whitespace.</param>
/// <param name="kind">The asset kind for the shell's AssetInformation. Defaults to <see cref="AssetKind.Instance"/>.</param>
/// <returns>An <see cref="IShellBuilder"/> to configure the created shell.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="id"/> or <paramref name="idShort"/> is null, empty, or whitespace.</exception>
public IShellBuilder AddShell(string id, string idShort, AssetKind kind = AssetKind.Instance)

Check failure on line 54 in FluentAAS/FluentAAS.Builder/AasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'

Check failure on line 54 in FluentAAS/FluentAAS.Builder/AasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'
{
if (string.IsNullOrWhiteSpace(id))
{
Expand Down Expand Up @@ -78,8 +85,14 @@
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <exception cref="ArgumentException">
/// Thrown when required submodel fields are invalid.
/// </exception>
/// <summary>
/// Registers the given submodel with the builder after validating its identifiers.
/// </summary>
/// <param name="submodel">The submodel to add; must have a non-empty `Id` and `IdShort`.</param>
/// <returns>The same builder instance for fluent chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="submodel"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown if the submodel's `Id` or `IdShort` is null, empty, or whitespace.</exception>
public IAasBuilder AddSubmodel(Submodel submodel)

Check failure on line 95 in FluentAAS/FluentAAS.Builder/AasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'

Check failure on line 95 in FluentAAS/FluentAAS.Builder/AasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'
{
ValidateSubmodelForPublicAdd(submodel);
AddSubmodelInternal(submodel);
Expand All @@ -91,7 +104,13 @@
/// </summary>
/// <param name="submodel">The submodel instance to add.</param>
/// <returns>The current <see cref="AasBuilder"/> instance for fluent chaining.</returns>
/// <summary>
/// Registers an existing <see cref="Submodel"/> instance with the builder without requiring an <c>IdShort</c> value.
/// </summary>
/// <param name="submodel">The submodel to register; its <c>Id</c> must be set (non-empty).</param>
/// <returns>The current builder instance for fluent chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="submodel"/> has a null, empty, or whitespace <c>Id</c>.</exception>
public IAasBuilder AddExistingSubmodel(Submodel submodel)
{
AddSubmodelInternal(submodel);
Expand All @@ -106,6 +125,13 @@
/// <param name="configure">Callback that contributes submodel elements.</param>
/// <returns>The current <see cref="IAasBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="submodelId"/> is null, empty, or whitespace.</exception>
/// <summary>
/// Stages a submodel fragment configuration to be applied to the submodel with the specified id during Build.
/// </summary>
/// <param name="submodelId">Identifier of the target submodel; must not be null, empty, or whitespace.</param>
/// <param name="configure">Callback that receives a <see cref="SubmodelFragmentBuilder"/> to configure the fragment.</param>
/// <returns>The current <see cref="IAasBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="submodelId"/> is null, empty, or whitespace.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="configure"/> is null.</exception>
public IAasBuilder AddSubmodelFragment(string submodelId, Action<SubmodelFragmentBuilder> configure)
{
Expand All @@ -131,8 +157,15 @@
/// <returns>
/// A new <see cref="Environment"/> containing the configured asset administration
/// shells and submodels.
/// </returns>
/// <summary>
/// Builds an Environment containing the builder's registered shells and submodels after applying any staged submodel fragments and validating build-time invariants.
/// </summary>
/// <returns>An Environment with copies of the registered AssetAdministrationShells and Submodels.</returns>
/// <exception cref="InvalidOperationException">Thrown when one or more duplicate submodel ids are detected among registered Submodel instances.</exception>
/// <exception cref="InvalidOperationException">Thrown when a staged submodel fragment references a base submodel id that has not been added.</exception>
/// <exception cref="InvalidOperationException">Thrown when a shell contains a submodel reference without a valid identifier.</exception>
/// <exception cref="InvalidOperationException">Thrown when a shell references a submodel id that is not present among the registered submodels.</exception>
public IEnvironment Build()

Check failure on line 168 in FluentAAS/FluentAAS.Builder/AasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'returns'.'

Check failure on line 168 in FluentAAS/FluentAAS.Builder/AasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'returns'.'
{
var duplicateSubmodelIds = _submodels.OfType<Submodel>()
.GroupBy(s => s.Id, StringComparer.Ordinal)
Expand Down Expand Up @@ -210,6 +243,10 @@
/// Intended for internal use by shell or submodel builders.
/// </summary>
/// <param name="submodel">The submodel instance to add.</param>
/// <summary>
/// Registers the given submodel in the builder's internal collection if the same instance is not already present.
/// </summary>
/// <param name="submodel">The submodel to register; must not be null and must have a non-empty Id.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
public void AddSubmodelInternal(Submodel submodel)
{
Expand All @@ -222,6 +259,12 @@
}
}

/// <summary>
/// Validates that the provided <paramref name="submodel"/> is not null and has a non-empty Id.
/// </summary>
/// <param name="submodel">The submodel to validate; its <c>Id</c> must not be null, empty, or whitespace.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="submodel"/>'s <c>Id</c> is null, empty, or consists only of whitespace.</exception>
private static void ValidateSubmodelId(Submodel submodel)
{
ArgumentNullException.ThrowIfNull(submodel);
Expand All @@ -232,6 +275,11 @@
}
}

/// <summary>
/// Validates that a submodel has a non-empty identifier and a non-empty IdShort.
/// </summary>
/// <param name="submodel">The submodel to validate; its identifier and IdShort must be set.</param>
/// <exception cref="ArgumentException">Thrown when <c>submodel.IdShort</c> is null, empty, or whitespace.</exception>
private static void ValidateSubmodelForPublicAdd(Submodel submodel)
{
ValidateSubmodelId(submodel);
Expand Down
39 changes: 34 additions & 5 deletions FluentAAS/FluentAAS.Builder/IAasBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="id"/> or <paramref name="idShort"/> is null, empty, or whitespace.
/// </exception>
/// <summary>
/// Declares a new AssetAdministrationShell to add to the environment.
/// </summary>
/// <param name="id">Unique identifier of the shell.</param>
/// <param name="idShort">Short name (IdShort) for the shell.</param>
/// <param name="kind">Specifies the asset kind; defaults to AssetKind.Instance.</param>
/// <returns>An IShellBuilder for configuring the newly declared shell.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="id"/> or <paramref name="idShort"/> is null, empty, or consists only of whitespace.</exception>
IShellBuilder AddShell(string id, string idShort, AssetKind kind = AssetKind.Instance);

Check failure on line 30 in FluentAAS/FluentAAS.Builder/IAasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'

Check failure on line 30 in FluentAAS/FluentAAS.Builder/IAasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'

/// <summary>
/// Adds an existing, fully constructed <see cref="Submodel"/> to the environment.
Expand All @@ -31,15 +38,26 @@
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <exception cref="ArgumentException">
/// Thrown when required submodel fields (for example <see cref="IReferable.IdShort"/>) are invalid.
/// </exception>
/// <summary>
/// Registers a fully constructed Submodel with the builder so it becomes part of the resulting environment.
/// </summary>
/// <param name="submodel">The fully constructed Submodel to register; it will participate in build-time uniqueness validation.</param>
/// <returns>The same IAasBuilder instance for fluent chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when required submodel fields (for example, <c>IReferable.IdShort</c>) are null, empty, or otherwise invalid.</exception>
IAasBuilder AddSubmodel(Submodel submodel);

Check failure on line 48 in FluentAAS/FluentAAS.Builder/IAasBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'

/// <summary>
/// Adds an existing <see cref="Submodel"/> to the environment.
/// </summary>
/// <param name="submodel">The submodel instance to add.</param>
/// <returns>The current <see cref="AasBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <summary>
/// Adds an existing Submodel instance to the builder's configuration.
/// </summary>
/// <param name="submodel">The Submodel instance to add to the environment.</param>
/// <returns>The current <see cref="IAasBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
IAasBuilder AddExistingSubmodel(Submodel submodel);

/// <summary>
Expand All @@ -50,7 +68,14 @@
/// <param name="configure">Callback that contributes submodel elements.</param>
/// <returns>The current <see cref="IAasBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="submodelId"/> is null, empty, or whitespace.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="configure"/> is null.</exception>
/// <summary>
/// Register a staged submodel fragment to be applied to an existing submodel identified by <paramref name="submodelId"/> during Build.
/// </summary>
/// <param name="submodelId">The identifier of an already registered submodel to which the fragment will be applied.</param>
/// <param name="configure">An action that configures the staged fragment using a <see cref="SubmodelFragmentBuilder"/>; fragments are applied in registration order when Build is called.</param>
/// <returns>The same <see cref="IAasBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="submodelId"/> is null, empty, or whitespace.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="configure"/> is null.</exception>
IAasBuilder AddSubmodelFragment(string submodelId, Action<SubmodelFragmentBuilder> configure);

/// <summary>
Expand All @@ -75,6 +100,10 @@
/// Intended for internal use by shell or submodel builders.
/// </summary>
/// <param name="submodel">The submodel instance to add.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
/// <summary>
/// Adds a fully constructed Submodel to the builder's environment.
/// </summary>
/// <param name="submodel">The fully constructed Submodel to add to the environment.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="submodel"/> is null.</exception>
void AddSubmodelInternal(Submodel submodel);
}
27 changes: 26 additions & 1 deletion FluentAAS/FluentAAS.Builder/SubModel/SubmodelFragmentBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
{
private readonly Submodel _target;

/// <summary>
/// Initializes a SubmodelFragmentBuilder for the specified submodel and ensures its SubmodelElements collection is initialized.
/// </summary>
/// <param name="target">The submodel to which staged elements will be appended.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="target"/> is null.</exception>
internal SubmodelFragmentBuilder(Submodel target)
{
_target = target ?? throw new ArgumentNullException(nameof(target));
Expand All @@ -23,8 +28,16 @@
/// <returns>The current <see cref="SubmodelFragmentBuilder"/>.</returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="idShort"/> or <paramref name="value"/> is null, empty, or whitespace.
/// </exception>
/// <summary>
/// Adds a Property with the specified idShort, value, and data type to the target Submodel.
/// </summary>
/// <param name="idShort">Short identifier for the Property; must not be null, empty, or whitespace.</param>
/// <param name="value">Value for the Property; must not be null, empty, or whitespace.</param>
/// <param name="valueType">Data type for the Property value. Defaults to <see cref="DataTypeDefXsd.String"/>.</param>
/// <returns>The current <see cref="SubmodelFragmentBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="idShort"/> is null, empty, or whitespace.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="value"/> is null, empty, or whitespace.</exception>
public SubmodelFragmentBuilder AddProperty(string idShort, string value, DataTypeDefXsd valueType = DataTypeDefXsd.String)

Check failure on line 40 in FluentAAS/FluentAAS.Builder/SubModel/SubmodelFragmentBuilder.cs

View workflow job for this annotation

GitHub Actions / PR Test Gate

XML comment has badly formed XML -- 'Expected an end tag for element 'exception'.'
{
if (string.IsNullOrWhiteSpace(idShort))
{
Expand Down Expand Up @@ -53,6 +66,13 @@
/// <param name="configure">Configuration callback for language strings.</param>
/// <returns>The current <see cref="SubmodelFragmentBuilder"/>.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="idShort"/> is null, empty, or whitespace.</exception>
/// <summary>
/// Adds a multilingual (language-string) property to the target submodel and stages it for later build operations.
/// </summary>
/// <param name="idShort">The short identifier for the property; must not be null, empty, or whitespace.</param>
/// <param name="configure">A configuration callback that populates the <see cref="LangStringSetBuilder"/> with language entries.</param>
/// <returns>The current <see cref="SubmodelFragmentBuilder"/> instance for fluent chaining.</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="idShort"/> is null, empty, or consists only of whitespace.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="configure"/> is null.</exception>
public SubmodelFragmentBuilder AddMultiLanguageProperty(string idShort, Action<LangStringSetBuilder> configure)
{
Expand All @@ -75,6 +95,11 @@
/// </summary>
/// <param name="element">The submodel element to add.</param>
/// <returns>The current <see cref="SubmodelFragmentBuilder"/>.</returns>
/// <summary>
/// Appends a submodel element to the target submodel and returns this builder for chaining.
/// </summary>
/// <param name="element">The submodel element to add to the target submodel.</param>
/// <returns>The current <see cref="SubmodelFragmentBuilder"/> instance.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="element"/> is null.</exception>
public SubmodelFragmentBuilder AddElement(ISubmodelElement element)
{
Expand Down
Loading