Skip to content
Open
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
12 changes: 6 additions & 6 deletions SysML2.NET.Serializer.Json.Tests/ApiSerializerTestFixture.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="ApiSerializerTestFixture.cs" company="Starion Group S.A.">
//
//
// Copyright 2022-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.
//
//
// </copyright>
// ------------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -73,7 +73,7 @@ private void CreateTestData()
Created = new DateTime(1976, 8, 20, 0, 0, 0, DateTimeKind.Utc),
Description = "",
OwningProject = Guid.Parse("9b0e1914-3241-461e-b9ee-a3ff5120de4e"),
PreviousCommit = Guid.Empty,
PreviousCommits = [Guid.Parse("8d3c3f31-2b2f-4f4b-8f35-6b2e0f4a4a11")],
ResourceIdentifier = "http://www.stariongroup.eu/commit",
};

Expand Down
36 changes: 34 additions & 2 deletions SysML2.NET.Serializer.Json.Tests/DeSerializerTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ public class DeSerializerTestFixture
/// </remarks>
private const int LargePayloadElementCount = 4000;

/// <summary>
/// A merge commit json object that names two immediately preceding commits
/// </summary>
private const string MergeCommit = """[{"@id":"6d7ad9fd-6520-4ff2-885b-8c5c129e6c27","@type":"Commit","created":"2023-03-13T17:53:59.111354-04:00","description":null,"owningProject":{"@id":"000e9890-6935-43e6-a5d7-5d7cac601f4c"},"previousCommit":[{"@id":"1e4c2a06-0f2f-4a3c-9d64-0f4b2f6d9a11"},{"@id":"2b7d5e18-6a4f-4d1e-8c32-7d5a1c8e4b22"}]}]""";

/// <summary>
/// The identifiers that the <see cref="MergeCommit"/> payload names as preceding commits
/// </summary>
private static readonly Guid[] MergeCommitPredecessors =
[
Guid.Parse("1e4c2a06-0f2f-4a3c-9d64-0f4b2f6d9a11"),
Guid.Parse("2b7d5e18-6a4f-4d1e-8c32-7d5a1c8e4b22")
];

private DeSerializer deSerializer;

[SetUp]
Expand Down Expand Up @@ -209,7 +223,7 @@ public void Verify_that_particular_project_and_commits_from_restapi_json_can_be_
using (Assert.EnterMultipleScope())
{
Assert.That(firstCommit.OwningProject, Is.EqualTo(Guid.Parse("000e9890-6935-43e6-a5d7-5d7cac601f4c")));
Assert.That(firstCommit.PreviousCommit, Is.EqualTo(Guid.Empty));
Assert.That(firstCommit.PreviousCommits, Has.Count.EqualTo(0));
Assert.That(firstCommit.Description, Is.Null);
Assert.That(firstCommit.Created, Is.EqualTo(DateTime.Parse("2023-03-13T17:53:59.111354-04:00", CultureInfo.InvariantCulture)));
}
Expand All @@ -232,12 +246,30 @@ public void Verify_that_particular_project_and_particular_commit_from_restapi_js
using (Assert.EnterMultipleScope())
{
Assert.That(firstCommit.OwningProject, Is.EqualTo(Guid.Parse("000e9890-6935-43e6-a5d7-5d7cac601f4c")));
Assert.That(firstCommit.PreviousCommit, Is.EqualTo(Guid.Empty));
Assert.That(firstCommit.PreviousCommits, Has.Count.EqualTo(0));
Assert.That(firstCommit.Description, Is.Null);
Assert.That(firstCommit.Created, Is.EqualTo(DateTime.Parse("2023-03-13T17:53:59.111354-04:00", CultureInfo.InvariantCulture)));
}
}

[Test]
[TestCase(false)]
[TestCase(true)]
public void Verify_that_a_merge_commit_from_restapi_json_can_be_deserialized(bool shouldDeserializeDerivedProperties)
{
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(MergeCommit));

var data = this.deSerializer.DeSerialize(stream, SerializationModeKind.JSON, SerializationTargetKind.PSM, shouldDeserializeDerivedProperties);

var mergeCommit = data.OfType<Commit>().Single();

