Skip to content

Commit

Permalink
[Add] EnumerationReader and EnumerationLiteralReader
Browse files Browse the repository at this point in the history
  • Loading branch information
samatstariongroup committed Oct 9, 2024
1 parent a14bb87 commit a3fe68c
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 3 deletions.
20 changes: 19 additions & 1 deletion uml4net.xmi.Tests/UMLXmiReaderTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ namespace uml4net.xmi.Tests
using NUnit.Framework;

using uml4net.POCO.Packages;
using uml4net.POCO.SimpleClassifiers;
using uml4net.POCO.StructuredClassifiers;

[TestFixture]
public class UMLXmiReaderTestFixture
{
Expand Down Expand Up @@ -89,6 +90,23 @@ public void Verify_that_UML_XMI_can_be_read()
Assert.That(classOwnedComment.Body, Is.EqualTo("A Class classifies a set of objects and specifies the features that characterize the structure and behavior of those objects. A Class may have an internal structure and Ports.\r\n"));

Assert.That(@class.Generalization.Count, Is.EqualTo(2));

var structuredClassifiersPackageEnumerations = structuredClassifiersPackage.PackagedElement.OfType<IEnumeration>();

Assert.That(structuredClassifiersPackageEnumerations.Count, Is.EqualTo(1));

var connectorKindEnumeration = structuredClassifiersPackageEnumerations.Single();

Assert.That(connectorKindEnumeration.Name, Is.EqualTo("ConnectorKind"));
Assert.That(connectorKindEnumeration.OwnedComment.First().Body, Is.EqualTo("ConnectorKind is an enumeration that defines whether a Connector is an assembly or a delegation."));

Assert.That(connectorKindEnumeration.OwnedLiteral.Count, Is.EqualTo(2));

var connectorKindEnumerationEnumerationLiteralAssembly = connectorKindEnumeration.OwnedLiteral.First();

Assert.That(connectorKindEnumerationEnumerationLiteralAssembly.Name, Is.EqualTo("assembly"));
Assert.That(connectorKindEnumerationEnumerationLiteralAssembly.OwnedComment.First().Body, Is.EqualTo("Indicates that the Connector is an assembly Connector."));

}
}
}
5 changes: 4 additions & 1 deletion uml4net.xmireader/Packages/PackageReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace uml4net.xmi.Packages
using uml4net.POCO.Packages;

using uml4net.xmi.CommonStructure;
using uml4net.xmi.SimpleClassifiers;
using uml4net.xmi.StructuredClassifiers;

/// <summary>
Expand Down Expand Up @@ -181,7 +182,9 @@ private void ReadPackagedElements(IPackage package, XmlReader xmlReader)
case "uml:Enumeration":
using (var enumerationXmlReader = xmlReader.ReadSubtree())
{
this.logger.LogDebug("uml:Enumeration not yet implements");
var enumerationReader = new EnumerationReader();
var enumeration = enumerationReader.Read(enumerationXmlReader);
package.PackagedElement.Add(enumeration);
}
break;
case "uml:Package":
Expand Down
116 changes: 116 additions & 0 deletions uml4net.xmireader/SimpleClassifiers/EnumerationLiteralReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="EnumerationLiteralReader.cs" company="Starion Group S.A.">
//
// Copyright 2019-2024 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, softwareUseCases
// 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>
// ------------------------------------------------------------------------------------------------

