Skip to content

Commit

Permalink
Support for AID and AIMC Submodel Templates (#211)
Browse files Browse the repository at this point in the history
* A commit for AID and AIMC implementations

This commit combines all implementation based on AID and AIMC.
AASXPluginAID is for AID and AASXPluginAssetInterfaceDesc is majorly for AIMC.

* some newlines added for code readability
  • Loading branch information
Kaz040 authored Aug 19, 2024
1 parent daf2f4b commit 51d7192
Show file tree
Hide file tree
Showing 53 changed files with 9,958 additions and 35 deletions.
60 changes: 60 additions & 0 deletions src/AasxCsharpLibrary/AdminShellCollections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public V GetValueOrDefault(K key)
}
}

/*
Commented out to add some lines to MultivalueDictionary class
public class MultiValueDictionary<K, V>
{
private Dictionary<K, List<V>> dict = new Dictionary<K, List<V>>();
Expand All @@ -49,7 +51,65 @@ public IEnumerable<List<V>> Keys
}
}
}
*/
public class MultiValueDictionary<K, V>
{
private Dictionary<K, List<V>> dict = new Dictionary<K, List<V>>();

public void Add(K key, V value)
{
if (dict.TryGetValue(key, out var list))
list.Add(value);
else
dict.Add(key, new List<V> { value });
}

public void Remove(K key)
{
if (dict.ContainsKey(key))
dict.Remove(key);
}

public bool ContainsKey(K key) => dict.ContainsKey(key);

public List<V> this[K key] => dict[key];

public IEnumerable<List<V>> ValueLists
{
get
{
return dict.Values;
}
}

public IEnumerable<V> Values
{
get
{
foreach (var vl in dict.Values)
foreach (var v in vl)
yield return v;
}
}

public IEnumerable<K> Keys
{
get
{
return dict.Keys;
}
}

public void Clear() => dict.Clear();

public IEnumerable<V> All(K key)
{
if (!dict.ContainsKey(key))
yield break;
foreach (var x in dict[key])
yield return x;
}
}
public class DoubleSidedDict<T1, T2>
{
private Dictionary<T1, T2> _forward = new Dictionary<T1, T2>();
Expand Down
151 changes: 150 additions & 1 deletion src/AasxCsharpLibrary/AdminShellUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,17 @@ public static string EvalToNonEmptyString(string fmt, string o, string elseStrin
return string.Format(fmt, o);
}

/// <summary>
/// Some syntactic sugar to easily take the first string which has content.
/// </summary>
public static string TakeFirstContent(params string[] choices)
{
foreach (var c in choices)
if (c != null && c.Trim().Length > 0)
return c;
return "";
}

/// <summary>
/// If len of <paramref name="str"/> exceeds <paramref name="maxLen"/> then
/// string is shortened and returned with an ellipsis(…) at the end.
Expand Down Expand Up @@ -458,10 +469,14 @@ public static string ToSingleLineShortened(string str, int maxLen, string textNe
/// <code doctest="true">Assert.AreEqual("someName", AdminShellUtil.FilterFriendlyName("someName"));</code>
/// <code doctest="true">Assert.AreEqual("some__name", AdminShellUtil.FilterFriendlyName("some!;name"));</code>
/// </example>
public static string FilterFriendlyName(string src)
public static string FilterFriendlyName(string src, bool pascalCase = false)
{
if (src == null)
return null;

if (pascalCase && src.Length > 0)
src = char.ToUpper(src[0]) + src.Substring(1);

return Regex.Replace(src, @"[^a-zA-Z0-9\-_]", "_");
}

Expand Down Expand Up @@ -785,6 +800,25 @@ public static string WrapLinesAtColumn(string text, int columnLimit)
// Reflection
//

/// <summary>
/// Returns type or the underlying type, if is a Nullable or if it is a
/// generic type, e.g. a List<>
/// </summary>
public static Type GetTypeOrUnderlyingType(Type type, bool resolveGeneric = false)
{
var nut = Nullable.GetUnderlyingType(type);
if (nut != null)
{
type = nut;
}
else
if (resolveGeneric && type.IsGenericType && type.GetGenericArguments().Count() > 0)
{
type = type.GetGenericArguments()[0];
}
return type;
}

public static void SetFieldLazyValue(FieldInfo f, object obj, object value)
{
// access
Expand Down Expand Up @@ -859,6 +893,121 @@ public static void SetFieldLazyValue(FieldInfo f, object obj, object value)
}
}

/// <summary>
/// Rathhe sepcialised: adding a type-specific value to a list
/// of type-specific values.
/// Works for most scalars, dateTime, string.
/// </summary>
public static void AddToListLazyValue(object obj, object value)
{
// access
if (obj == null)
return;

switch (obj)
{
case List<string> lstr:
lstr.Add("" + value);
break;

case List<DateTime> ldt:
if (DateTime.TryParse("" + value, out var dt))
ldt.Add(dt);
break;

case List<byte> lbyte:
if (Byte.TryParse("" + value, out var ui8))
lbyte.Add(ui8);
break;

case List<sbyte> lsbyte:
if (SByte.TryParse("" + value, out var i8))
lsbyte.Add(i8);
break;

case List<Int16> li16:
if (Int16.TryParse("" + value, out var i16))
li16.Add(i16);
break;

case List<Int32> li32:
if (Int32.TryParse("" + value, out var i32))
li32.Add(i32);
break;

case List<Int64> li64:
if (Int64.TryParse("" + value, out var i64))
li64.Add(i64);
break;

case List<UInt16> lui16:
if (UInt16.TryParse("" + value, out var ui16))
lui16.Add(ui16);
break;

case List<UInt32> lui32:
if (UInt32.TryParse("" + value, out var ui32))
lui32.Add(ui32);
break;

case List<UInt64> lui64:
if (UInt64.TryParse("" + value, out var ui64))
lui64.Add(ui64);
break;

case List<float> lfloat:
if (value is double vd)
lfloat.Add((float)vd);
else
if (value is float vf)
lfloat.Add(vf);
else
if (Single.TryParse("" + value, NumberStyles.Float,
CultureInfo.InvariantCulture, out var sgl))
lfloat.Add(sgl);
break;

case List<double> ldouble:
if (value is double vd2)
ldouble.Add(vd2);
else
if (value is float vf2)
ldouble.Add(vf2);
else
if (Double.TryParse("" + value, NumberStyles.Float,
CultureInfo.InvariantCulture, out var dbl))
ldouble.Add(dbl);
break;

case List<bool> lbool:
var isFalse = value == null
|| (value is int vi && vi == 0)
|| (value is string vs && (vs == "" || vs == "false"))
|| (value is bool vb && !vb);
lbool.Add(!isFalse);
break;
}
}

public static string ToStringInvariant(object o)
{
// trivial
if (o == null)
return "";

// special cases
if (o is double od)
return od.ToString(CultureInfo.InvariantCulture);
if (o is float of)
return of.ToString(CultureInfo.InvariantCulture);
if (o is DateTime odt)
return odt.ToUniversalTime()
.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");

// use automatic conversion
return "" + o;
}

//
// temp file utilities
//
Expand Down
12 changes: 12 additions & 0 deletions src/AasxCsharpLibrary/Extensions/ExtendIReferable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ public static void BaseValidation(this IReferable referable, AasValidationRecord
}));
}

