Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jtikekar/master v3 rc2 #166

Open
wants to merge 4 commits into
base: masterV3
Choose a base branch
from
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

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
using System;
/*
Copyright (c) 2018-2021 Festo AG & 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using AasCore.Aas3_0_RC02;
using AasxCompatibilityModels;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace AdminShellNS
//namespace AdminShellNS
namespace AdminShell_V20
{
public class AdminShellConverters
public static class AdminShellConverters
{
/// <summary>
/// This converter is used for reading JSON files; it claims to be responsible for "SubmodelElements" (the base class)
/// and decides, which sub-class of the base class shall be populated.
/// The decision, shich special sub-class to create is done in a factory SubmodelElementWrapper.CreateAdequateType(),
/// This converter is used for reading JSON files; it claims to be responsible for
/// "Referable" (the base class)
/// and decides, which sub-class of the base class shall be populated.
/// If the object is SubmodelElement, the decision, shich special sub-class to create is done in a factory
/// AdminShell.SubmodelElementWrapper.CreateAdequateType(),
/// in order to have all sub-class specific decisions in one place (SubmodelElementWrapper)
/// Remark: There is a NuGet package JsonSubTypes, which could have done the job, except the fact of having
/// "modelType" being a class property with a contained property "name".
Expand All @@ -38,7 +50,8 @@ public JsonAasxConverter(string UpperClassProperty, string LowerClassProperty) :

public override bool CanConvert(Type objectType)
{
if (typeof(ISubmodelElement).IsAssignableFrom(objectType))
// Info MIHO 21 APR 2020: changed this from SubmodelElement to Referable
if (typeof(AdminShell.Referable).IsAssignableFrom(objectType))
return true;
return false;
}
Expand All @@ -57,27 +70,28 @@ public override object ReadJson(JsonReader reader,
JObject jObject = JObject.Load(reader);

// Create target object based on JObject
//object target = new SubmodelElement();
ISubmodelElement target = null;
object target = new AdminShell.Referable();

if (jObject.ContainsKey(UpperClassProperty))
{
var j2 = jObject[UpperClassProperty];
foreach (var c in j2.Children())
{
var cprop = c as Newtonsoft.Json.Linq.JProperty;
if (cprop == null)
continue;
if (cprop.Name == LowerClassProperty && cprop.Value != null && cprop.Value.Type.ToString() == "String")
if (j2 != null)
foreach (var c in j2.Children())
{
var cpval = cprop.Value.ToObject<string>();
if (cpval == null)
var cprop = c as Newtonsoft.Json.Linq.JProperty;
if (cprop == null)
continue;
var o = CreateSubmodelElementIstance(cpval);
if (o != null)
target = o;
if (cprop.Name == LowerClassProperty && cprop.Value.Type.ToString() == "String")
{
var cpval = cprop.Value.ToObject<string>();
if (cpval == null)
continue;
// Info MIHO 21 APR 2020: use Referable.CreateAdequateType instead of SMW...
var o = AdminShell.Referable.CreateAdequateType(cpval);
if (o != null)
target = o;
}
}
}
}

// Populate the object properties
Expand All @@ -86,22 +100,16 @@ public override object ReadJson(JsonReader reader,
return target;
}


private static ISubmodelElement CreateSubmodelElementIstance(string typeName)
{
//TODO: jtikekar Need to test
Type type = Type.GetType(typeName);
if (type == null || !type.IsSubclassOf(typeof(ISubmodelElement)))
return null;
var sme = Activator.CreateInstance(type) as ISubmodelElement;
return sme;
}
/// <summary>
/// Introduced for JSON serialization, can create Referables based on a string name
/// </summary>
/// <param name="elementName">string name (standard PascalCased)</param>


public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}

}

/// <summary>
Expand Down Expand Up @@ -138,21 +146,24 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
{
JsonProperty property = base.CreateProperty(member, memberSerialization);

if (!BlobHasValue && property.DeclaringType == typeof(Blob) && property.PropertyName == "value")
if (!BlobHasValue && property.DeclaringType == typeof(AdminShell.Blob) &&
property.PropertyName == "value")
property.ShouldSerialize = instance => { return false; };

if (!SubmodelHasElements && property.DeclaringType == typeof(Submodel) && property.PropertyName == "submodelElements")
if (!SubmodelHasElements && property.DeclaringType == typeof(AdminShell.Submodel) &&
property.PropertyName == "submodelElements")
property.ShouldSerialize = instance => { return false; };

if (!SmcHasValue && property.DeclaringType == typeof(SubmodelElementCollection) && property.PropertyName == "value")
if (!SmcHasValue && property.DeclaringType == typeof(AdminShell.SubmodelElementCollection) &&
property.PropertyName == "value")
property.ShouldSerialize = instance => { return false; };

if (!OpHasVariables && property.DeclaringType == typeof(Operation) && (property.PropertyName == "in" || property.PropertyName == "out"))
if (!OpHasVariables && property.DeclaringType == typeof(AdminShell.Operation) &&
(property.PropertyName == "in" || property.PropertyName == "out"))
property.ShouldSerialize = instance => { return false; };


//TODO (jtikekar, 2022-07-08): AssetAdministrationShell.View not supported anymore
if (!AasHasViews && property.DeclaringType == typeof(AssetAdministrationShell) && property.PropertyName == "views")
if (!AasHasViews && property.DeclaringType == typeof(AdminShell.AdministrationShell) &&
property.PropertyName == "views")
property.ShouldSerialize = instance => { return false; };

return property;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/*
Copyright (c) 2018-2019 Festo AG & Co. KG <https://www.festo.com/net/de_de/Forms/web/contact_international>
Copyright (c) 2018-2021 Festo AG & 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 AasCore.Aas3_0_RC02;
using AasxServerStandardBib;
using AasxCompatibilityModels;
using System;
using System.Collections;
using System.Collections.Generic;
Expand All @@ -19,9 +18,10 @@ This source code may use other Open Source software components (see LICENSE.txt)
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace AdminShellNS
//namespace AdminShellNS
namespace AdminShell_V20
{
public static class AdminShellUtil
public static class AdminShellUtilV20
{
public static string EvalToNonNullString(string fmt, object o, string elseString = "")
{
Expand Down Expand Up @@ -187,7 +187,7 @@ public static string[] CleanHereStringToArray(string here)
public static string CleanHereStringWithNewlines(string here, string nl = null)
{
if (nl == null)
nl = System.Environment.NewLine;
nl = Environment.NewLine;
var lines = CleanHereStringToArray(here);
if (lines == null)
return null;
Expand Down Expand Up @@ -362,12 +362,12 @@ public static void CheckSearchable(
{
// try get a speaking name
var metaModelName = "<unknown>";
var x1 = mi.GetCustomAttribute<MetaModelName>();
var x1 = mi.GetCustomAttribute<AdminShell.MetaModelName>();
if (x1 != null && x1.name != null)
metaModelName = x1.name;

// check if this object is searchable
var x2 = mi.GetCustomAttribute<TextSearchable>();
var x2 = mi.GetCustomAttribute<AdminShell.TextSearchable>();
if (x2 != null)
{
// what to check?
Expand Down Expand Up @@ -415,10 +415,9 @@ public static void EnumerateSearchable(

// try to get element name of an AAS entity
string elName = null;
if (obj is IReferable)
if (obj is AdminShell.Referable)
{
//elName = (obj as IReferable).GetElementName();
elName = obj.GetType().Name;
elName = (obj as AdminShell.Referable).GetElementName();
businessObject = obj;
}

Expand All @@ -431,16 +430,20 @@ public static void EnumerateSearchable(
if (options.allowedAssemblies == null || !options.allowedAssemblies.Contains(objType.Assembly))
return;

// do not dive into enums
if (objType.IsEnum)
return;

// look at fields, first
var fields = objType.GetFields();
foreach (var fi in fields)
{
// is the object marked to be skipped?
var x3 = fi.GetCustomAttribute<SkipForReflection>();
var x3 = fi.GetCustomAttribute<AdminShell.SkipForReflection>();
if (x3 != null)
continue;

var x4 = fi.GetCustomAttribute<SkipForSearch>();
var x4 = fi.GetCustomAttribute<AdminShell.SkipForSearch>();
if (x4 != null)
continue;

Expand Down Expand Up @@ -477,11 +480,11 @@ public static void EnumerateSearchable(
continue;

// is the object marked to be skipped?
var x3 = pi.GetCustomAttribute<SkipForReflection>();
var x3 = pi.GetCustomAttribute<AdminShell.SkipForReflection>();
if (x3 != null)
continue;

var x4 = pi.GetCustomAttribute<SkipForSearch>();
var x4 = pi.GetCustomAttribute<AdminShell.SkipForSearch>();
if (x4 != null)
continue;

Expand All @@ -508,5 +511,126 @@ public static void EnumerateSearchable(
}
}
}

//
// String manipulations
//

public static string ReplacePercentPlaceholder(
string input,
string searchFor,
Func<string> substLamda,
StringComparison comparisonType = StringComparison.InvariantCulture)
{
// access
if (input == null || searchFor == null || searchFor == "")
return input;

// find
while (true)
{
// any occurence
var p = input.IndexOf(searchFor, comparisonType);
if (p < 0)
break;

// split
var left = input.Substring(0, p);
var right = "";
var rp = p + searchFor.Length;
if (rp < input.Length)
right = input.Substring(rp);

// lambda
var repl = "" + substLamda?.Invoke();

// build new
input = left + repl + right;
}

// ok
return input;
}

//
// Base 64
//

public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}

public static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

//
// Generation of Ids
//

private static Random MyRnd = new Random();

public static string GenerateIdAccordingTemplate(string tpl)
{
// generate a deterministic decimal digit string
var decimals = String.Format("{0:ffffyyMMddHHmmss}", DateTime.UtcNow);
decimals = new string(decimals.Reverse().ToArray());
// convert this to an int
if (!Int64.TryParse(decimals, out Int64 decii))
decii = MyRnd.Next(Int32.MaxValue);
// make an hex out of this
string hexamals = decii.ToString("X");
// make an alphanumeric string out of this
string alphamals = "";
var dii = decii;
while (dii >= 1)
{
var m = dii % 26;
alphamals += Convert.ToChar(65 + m);
dii = dii / 26;
}

// now, "salt" the strings
for (int i = 0; i < 32; i++)
{
var c = Convert.ToChar(48 + MyRnd.Next(10));
decimals += c;
hexamals += c;
alphamals += c;
}

// now, can just use the template
var id = "";
foreach (var tpli in tpl)
{
if (tpli == 'D' && decimals.Length > 0)
{
id += decimals[0];
decimals = decimals.Remove(0, 1);
}
else
if (tpli == 'X' && hexamals.Length > 0)
{
id += hexamals[0];
hexamals = hexamals.Remove(0, 1);
}
else
if (tpli == 'A' && alphamals.Length > 0)
{
id += alphamals[0];
alphamals = alphamals.Remove(0, 1);
}
else
id += tpli;
}

// ok
return id;
}

}
}
Loading