Skip to content

Commit

Permalink
[FIX] #60 (#61)
Browse files Browse the repository at this point in the history
* [FIX] #60
  • Loading branch information
nathanatstariongroup authored Nov 14, 2024
1 parent 5b871f7 commit 7d13d92
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 100 deletions.
59 changes: 59 additions & 0 deletions uml4net.Extensions/ClassExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="ClassExtensions.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.Extensions
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

using uml4net.POCO.Classification;
using uml4net.POCO.StructuredClassifiers;

/// <summary>
/// Extension methods for <see cref="IClass"/> interface
/// </summary>
public static class ClassExtensions
{
/// <summary>
/// Queries all the properties that are implemented by the class directly or through superclasses
/// or interface implementations
/// </summary>
/// <param name="class">The <see cref="IClass"/> from which to query the properties</param>
/// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="IProperty"/></returns>
public static ReadOnlyCollection<IProperty> QueryAllProperties(this IClass @class)
{
var result = new List<IProperty>();

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();
}
}
}
52 changes: 52 additions & 0 deletions uml4net.Extensions/ClassifierExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ClassifierExtensions.cs" company="Starion Group N.V.">
// 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
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace uml4net.Extensions
{
using POCO.Classification;
using System.Collections.Generic;

using System.Collections.ObjectModel;
using System.Linq;

/// <summary>
/// The <see cref="ClassifierExtensions"/> class provides extensions methods for the <see cref="IClassifier"/>
/// </summary>
public static class ClassifierExtensions
{
/// <summary>
/// Queries all the general <see cref="IClassifier"/>s of the subject <see cref="IClassifier"/>
/// </summary>
/// <param name="classifier">
/// the subject <see cref="IClassifier"/>
/// </param>
/// <returns>
/// a readonly collection of <see cref="IClassifier"/>s, including the subject <see cref="IClassifier"/>, of
/// all the super classifiers
/// </returns>
public static ReadOnlyCollection<IClassifier> QueryAllGeneralClassifiers(this IClassifier classifier)
{
var result = new List<IClassifier> { classifier };

if (classifier.Generalization != null)
{
foreach (var generalization in classifier.Generalization)
{
result.AddRange(generalization.General.QueryAllGeneralClassifiers());
}
}

return result.Distinct().ToList().AsReadOnly();
}
}
}
54 changes: 38 additions & 16 deletions uml4net.Extensions/PropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ namespace uml4net.Extensions
{
using POCO.Values;
using System;

using uml4net.POCO.Classification;
using uml4net.POCO.SimpleClassifiers;
using uml4net.POCO.StructuredClassifiers;
Expand All @@ -47,17 +46,44 @@ public static bool QueryIsEnum(this IProperty property)
}

/// <summary>
/// Queries whether the type of the <see cref="IProperty"/> is an <see cref="IPrimitiveType"/>
/// Queries whether the type of the <see cref="IProperty"/> is of type boolean
/// </summary>
/// <param name="property">
/// The subject <see cref="IProperty"/>
/// </param>
/// <returns>
/// true of the type is a <see cref="IPrimitiveType"/>, false if not
/// true if the type is a <see cref="bool"/>, false if not
/// </returns>
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;
}

/// <summary>
/// Queries whether the type of the <see cref="IProperty"/> is a numeric type (e.g., int, double, decimal, float, etc.)
/// </summary>
/// <param name="property">
/// The subject <see cref="IProperty"/>
/// </param>
/// <returns>
/// true if the type is a numeric type (e.g., int, double, decimal, float), false otherwise.
/// </returns>
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");
}

/// <summary>
Expand All @@ -71,7 +97,7 @@ public static bool QueryIsPrimitiveType(this IProperty property)
/// </returns>
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,
Expand Down Expand Up @@ -146,35 +172,31 @@ public static string QueryTypeName(this IProperty property)
}

/// <summary>
/// Queries a value indicating whether the specified <see cref="IProperty"/> type is a value type or <see cref="string"/>
/// Queries a value indicating whether the specified <see cref="IProperty"/> is a reference type
/// </summary>
/// <param name="property">
/// The subject <see cref="IProperty"/>
/// </param>
/// <returns>
/// A <see cref="bool"/>
/// </returns>
/// <remarks>
/// The <see cref="IPrimitiveType"/> and <see cref="IEnumeration"/> are concrete subtypes of the
/// concrete <see cref="IDataType"/> type
/// </remarks>
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;
}

/// <summary>
/// Queries a value indicating whether the specified <see cref="IProperty"/> is a reference type
/// Queries a value indicating whether the specified <see cref="IProperty"/> type is a value type or <see cref="string"/>
/// </summary>
/// <param name="property">
/// The subject <see cref="IProperty"/>
/// </param>
/// <returns>
/// A <see cref="bool"/>
/// </returns>
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;
}

/// <summary>
Expand Down
74 changes: 69 additions & 5 deletions uml4net.HandleBars/PropertyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand All @@ -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) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// <copyright file="ModelInspectorTestFixture.cs" company="Starion Group S.A.">
//
// Copyright 2019-2024 Starion Group S.A.
Expand Down
2 changes: 1 addition & 1 deletion uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
Expand Down
Loading

0 comments on commit 7d13d92

Please sign in to comment.