namespace uml4net.xmi.SimpleClassifiers
{
using System;
using System.Xml;

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

using uml4net.POCO.CommonStructure;
using uml4net.POCO.SimpleClassifiers;
using uml4net.POCO.StructuredClassifiers;
using uml4net.xmi.Classification;
using uml4net.xmi.CommonStructure;

/// <summary>
/// The purpose of the <see cref="EnumerationLiteralReader"/> is to read an instance of <see cref="IEnumerationLiteral"/>
/// from the XMI document
/// </summary>
public class EnumerationLiteralReader
{
/// <summary>
/// The (injected) <see cref="ILoggerFactory"/> used to setup logging
/// </summary>
private readonly ILoggerFactory loggerFactory;

/// <summary>
/// The <see cref="ILogger"/> used to log
/// </summary>
private readonly ILogger<EnumerationLiteralReader> logger;

/// <summary>
/// Initializes a new instance of the <see cref="EnumerationLiteralReader"/> class.
/// </summary>
/// <param name="loggerFactory">
/// The (injected) <see cref="ILoggerFactory"/> used to setup logging
/// </param>
public EnumerationLiteralReader(ILoggerFactory loggerFactory = null)
{
this.loggerFactory = loggerFactory;

this.logger = this.loggerFactory == null ? NullLogger<EnumerationLiteralReader>.Instance : this.loggerFactory.CreateLogger<EnumerationLiteralReader>();
}

/// <summary>
/// Reads the <see cref="IEnumeration"/> object from its XML representation
/// </summary>
/// <param name="xmlReader">
/// an instance of <see cref="XmlReader"/>
/// </param>
/// <returns>
/// an instance of <see cref="IEnumeration"/>
/// </returns>
public IEnumerationLiteral Read(XmlReader xmlReader)
{
IEnumerationLiteral enumerationLiteral = new EnumerationLiteral();

if (xmlReader.MoveToContent() == XmlNodeType.Element)
{
enumerationLiteral.XmiId = xmlReader.GetAttribute("xmi:id");

var xmiType = xmlReader.GetAttribute("xmi:type");

if (xmiType != "uml:EnumerationLiteral")
{
throw new XmlException($"The XmiType should be: uml:EnumerationLiteral while it is {xmiType}");
}

enumerationLiteral.XmiType = xmlReader.GetAttribute("xmi:type");

enumerationLiteral.Name = xmlReader.GetAttribute("name");

while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
switch (xmlReader.LocalName)
{
case "ownedComment":
using (var ownedCommentXmlReader = xmlReader.ReadSubtree())
{
var commentReader = new CommentReader(this.loggerFactory);
var comment = commentReader.Read(ownedCommentXmlReader);
enumerationLiteral.OwnedComment.Add(comment);
}
break;
default:
throw new NotImplementedException($"EnumerationLiteralReader: {xmlReader.LocalName}");
}
}
}
}

return enumerationLiteral;
}
}
}
126 changes: 126 additions & 0 deletions uml4net.xmireader/SimpleClassifiers/EnumerationReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="EnumerationReader.cs" company="Starion Group S.A.">
//
// Copyright 2019-2024 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, softwareUseCases
// 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>
// ------------------------------------------------------------------------------------------------

namespace uml4net.xmi.SimpleClassifiers
{
using System;
using System.Xml;

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

using uml4net.POCO.CommonStructure;
using uml4net.POCO.SimpleClassifiers;
using uml4net.POCO.StructuredClassifiers;
using uml4net.xmi.Classification;
using uml4net.xmi.CommonStructure;

/// <summary>
/// The purpose of the <see cref="EnumerationReader"/> is to read an instance of <see cref="IEnumeration"/>
/// from the XMI document
/// </summary>
public class EnumerationReader
{
/// <summary>
/// The (injected) <see cref="ILoggerFactory"/> used to setup logging
/// </summary>
private readonly ILoggerFactory loggerFactory;

/// <summary>
/// The <see cref="ILogger"/> used to log
/// </summary>
private readonly ILogger<EnumerationReader> logger;

/// <summary>
/// Initializes a new instance of the <see cref="EnumerationReader"/> class.
/// </summary>
/// <param name="loggerFactory">
/// The (injected) <see cref="ILoggerFactory"/> used to setup logging
/// </param>
public EnumerationReader(ILoggerFactory loggerFactory = null)
{
this.loggerFactory = loggerFactory;

this.logger = this.loggerFactory == null ? NullLogger<EnumerationReader>.Instance : this.loggerFactory.CreateLogger<EnumerationReader>();
}

/// <summary>
/// Reads the <see cref="IEnumeration"/> object from its XML representation
/// </summary>
/// <param name="xmlReader">
/// an instance of <see cref="XmlReader"/>
/// </param>
/// <returns>
/// an instance of <see cref="IEnumeration"/>
/// </returns>
public IEnumeration Read(XmlReader xmlReader)
{
IEnumeration enumeration = new Enumeration();

if (xmlReader.MoveToContent() == XmlNodeType.Element)
{
enumeration.XmiId = xmlReader.GetAttribute("xmi:id");

var xmiType = xmlReader.GetAttribute("xmi:type");

if (xmiType != "uml:Enumeration")
{
throw new XmlException($"The XmiType should be: uml:Enumeration while it is {xmiType}");
}

enumeration.XmiType = xmlReader.GetAttribute("xmi:type");

enumeration.Name = xmlReader.GetAttribute("name");

while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
switch (xmlReader.LocalName)
{
case "ownedComment":
using (var ownedCommentXmlReader = xmlReader.ReadSubtree())
{
var commentReader = new CommentReader(this.loggerFactory);
var comment = commentReader.Read(ownedCommentXmlReader);
enumeration.OwnedComment.Add(comment);
}
break;
case "ownedLiteral":
using (var ownedLiteralXmlReader = xmlReader.ReadSubtree())
{
var enumerationLiteralReader = new EnumerationLiteralReader(this.loggerFactory);
var enumerationLiteral = enumerationLiteralReader.Read(ownedLiteralXmlReader);
enumeration.OwnedLiteral.Add(enumerationLiteral);

this.logger.LogInformation("ClassReader.ownedRule not yet implemented");
}
break;
default:
throw new NotImplementedException($"ClassReader: {xmlReader.LocalName}");
}
}
}
}

return enumeration;
}
}
}
8 changes: 8 additions & 0 deletions uml4net/POCO/SimpleClassifiers/Enumeration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,5 +354,13 @@ public class Enumeration : IEnumeration
[Property(aggregation: AggregationKind.None, lowerValue: 0, upperValue: int.MaxValue, isReadOnly: true, isDerived: true, isDerivedUnion: true)]
[Implements(implementation: "IRedefinableElement.RedefinitionContext")]
public IClassifier RedefinitionContext => throw new NotImplementedException();