/// <summary>
/// Tells, if the IReferable can sub-structure more elements
/// </summary>
public static bool IsStructured(this IReferable rf)
{
return (rf is ISubmodel
|| rf is ISubmodelElementCollection
|| rf is ISubmodelElementList
|| rf is IOperation
|| rf is IEntity);
}

/// <summary>
/// Tells, if the IReferable is used with an index instead of <c>idShort</c>.
/// </summary>
Expand Down
35 changes: 35 additions & 0 deletions src/AasxCsharpLibrary/Extensions/ExtendReferenceList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright (c) 2018-2023 Festo SE & Co. KG <https://www.festo.com/net/de_de/Forms/web/contact_international>
Author: Michael Hoffmeister
This source code is licensed under the Apache License 2.0 (see LICENSE.txt).
This source code may use other Open Source software components (see LICENSE.txt).
*/
using AdminShellNS.Exceptions;
using System.Collections.Generic;
using System.Linq;

namespace Extensions
{
public static class ExtendReferenceList
{
/// <summary>
/// Useful, if the searched reference will have only on key (e.g. ECLASS properties)
/// </summary>
public static bool MatchesAnyWithExactlyOneKey(this List<IReference> reflist, IKey key, MatchMode matchMode = MatchMode.Strict)
{
if (key == null || reflist == null || reflist.Count < 1)
{
return false;
}

var found = false;
foreach (var r in reflist)
found = found || r.MatchesExactlyOneKey(key, matchMode);

return found;
}
}

}
19 changes: 19 additions & 0 deletions src/AasxIntegrationBase/AasForms/AasFormUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ namespace AasxIntegrationBase.AasForms
{
public static class AasFormUtils
{
public static FormMultiplicity? GetCardinality(List<Aas.IQualifier> qs)
{
if (qs == null)
return null;

var multiTrigger = new[] { "Multiplicity", "Cardinality", "SMT/Cardinality" };
foreach (var mt in multiTrigger)
{
var q = qs?.FindQualifierOfType(mt);
if (q != null)
{
foreach (var m in (FormMultiplicity[])Enum.GetValues(typeof(FormMultiplicity)))
if (("" + q.Value) == Enum.GetName(typeof(FormMultiplicity), m))
return m;
}
}

return null;
}
private static void RecurseExportAsTemplate(
List<Aas.ISubmodelElement> smwc, FormDescListOfElement tels,
Aas.Environment env = null, List<Aas.ConceptDescription> cds = null)
Expand Down
Loading

0 comments on commit 51d7192

Please sign in to comment.