using (Assert.EnterMultipleScope())
{
Assert.That(mergeCommit.PreviousCommits, Is.EqualTo(MergeCommitPredecessors));
Assert.That(mergeCommit.OwningProject, Is.EqualTo(Guid.Parse("000e9890-6935-43e6-a5d7-5d7cac601f4c")));
}
}

[Test]
[TestCase(false)]
[TestCase(true)]
Expand Down
19 changes: 9 additions & 10 deletions SysML2.NET.Serializer.Json/PIM/CommitDeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,17 @@ internal static Commit DeSerialize(JsonElement jsonElement, SerializationModeKin

if (jsonElement.TryGetProperty("previousCommit"u8, out JsonElement previousCommitProperty))
{
if (previousCommitProperty.ValueKind == JsonValueKind.Null)
if (previousCommitProperty.ValueKind == JsonValueKind.Array)
{
dtoInstance.PreviousCommit = Guid.Empty;
}
else
{
if (previousCommitProperty.TryGetProperty("@id"u8, out JsonElement previousCommitPropertyIdProperty))
foreach (var previousCommitItem in previousCommitProperty.EnumerateArray())
{
var propertyValue = previousCommitPropertyIdProperty.GetString();
if (propertyValue != null)
if (previousCommitItem.TryGetProperty("@id"u8, out JsonElement previousCommitItemIdProperty))
{
dtoInstance.PreviousCommit = Guid.Parse(propertyValue);
var propertyValue = previousCommitItemIdProperty.GetString();
if (propertyValue != null)
{
dtoInstance.PreviousCommits.Add(Guid.Parse(propertyValue));
}
}
}
}
Expand All @@ -165,7 +164,7 @@ internal static Commit DeSerialize(JsonElement jsonElement, SerializationModeKin
{
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug("the owningProject Json property was not found in the Commit: {Id}", dtoInstance.Id);
logger.LogDebug("the previousCommit Json property was not found in the Commit: {Id}", dtoInstance.Id);
}
}

Expand Down
14 changes: 11 additions & 3 deletions SysML2.NET.Serializer.Json/PIM/CommitSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,17 @@ internal static void Serialize(object obj, Utf8JsonWriter writer, SerializationM
writer.WriteString("@id"u8, commit.OwningProject);
writer.WriteEndObject();
writer.WriteString("resourceIdentifier"u8, commit.ResourceIdentifier);
writer.WriteStartObject("previousCommit"u8);
writer.WriteString("@id"u8, commit.PreviousCommit);
writer.WriteEndObject();
writer.WriteStartArray("previousCommit"u8);
if (commit.PreviousCommits != null)
{
foreach (var item in commit.PreviousCommits)
{
writer.WriteStartObject();
writer.WriteString("@id"u8, item);
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();

break;
Expand Down
5 changes: 4 additions & 1 deletion SysML2.NET/PIM/DTO/Branch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ namespace SysML2.NET.PIM.DTO
{
using System;

using SysML2.NET.Decorators;

/// <summary>
/// A <see cref="Branch"/> is a type of CommitReference. A <see cref="Branch"/> is a pointer to a <see cref="Commit"/> (Branch.head).
/// The <see cref="Commit"/> history of a <see cref="Project"/> on a given branch can be computed by recursively navigating
/// <see cref="Commit.PreviousCommit"/>, starting from the head <see cref="Commit"/> of the <see cref="Branch"/> (Branch.head)
/// <see cref="Commit.PreviousCommits"/>, starting from the head <see cref="Commit"/> of the <see cref="Branch"/> (Branch.head)
/// </summary>
public class Branch : CommitReference
{
/// <summary>
/// Gets or sets the commit to which the branch is currently pointing. It represents the latest state of the
/// <see cref="Project"/> on the given branch
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the purpose of the Property C# attribute is to act as self documentation. My preference would be to write the whole propery, including repeating the default values. The intent is that a reader of the class can immediately see the related info coming from the UML model.

example:

[Property(xmiId: "abc", aggregation: AggregationKind.None, lowerValue: 1, upperValue: 1, isOrdered: false, isReadOnly: false, isDerived: false, isDerivedUnion: false, isUnique: true, defaultValue: null)]

public Guid Head { get; set; }
}
}
32 changes: 28 additions & 4 deletions SysML2.NET/PIM/DTO/Commit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace SysML2.NET.PIM.DTO
using System;
using System.Collections.Generic;

using SysML2.NET.Decorators;
using SysML2.NET.PIM;

/// <summary>
Expand All @@ -31,9 +32,9 @@ namespace SysML2.NET.PIM.DTO
/// a <see cref="Project"/>. A <see cref="Project"/> has 0 or more <see cref="Commit"/>s
/// </summary>
/// <remarks>
/// <see cref="Commit"/>s are immutable. For a given <see cref="Commit"/> record, the value of <c>change</c>
/// <see cref="Commit"/>s are immutable. For a given <see cref="Commit"/> record, the value of <see cref="Change"/>
/// cannot be modified after a <see cref="Commit"/> has been created. If a modification is required, a new <see cref="Commit"/>
/// record can be created with a different value of <c>change</c>.
/// record can be created with a different value of <see cref="Change"/>.
/// <see cref="Commit"/>s are not destructible1. A <see cref="Commit"/> record cannot be deleted during normal
/// end-user operation. <see cref="Commit"/>s represent the history and evolution of a <see cref="Project"/>.
/// Deleting and mutating <see cref="Commit"/> records must be disabled for the normal end-user operations
Expand All @@ -44,16 +45,39 @@ public class Commit : Record
/// <summary>
/// Gets or sets the timestamp at which the <see cref="Commit"/> was created
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public DateTime Created { get; set; }

/// <summary>
/// Gets or sets the <see cref="Project"/> that owns the <see cref="Commit"/>.
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public Guid OwningProject { get; set; }

/// <summary>
/// Gets or sets the immediately preceding <see cref="Commit"/>s
/// Gets or sets the set of immediately preceding <see cref="Commit"/>s
/// </summary>
public Guid PreviousCommit { get; set; }
[Property(lowerValue: 0, upperValue: int.MaxValue)]
public List<Guid> PreviousCommits { get; set; } = [];

/// <summary>
/// Gets or sets the set of <see cref="DataVersion"/> records representing data that is created, updated,
/// or deleted in the <see cref="Commit"/>
/// </summary>
/// <remarks>
/// A deletion is recorded by a <see cref="DataVersion"/> whose payload is <c>null</c>.
/// </remarks>
[Property(lowerValue: 1, upperValue: int.MaxValue)]
public List<Guid> Change { get; set; } = [];

/// <summary>
/// Gets or sets the set of cumulative <see cref="DataVersion"/> records in a <see cref="Project"/> at the <see cref="Commit"/>
/// </summary>
/// <remarks>
/// Derived by Systems Modeling API and Services, Clause 7.1.2 from <see cref="Change"/> and the
/// versioned data of <see cref="PreviousCommits"/>.
/// </remarks>
[Property(lowerValue: 0, upperValue: int.MaxValue, isDerived: true)]
public List<Guid> VersionedData { get; set; } = [];
}
}
6 changes: 6 additions & 0 deletions SysML2.NET/PIM/DTO/CommitReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace SysML2.NET.PIM.DTO
using System;

using SysML2.NET.Common;
using SysML2.NET.Decorators;

/// <summary>
/// An abstract subclass of <see cref="Record"/> that references a specific <see cref="Commit"/> (Commit Reference.referencedCommit). Project.commit is the set of all the Commit records for a given Project.
Expand All @@ -34,21 +35,26 @@ public abstract class CommitReference : Record
/// <summary>
/// Gets or sets the timestamp at which the <see cref="CommitReference"/> was created.
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public DateTime Created { get; set; }

/// <summary>
/// Gets or sets the timestamp at which the <see cref="CommitReference"/> was deleted
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public DateTime Deleted { get; set; }

/// <summary>
/// Gets or sets the Project that owns the given <see cref="CommitReference"/>
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public Guid OwningProject { get; set; }

/// <summary>
/// Gets or sets the name of the <see cref="CommitReference"/>
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
[RedefinedProperty(propertyName: "Record.Name")]
public new string Name { get; set; }
}
}
6 changes: 5 additions & 1 deletion SysML2.NET/PIM/DTO/CompositeConstraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ namespace SysML2.NET.PIM.DTO
{
using System.Collections.Generic;

using SysML2.NET.Decorators;

/// <summary>
/// a subtype of <see cref="Constraint"/> that represents complex conditions composed of two or more
/// a concrete subtype of <see cref="Constraint"/> that represents complex conditions composed of two or more
/// <see cref="CompositeConstraint"/>s or <see cref="PrimitiveConstraint"/>s using logical AND or OR operators
/// </summary>
public class CompositeConstraint : Constraint
Expand All @@ -34,11 +36,13 @@ public class CompositeConstraint : Constraint
/// <remarks>
/// There must be at least 2
/// </remarks>
[Property(lowerValue: 2, upperValue: int.MaxValue)]
public List<Constraint> Constraint { get; set; } = [];

/// <summary>
/// Gets or sets the logical operator for composing the <see cref="Constraint"/>s
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public JoinOperator Operator { get; set; }
}
}
4 changes: 4 additions & 0 deletions SysML2.NET/PIM/DTO/DataDifference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace SysML2.NET.PIM.DTO
{
using System;

using SysML2.NET.Decorators;

/// <summary>
/// Represents a single difference between two compared versions of the same <see cref="DataIdentity"/>
/// </summary>
Expand All @@ -30,11 +32,13 @@ public class DataDifference
/// <summary>
/// Gets or sets the <see cref="DataVersion"/> taken as the baseline of the comparison, or <c>null</c> when the data was added
/// </summary>
[Property(lowerValue: 0, upperValue: 1)]
public Guid? BaseData { get; set; }

/// <summary>
/// Gets or sets the <see cref="DataVersion"/> compared against the baseline, or <c>null</c> when the data was deleted
/// </summary>
[Property(lowerValue: 0, upperValue: 1)]
public Guid? CompareData { get; set; }
}
}
18 changes: 17 additions & 1 deletion SysML2.NET/PIM/DTO/DataVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace SysML2.NET.PIM.DTO
using System;