/// <summary>
/// The ordered set of literals owned by this Enumeration.
/// </summary>
[Property(aggregation: AggregationKind.Composite, lowerValue: 0, upperValue: int.MaxValue)]
[SubsettedProperty("Namespace-ownedMember")]
[Implements(implementation: "IEnumeration.OwnedLiteral")]
public List<IEnumerationLiteral> OwnedLiteral { get; set; } = new();
}
}
18 changes: 17 additions & 1 deletion uml4net/POCO/SimpleClassifiers/EnumerationLiteral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public class EnumerationLiteral : IEnumerationLiteral
/// </summary>
[Property(aggregation: AggregationKind.None, lowerValue: 0, upperValue: int.MaxValue)]
[Implements("IInstanceSpecification.Classifier")]
public List<IClassifier> Classifier { get; set; } = new List<IClassifier>();
List<IClassifier> IInstanceSpecification.Classifier { get; set; } = new List<IClassifier>();

/// <summary>
/// A Slot giving the value or values of a StructuralFeature of the instance. An InstanceSpecification
Expand All @@ -161,5 +161,21 @@ public class EnumerationLiteral : IEnumerationLiteral
[Property(aggregation: AggregationKind.Composite, lowerValue: 0, upperValue: 1)]
[Implements("IInstanceSpecification.Specification")]
public IValueSpecification Specification { get; set; }

/// <summary>
/// The classifier of this EnumerationLiteral derived to be equal to its Enumeration.
/// </summary>
[Property(aggregation: AggregationKind.None, lowerValue: 0, upperValue: 1, isReadOnly: true, isDerived: true)]
[RedefinedProperty("InstanceSpecification-classifier")]
[Implements("IEnumeration.Classifier")]
public IEnumeration Classifier => throw new NotImplementedException();

/// <summary>
/// The Enumeration that this EnumerationLiteral is a member of.
/// </summary>
[Property(aggregation: AggregationKind.None, lowerValue: 1, upperValue: 1)]
[SubsettedProperty("NamedElement-namespace")]
[Implements("IEnumeration.Enumeration")]
public IEnumeration Enumeration { get; set; }
}
}
11 changes: 11 additions & 0 deletions uml4net/POCO/SimpleClassifiers/IEnumeration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,21 @@

namespace uml4net.POCO.SimpleClassifiers
{
using System.Collections.Generic;

using uml4net.Decorators;
using uml4net.POCO.Classification;

/// <summary>
/// An Enumeration is a DataType whose values are enumerated in the model as EnumerationLiterals.
/// </summary>
public interface IEnumeration : IDataType
{
/// <summary>
/// The ordered set of literals owned by this Enumeration.
/// </summary>
[Property(aggregation: AggregationKind.Composite, lowerValue: 0, upperValue: int.MaxValue)]
[SubsettedProperty("Namespace-ownedMember")]
public List<IEnumerationLiteral> OwnedLiteral { get; set; }
}
}
14 changes: 14 additions & 0 deletions uml4net/POCO/SimpleClassifiers/IEnumerationLiteral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,26 @@

namespace uml4net.POCO.SimpleClassifiers
{
using uml4net.Decorators;
using uml4net.POCO.Classification;

/// <summary>
/// An EnumerationLiteral is a user-defined data value for an Enumeration.
/// </summary>
public interface IEnumerationLiteral : IInstanceSpecification
{
/// <summary>
/// The classifier of this EnumerationLiteral derived to be equal to its Enumeration.
/// </summary>
[Property(aggregation: AggregationKind.None, lowerValue: 1, upperValue: 1, isReadOnly:true, isDerived:true)]
[RedefinedProperty("InstanceSpecification-classifier")]
public new IEnumeration Classifier { get; }

/// <summary>
/// The Enumeration that this EnumerationLiteral is a member of.
/// </summary>
[Property(aggregation: AggregationKind.None, lowerValue: 1, upperValue: 1)]
[SubsettedProperty("NamedElement-namespace")]
public IEnumeration Enumeration { get; set; }
}
}

0 comments on commit a3fe68c

Please sign in to comment.