From 7d13d9245dba42a91157a7384b712780c6973037 Mon Sep 17 00:00:00 2001 From: Smiechowski Nathanael Date: Thu, 14 Nov 2024 09:33:12 +0100 Subject: [PATCH] [FIX] #60 (#61) * [FIX] #60 --- uml4net.Extensions/ClassExtensions.cs | 59 +++++++++++++++ uml4net.Extensions/ClassifierExtensions.cs | 52 +++++++++++++ uml4net.Extensions/PropertyExtensions.cs | 54 ++++++++++---- uml4net.HandleBars/PropertyHelper.cs | 74 +++++++++++++++++-- .../Generators/ModelInspectorTestFixture.cs | 2 +- .../uml4net.Reporting.Tests.csproj | 2 +- uml4net.xmi.Tests/AssemblerTestFixture.cs | 62 +++++++++++++++- uml4net.xmi.Tests/uml4net.xmi.Tests.csproj | 2 +- uml4net.xmireader/Cache/Assembler.cs | 24 +----- uml4net.xmireader/Cache/IXmiReaderCache.cs | 20 ++++- uml4net.xmireader/Cache/XmiReaderCache.cs | 33 ++++++--- uml4net/Extend/ClassExtensions.cs | 46 ++++++++++++ .../HandCoded/StructuredClassifiers/Class.cs | 37 ---------- uml4net/POCO/StructuredClassifiers/Class.cs | 2 +- 14 files changed, 369 insertions(+), 100 deletions(-) create mode 100644 uml4net.Extensions/ClassExtensions.cs create mode 100644 uml4net.Extensions/ClassifierExtensions.cs create mode 100644 uml4net/Extend/ClassExtensions.cs delete mode 100644 uml4net/POCO/HandCoded/StructuredClassifiers/Class.cs diff --git a/uml4net.Extensions/ClassExtensions.cs b/uml4net.Extensions/ClassExtensions.cs new file mode 100644 index 00000000..e164a3db --- /dev/null +++ b/uml4net.Extensions/ClassExtensions.cs @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// 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. +// +// +// ------------------------------------------------------------------------------------------------ + +namespace uml4net.Extensions +{ + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + + using uml4net.POCO.Classification; + using uml4net.POCO.StructuredClassifiers; + + /// + /// Extension methods for interface + /// + public static class ClassExtensions + { + /// + /// Queries all the properties that are implemented by the class directly or through superclasses + /// or interface implementations + /// + /// The from which to query the properties + /// A of + public static ReadOnlyCollection QueryAllProperties(this IClass @class) + { + var result = new List(); + + var superClassifiers = @class.QueryAllGeneralClassifiers(); + + foreach (var classifier in superClassifiers) + { + if (classifier is IClass c) + { + result.AddRange(c.OwnedAttribute); + result.AddRange(c.QueryInterfaces().SelectMany(x => x.Attribute).Distinct()); + } + } + + return result.Distinct().ToList().AsReadOnly(); + } + } +} diff --git a/uml4net.Extensions/ClassifierExtensions.cs b/uml4net.Extensions/ClassifierExtensions.cs new file mode 100644 index 00000000..c2e47be3 --- /dev/null +++ b/uml4net.Extensions/ClassifierExtensions.cs @@ -0,0 +1,52 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2024 Starion Group N.V. +// +// Author: Seliman Niakate, Sebastien d'Antuono, Nathanael Smiechowski, Amine Nemmaoui, Amir Janati. +// +// This file is part of the SafePlace solution. +// +// SafePlace is distributed under the terms and conditions of the +// European Space Agency Public License (ESA-PL) Weak Copyleft (Type 2) – v2.4 +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace uml4net.Extensions +{ + using POCO.Classification; + using System.Collections.Generic; + + using System.Collections.ObjectModel; + using System.Linq; + + /// + /// The class provides extensions methods for the + /// + public static class ClassifierExtensions + { + /// + /// Queries all the general s of the subject + /// + /// + /// the subject + /// + /// + /// a readonly collection of s, including the subject , of + /// all the super classifiers + /// + public static ReadOnlyCollection QueryAllGeneralClassifiers(this IClassifier classifier) + { + var result = new List { classifier }; + + if (classifier.Generalization != null) + { + foreach (var generalization in classifier.Generalization) + { + result.AddRange(generalization.General.QueryAllGeneralClassifiers()); + } + } + + return result.Distinct().ToList().AsReadOnly(); + } + } +} diff --git a/uml4net.Extensions/PropertyExtensions.cs b/uml4net.Extensions/PropertyExtensions.cs index 4579877e..5870c9e6 100644 --- a/uml4net.Extensions/PropertyExtensions.cs +++ b/uml4net.Extensions/PropertyExtensions.cs @@ -22,7 +22,6 @@ namespace uml4net.Extensions { using POCO.Values; using System; - using uml4net.POCO.Classification; using uml4net.POCO.SimpleClassifiers; using uml4net.POCO.StructuredClassifiers; @@ -47,17 +46,44 @@ public static bool QueryIsEnum(this IProperty property) } /// - /// Queries whether the type of the is an + /// Queries whether the type of the is of type boolean /// /// /// The subject /// /// - /// true of the type is a , false if not + /// true if the type is a , false if not /// - public static bool QueryIsPrimitiveType(this IProperty property) + public static bool QueryIsBool(this IProperty property) { - return property.Type is IPrimitiveType; + return property?.Type?.Name?.IndexOf("bool", StringComparison.InvariantCultureIgnoreCase) >= 0; + } + + /// + /// Queries whether the type of the is a numeric type (e.g., int, double, decimal, float, etc.) + /// + /// + /// The subject + /// + /// + /// true if the type is a numeric type (e.g., int, double, decimal, float), false otherwise. + /// + public static bool QueryIsNumeric(this IProperty property) + { + if (property?.Type?.Name == null) + { + return false; + } + + var typeName = property.Type.Name.ToLowerInvariant(); + + return typeName.Contains("int") || + typeName.Contains("float") || + typeName.Contains("double") || + typeName.Contains("decimal") || + typeName.Contains("short") || + typeName.Contains("long") || + typeName.Contains("byte"); } /// @@ -71,7 +97,7 @@ public static bool QueryIsPrimitiveType(this IProperty property) /// public static bool QueryIsEnumerable(this IProperty property) { - var value = property.UpperValue switch + var value = property?.UpperValue switch { ILiteralUnlimitedNatural literalUnlimitedNatural => literalUnlimitedNatural.Value, ILiteralInteger literalInteger => literalInteger.Value, @@ -146,7 +172,7 @@ public static string QueryTypeName(this IProperty property) } /// - /// Queries a value indicating whether the specified type is a value type or + /// Queries a value indicating whether the specified is a reference type /// /// /// The subject @@ -154,17 +180,13 @@ public static string QueryTypeName(this IProperty property) /// /// A /// - /// - /// The and are concrete subtypes of the - /// concrete type - /// - public static bool QueryIsValueProperty(this IProperty property) + public static bool QueryIsReferenceProperty(this IProperty property) { - return property.Type is IDataType; + return property.Type is not IDataType; } /// - /// Queries a value indicating whether the specified is a reference type + /// Queries a value indicating whether the specified type is a value type or /// /// /// The subject @@ -172,9 +194,9 @@ public static bool QueryIsValueProperty(this IProperty property) /// /// A /// - public static bool QueryIsReferenceProperty(this IProperty property) + public static bool QueryIsValueProperty(this IProperty property) { - return property.Type is not IDataType; + return property.Type is IDataType; } /// diff --git a/uml4net.HandleBars/PropertyHelper.cs b/uml4net.HandleBars/PropertyHelper.cs index ce2a4b11..013b699f 100644 --- a/uml4net.HandleBars/PropertyHelper.cs +++ b/uml4net.HandleBars/PropertyHelper.cs @@ -54,7 +54,7 @@ public static void RegisterStructuralFeatureHelper(this IHandlebars handlebars) return property.QueryIsEnumerable(); }); - + handlebars.RegisterHelper("Property.IsEnumerable", (output, options, context, arguments) => { if (arguments.Length != 1) @@ -115,7 +115,7 @@ public static void RegisterStructuralFeatureHelper(this IHandlebars handlebars) return property.QueryIsEnum(); }); - handlebars.RegisterHelper("Property.IsEnum", (output, options, context, arguments) => + handlebars.RegisterHelper("Property.IsEnum", (context, arguments) => { if (arguments.Length != 1) { @@ -124,12 +124,76 @@ public static void RegisterStructuralFeatureHelper(this IHandlebars handlebars) var property = arguments.Single() as IProperty; - var isEnum = property.QueryIsEnum(); + return property.QueryIsEnum(); + }); - if (isEnum) + handlebars.RegisterHelper("Property.QueryIsBool", (context, arguments) => + { + if (arguments.Length != 1) { - options.Template(output, context); + throw new HandlebarsException("{{#Property.QueryIsBool}} helper must have exactly one argument"); + } + + var property = arguments.Single() as IProperty; + + return property.QueryIsBool(); + }); + + handlebars.RegisterHelper("Property.QueryIsNumeric", (context, arguments) => + { + if (arguments.Length != 1) + { + throw new HandlebarsException("{{#Property.QueryIsNumeric}} helper must have exactly one argument"); + } + + var property = arguments.Single() as IProperty; + + return property.QueryIsNumeric(); + }); + + handlebars.RegisterHelper("Property.QueryIsInteger", (context, arguments) => + { + if (arguments.Length != 1) + { + throw new HandlebarsException("{{#Property.QueryIsInteger}} helper must have exactly one argument"); } + + var property = arguments.Single() as IProperty; + + return property?.Type?.Name.ToLowerInvariant().Contains("int"); + }); + + handlebars.RegisterHelper("Property.QueryIsFloat", (context, arguments) => + { + if (arguments.Length != 1) + { + throw new HandlebarsException("{{#Property.QueryIsFloat}} helper must have exactly one argument"); + } + + var typeName = (arguments.Single() as IProperty)?.Type?.Name?.ToLowerInvariant(); + return typeName is not null && (typeName.Contains("single") || typeName.Contains("float")); + }); + + handlebars.RegisterHelper("Property.QueryIsDouble", (context, arguments) => + { + if (arguments.Length != 1) + { + throw new HandlebarsException("{{#Property.QueryIsDouble}} helper must have exactly one argument"); + } + + var typeName = (arguments.Single() as IProperty)?.Type?.Name?.ToLowerInvariant(); + return typeName?.Contains("double"); + }); + + handlebars.RegisterHelper("Property.QueryIsDateTime", (context, arguments) => + { + if (arguments.Length != 1) + { + throw new HandlebarsException("{{#Property.QueryIsDouble}} helper must have exactly one argument"); + } + + var typeName = (arguments.Single() as IProperty)?.Type?.Name?.ToLowerInvariant(); + return typeName?.Contains("date"); }); handlebars.RegisterHelper("Property.QueryHasDefaultValue", (context, arguments) => diff --git a/uml4net.Reporting.Tests/Generators/ModelInspectorTestFixture.cs b/uml4net.Reporting.Tests/Generators/ModelInspectorTestFixture.cs index 81ec9e06..611767fc 100644 --- a/uml4net.Reporting.Tests/Generators/ModelInspectorTestFixture.cs +++ b/uml4net.Reporting.Tests/Generators/ModelInspectorTestFixture.cs @@ -1,4 +1,4 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // // Copyright 2019-2024 Starion Group S.A. diff --git a/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj b/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj index 4006e6fd..8760415f 100644 --- a/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj +++ b/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj @@ -1,4 +1,4 @@ - + net8.0 diff --git a/uml4net.xmi.Tests/AssemblerTestFixture.cs b/uml4net.xmi.Tests/AssemblerTestFixture.cs index 68ffe2bc..a5e82834 100644 --- a/uml4net.xmi.Tests/AssemblerTestFixture.cs +++ b/uml4net.xmi.Tests/AssemblerTestFixture.cs @@ -26,6 +26,7 @@ namespace uml4net.xmi.Tests using System; using POCO.Classification; using POCO.SimpleClassifiers; + using System.Linq; using uml4net.POCO.CommonStructure; using uml4net.POCO.StructuredClassifiers; using uml4net.POCO.Values; @@ -112,6 +113,63 @@ public void Synchronize_ShouldSetMultiValueReference() }); } + [Test] + public void Synchronize_ShouldSetMultiValueReferenceFromExternalXmi() + { + // Arrange + const string externalXmi0 = "otherxmi"; + const string externalXmi1 = "anotherone"; + + var classElement0 = new Class { XmiId = Guid.NewGuid().ToString(), Name = "TestClass0"}; + var classElement1 = new Class { XmiId = Guid.NewGuid().ToString(), Name = "TestClass1" }; + var stringType = new PrimitiveType { XmiId = Guid.NewGuid().ToString(), Name = "string" }; + + var attribute0 = new Property + { + XmiId = Guid.NewGuid().ToString(), + SingleValueReferencePropertyIdentifiers = { { nameof(Property.Type), $"{externalXmi1}#{stringType.XmiId}" } } + }; + + var attribute1 = new Property + { + XmiId = Guid.NewGuid().ToString(), + SingleValueReferencePropertyIdentifiers = { { nameof(Property.Type), $"{externalXmi1}#{classElement1.XmiId}" } } + }; + + var comment1 = new Comment { XmiId = Guid.NewGuid().ToString(), Body = "Comment 1" }; + var comment2 = new Comment { XmiId = Guid.NewGuid().ToString(), Body = "Comment 2" }; + + classElement0.MultiValueReferencePropertyIdentifiers.Add("OwnedComment", [comment1.XmiId, comment2.XmiId]); + classElement0.MultiValueReferencePropertyIdentifiers.Add("OwnedAttribute", [$"{externalXmi0}#{attribute0.XmiId}", $"{externalXmi1}#{attribute1.XmiId}"]); + + this.cache.Add(classElement0.XmiId, classElement0); + this.cache.Add(comment1.XmiId, comment1); + this.cache.Add(comment2.XmiId, comment2); + + this.cache.SwitchContext(externalXmi0); + this.cache.Add(attribute0.XmiId, attribute0); + + this.cache.SwitchContext(externalXmi1); + this.cache.Add(attribute1.XmiId, attribute1); + this.cache.Add(classElement1.XmiId, classElement1); + this.cache.Add(stringType.XmiId, stringType); + + // Act + this.assembler.Synchronize(); + + // Assert + Assert.Multiple(() => + { + Assert.That(classElement0.OwnedComment.Count, Is.EqualTo(2)); + Assert.That(classElement0.OwnedComment.Contains(comment1)); + Assert.That(classElement0.OwnedComment.Contains(comment2)); + Assert.That(classElement0.OwnedAttribute.Contains(attribute0)); + Assert.That(classElement0.OwnedAttribute.Contains(attribute1)); + Assert.That(classElement0.OwnedAttribute.Single(x => x.XmiId == attribute1.XmiId).Type, Is.SameAs(classElement1)); + Assert.That(classElement0.OwnedAttribute.Single(x => x.XmiId == attribute0.XmiId).Type, Is.SameAs(stringType)); + }); + } + [Test] public void Synchronize_ShouldSetSingleValueReferenceAndMultipleValuesReference() { @@ -251,7 +309,7 @@ public void Synchronize_ShouldThrow_WhenElementNotIReferenceable() [Test] public void Synchronize_verify_that_type_is_set() { - var property = new Property() + var property = new Property { XmiId = "Property-aggregation", Name = "aggregation" @@ -259,7 +317,7 @@ public void Synchronize_verify_that_type_is_set() property.SingleValueReferencePropertyIdentifiers.Add("type", "AggregationKind"); - var enumeration = new Enumeration() + var enumeration = new Enumeration { XmiId = "AggregationKind", Name = "AggregationKind", diff --git a/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj b/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj index 0fd98eb0..ee34e4d7 100644 --- a/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj +++ b/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj @@ -1,4 +1,4 @@ - + net8.0 diff --git a/uml4net.xmireader/Cache/Assembler.cs b/uml4net.xmireader/Cache/Assembler.cs index 498d71c2..21af07bd 100644 --- a/uml4net.xmireader/Cache/Assembler.cs +++ b/uml4net.xmireader/Cache/Assembler.cs @@ -126,27 +126,9 @@ public void ResolveReferences(IXmiElement element) /// true if the referenced element was successfully retrieved; otherwise, false. private bool TryGetReferencedElement(string referenceIdKey, out IXmiElement element) { - var isContextResolved = this.cache.TryResolveContext(referenceIdKey, out var resolvedContextAndResource); - - if (isContextResolved) - { - var isValueFound = this.cache.TryGetValue(resolvedContextAndResource.Context, resolvedContextAndResource.ResourceId, out element); - return isValueFound; - } - - foreach (var globalCacheKey in this.cache.GlobalCache.Keys) - { - var cache = this.cache.GlobalCache[globalCacheKey]; - var isFallbackFound = cache.TryGetValue(referenceIdKey, out element); - - if (isFallbackFound) - { - return true; - } - } - - element = null; - return false; + return this.cache.TryResolveContext(referenceIdKey, out var resolvedContextAndResource, true) + ? this.cache.TryGetValue(resolvedContextAndResource.Context, resolvedContextAndResource.ResourceId, out element) + : this.cache.Cache.TryGetValue(referenceIdKey, out element); } /// diff --git a/uml4net.xmireader/Cache/IXmiReaderCache.cs b/uml4net.xmireader/Cache/IXmiReaderCache.cs index bc6eef7d..b6bd9188 100644 --- a/uml4net.xmireader/Cache/IXmiReaderCache.cs +++ b/uml4net.xmireader/Cache/IXmiReaderCache.cs @@ -95,9 +95,21 @@ public interface IXmiReaderCache /// /// Attempts to resolve the context and resource ID from the specified resource key. /// - /// The key representing the resource, which may contain context and resource ID separated by '#'. - /// When this method returns, contains a tuple with the context and resource ID if resolved successfully; otherwise, (null, null). - /// true if the context and resource ID were successfully resolved; otherwise, false. - bool TryResolveContext(string resourceKey, out (string Context, string ResourceId) resolvedContextAndResource); + /// + /// The key representing the resource, which may contain context and resource ID separated by '#'. + /// + /// + /// When this method returns, contains a tuple with the resolved context and resource ID if successful; + /// otherwise, (null, null) if unsuccessful. + /// + /// + /// If true, checks whether the resolved context exists in the global cache. If false, + /// performs no such check. + /// + /// + /// true if the context and resource ID were successfully resolved and, if applicable, the + /// context exists in the global cache; otherwise, false. + /// + bool TryResolveContext(string resourceKey, out (string Context, string ResourceId) resolvedContextAndResource, bool validateContextExistence = false); } } diff --git a/uml4net.xmireader/Cache/XmiReaderCache.cs b/uml4net.xmireader/Cache/XmiReaderCache.cs index 003f7352..03d2781b 100644 --- a/uml4net.xmireader/Cache/XmiReaderCache.cs +++ b/uml4net.xmireader/Cache/XmiReaderCache.cs @@ -147,21 +147,32 @@ public void Add(string id, IXmiElement element) /// /// Attempts to resolve the context and resource ID from the specified resource key. /// - /// The key representing the resource, which may contain context and resource ID separated by '#'. - /// When this method returns, contains a tuple with the context and resource ID if resolved successfully; otherwise, (null, null). - /// true if the context and resource ID were successfully resolved; otherwise, false. - public bool TryResolveContext(string resourceKey, out (string Context, string ResourceId) resolvedContextAndResource) + /// + /// The key representing the resource, which may contain context and resource ID separated by '#'. + /// + /// + /// When this method returns, contains a tuple with the resolved context and resource ID if successful; + /// otherwise, (null, null) if unsuccessful. + /// + /// + /// If true, checks whether the resolved context exists in the global cache. If false, + /// performs no such check. + /// + /// + /// true if the context and resource ID were successfully resolved and, if applicable, the + /// context exists in the global cache; otherwise, false. + /// + public bool TryResolveContext(string resourceKey, out (string Context, string ResourceId) resolvedContextAndResource, bool validateContextExistence = false) { var referenceString = resourceKey.Split(['#'], StringSplitOptions.RemoveEmptyEntries); - if (referenceString.Length == 2) + resolvedContextAndResource = referenceString.Length switch { - resolvedContextAndResource = (referenceString[0], referenceString[1]); - return true; - } - - resolvedContextAndResource = (null, null); - return false; + 2 => (referenceString[0], referenceString[1]), + _ => (DefaultKey, resourceKey) + }; + + return !validateContextExistence || this.GlobalCache.ContainsKey(resolvedContextAndResource.Context); } } } diff --git a/uml4net/Extend/ClassExtensions.cs b/uml4net/Extend/ClassExtensions.cs new file mode 100644 index 00000000..9038b0b0 --- /dev/null +++ b/uml4net/Extend/ClassExtensions.cs @@ -0,0 +1,46 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// 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. +// +// +// ------------------------------------------------------------------------------------------------ + +namespace uml4net.Extend +{ + using System.Collections.Generic; + using System.Linq; + + using uml4net.POCO.StructuredClassifiers; + + /// + /// The class provides extensions methods for the + /// + public static class ClassExtensions + { + /// + /// Retrieves the list of immediate superclasses for the specified class, based on its generalizations. + /// + /// + /// The instance whose superclasses are being queried. + /// + /// + /// A list of objects representing the immediate superclasses of the specified class. + /// If no superclasses are defined, returns an empty list. + /// + public static List QuerySuperClass(this IClass @class) => + @class.Generalization.Select(x => x.General).OfType().ToList(); + } +} \ No newline at end of file diff --git a/uml4net/POCO/HandCoded/StructuredClassifiers/Class.cs b/uml4net/POCO/HandCoded/StructuredClassifiers/Class.cs deleted file mode 100644 index 07f83e57..00000000 --- a/uml4net/POCO/HandCoded/StructuredClassifiers/Class.cs +++ /dev/null @@ -1,37 +0,0 @@ -// ------------------------------------------------------------------------------------------------- -// -// -// 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. -// -// -// ------------------------------------------------------------------------------------------------ - -namespace uml4net.POCO.StructuredClassifiers -{ - using System.Collections.Generic; - using System.Linq; - - /// - /// 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 - /// - public partial class Class - { - /// - /// Queries the superclasses of a Class, derived from its Generalizations. - /// - private List QuerySuperClass() => this.Generalization.Select(x => x.General).OfType().ToList(); - } -} diff --git a/uml4net/POCO/StructuredClassifiers/Class.cs b/uml4net/POCO/StructuredClassifiers/Class.cs index 35356b10..98197bd7 100644 --- a/uml4net/POCO/StructuredClassifiers/Class.cs +++ b/uml4net/POCO/StructuredClassifiers/Class.cs @@ -37,7 +37,7 @@ namespace uml4net.POCO.StructuredClassifiers /// 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 /// - public partial class Class : XmiElement, IClass + public class Class : XmiElement, IClass { /// /// The Comments owned by this Element.