using SysML2.NET.Common;
using SysML2.NET.Decorators;

/// <summary>
/// A subclass of <see cref="Record"/> that represents <see cref="IData"/> at a specific version in its lifecycle.
Expand All @@ -32,18 +33,33 @@ namespace SysML2.NET.PIM.DTO
public class DataVersion : Record
{
/// <summary>
/// Gets or sets the <see cref="Project"/> <see cref="Commit"/> at which the wrapped data (payload) was created, modified, or deleted.
/// Gets or sets the <see cref="DTO.Project"/> <see cref="Commit"/> at which the wrapped data (payload) was created, modified, or deleted.
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public Guid Commit { get; set; }

/// <summary>
/// Gets or sets the <see cref="DTO.Project"/> that owns the <see cref="DataVersion"/>
/// </summary>
/// <remarks>
/// Derived by Systems Modeling API and Services, Clause 7.1.2 from the owning project of <see cref="Commit"/>.
/// </remarks>
[Property(lowerValue: 1, upperValue: 1, isDerived: true)]
public Guid Project { get; set; }

/// <summary>
/// Gets or sets the contained <see cref="DataIdentity"/>
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public DataIdentity Identity { get; set; }

/// <summary>
/// Gets or sets the <see cref="IData"/> that is the payload
/// </summary>
/// <remarks>
/// <c>null</c> when no data with the given identity is present at the <see cref="Commit"/>.
/// </remarks>
[Property(lowerValue: 0, upperValue: 1)]
public IData Payload { get; set; }
}
}
3 changes: 3 additions & 0 deletions SysML2.NET/PIM/DTO/ExternalData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace SysML2.NET.PIM.DTO
using System;

using SysML2.NET.Common;
using SysML2.NET.Decorators;

/// <summary>
/// ExternalData is a realization of Data, and represents a resource external to a given tool or
Expand All @@ -33,11 +34,13 @@ public class ExternalData : IData
/// <summary>
/// Gets or sets the unique identifier
/// </summary>
[Property(lowerValue: 1, upperValue: 1, isReadOnly: true)]
public Guid Id { get; set; }

/// <summary>
/// Gets or sets the string representation of the IRI of the resource represented by the ExternalData
/// </summary>
[Property(lowerValue: 1, upperValue: 1)]
public string ResourceIdentifier { get; set; }
}
}
Loading
Loading