Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Toxantron committed Jan 9, 2022
2 parents fb64d1b + 93dace4 commit ffab69d
Show file tree
Hide file tree
Showing 70 changed files with 2,164 additions and 288 deletions.
11 changes: 9 additions & 2 deletions AbstractionLayer.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.352
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartProject", "src\StartProject\StartProject.csproj", "{08B7686D-63C7-498C-90F0-B756E93575DD}"
EndProject
Expand Down Expand Up @@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moryx.AbstractionLayer.Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moryx.Resources.Wcf", "src\Moryx.Resources.Wcf\Moryx.Resources.Wcf.csproj", "{E1AD28CD-37A6-4AF6-80D7-756586A727B6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moryx.Products.Management.Tests", "src\Tests\Moryx.Products.Management.Tests\Moryx.Products.Management.Tests.csproj", "{0CCA2AFB-1788-44C2-8919-F5CD46BC94AD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -111,6 +113,10 @@ Global
{E1AD28CD-37A6-4AF6-80D7-756586A727B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1AD28CD-37A6-4AF6-80D7-756586A727B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1AD28CD-37A6-4AF6-80D7-756586A727B6}.Release|Any CPU.Build.0 = Release|Any CPU
{0CCA2AFB-1788-44C2-8919-F5CD46BC94AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CCA2AFB-1788-44C2-8919-F5CD46BC94AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CCA2AFB-1788-44C2-8919-F5CD46BC94AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CCA2AFB-1788-44C2-8919-F5CD46BC94AD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -130,6 +136,7 @@ Global
{93650069-26E9-4E0D-A336-9D02F1039346} = {D6D69517-7889-4E08-ABEA-D3E069D08A6B}
{583CBD84-DD9F-4834-A89C-1625A05EE15D} = {BA183EBF-FAC1-45AE-9559-09879DB103AC}
{E1AD28CD-37A6-4AF6-80D7-756586A727B6} = {BA183EBF-FAC1-45AE-9559-09879DB103AC}
{0CCA2AFB-1788-44C2-8919-F5CD46BC94AD} = {D6D69517-7889-4E08-ABEA-D3E069D08A6B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {23463631-1BA0-41B8-ABA3-1E9741037513}
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<PropertyGroup>
<MoryxCoreVersion>3.2.0</MoryxCoreVersion>
<MoryxClientFrameworkVersion>3.1.0</MoryxClientFrameworkVersion>
<MoryxClientFrameworkVersion>3.2.0</MoryxClientFrameworkVersion>
<MoryxMaintenanceWebVersion>3.1.1</MoryxMaintenanceWebVersion>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.10.1
5.11.0
25 changes: 25 additions & 0 deletions src/Moryx.AbstractionLayer.TestTools/DummyProductPartLink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2020, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using Moryx.AbstractionLayer.Products;
using System.Linq;

namespace Moryx.AbstractionLayer.TestTools
{
/// <summary>
/// Dummy implementation of a ProductPartLink.
/// </summary>
public class DummyProductPartLink : ProductPartLink<DummyProductType>
{
public override bool Equals(object obj)
{
var toCompareWith = obj as DummyProductPartLink;
if (toCompareWith == null)
return false;

return GetType().GetProperties()
.All(prop => (prop.GetValue(toCompareWith) is null && prop.GetValue(this) is null)
|| prop.GetValue(toCompareWith).Equals(prop.GetValue(this)));
}
}
}
47 changes: 47 additions & 0 deletions src/Moryx.AbstractionLayer.TestTools/DummyProductRecipe.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2020, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using Moryx.AbstractionLayer.Recipes;
using Moryx.Workflows;
using System.Collections.Generic;
using System.Linq;

namespace Moryx.AbstractionLayer.TestTools
{
/// <summary>
/// Dummy implementation of an product instance. Created by the <see cref="DummyProductType"/>
/// </summary>
public class DummyProductRecipe : ProductRecipe
{
public override bool Equals(object obj)
{
var toCompareWith = obj as DummyProductRecipe;
if (toCompareWith == null)
return false;

return toCompareWith.Name == Name && toCompareWith.Revision == Revision
&& toCompareWith.State == State && toCompareWith.Classification == Classification
&& ((toCompareWith.Origin is null && Origin is null) || Origin.Equals(toCompareWith.Origin))
&& ((toCompareWith.Product is null && Product is null) || Product.Equals(toCompareWith.Product))
&& ((toCompareWith.Target is null && Target is null) || Target.Equals(toCompareWith.Target));
}
}

public class DummyProductWorkplanRecipe : DummyProductRecipe, IWorkplanRecipe
{
public IWorkplan Workplan { get; set; }

public ICollection<long> DisabledSteps { get; set; }

public override bool Equals(object obj)
{
var toCompareWith = obj as DummyProductWorkplanRecipe;
if (toCompareWith == null)
return false;

return base.Equals(toCompareWith)
&& ((toCompareWith.Workplan is null && Workplan is null) || Workplan.Equals(toCompareWith.Workplan))
&& ((toCompareWith.DisabledSteps is null && DisabledSteps is null) || Enumerable.SequenceEqual<long>(DisabledSteps, toCompareWith.DisabledSteps));
}
}
}
84 changes: 84 additions & 0 deletions src/Moryx.AbstractionLayer.TestTools/DummyProductType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the Apache License, Version 2.0

using Moryx.AbstractionLayer.Products;
using System.Collections.Generic;
using System.Linq;

namespace Moryx.AbstractionLayer.TestTools
{
Expand All @@ -15,5 +17,87 @@ protected override ProductInstance Instantiate()
{
return new DummyProductInstance();
}

public override bool Equals(object obj)
{
var toCompareWith = obj as DummyProductType;
if (toCompareWith == null)
return false;

return toCompareWith.Id == Id && toCompareWith.Name == Name && toCompareWith.State == State
&& ((toCompareWith.Identity is null && Identity is null) || toCompareWith.Identity.Equals(Identity));
}
}


/// <summary>
/// Dummy implementation of a <see cref="ProductType"/> with Product Parts
/// </summary>
public class DummyProductTypeWithParts : DummyProductType
{
/// <inheritdoc />
protected override ProductInstance Instantiate()
{
return new DummyProductInstance();
}

/// <summary>
/// Dummy ProductPartLink
/// </summary>
public DummyProductPartLink ProductPartLink { get; set; }

/// <summary>
/// Dummy ProductPartLink enumerable
/// </summary>
public IEnumerable<DummyProductPartLink> ProductPartLinkEnumerable { get; set; }

public override bool Equals(object obj)
{
var toCompareWith = obj as DummyProductTypeWithParts;
if (toCompareWith == null)
return false;

return base.Equals(toCompareWith) &&
((toCompareWith.ProductPartLink is null && ProductPartLink is null) ||
toCompareWith.ProductPartLink.Equals(ProductPartLink))
&& ((toCompareWith.ProductPartLinkEnumerable is null && ProductPartLinkEnumerable is null) ||
Enumerable.SequenceEqual<DummyProductPartLink>(toCompareWith.ProductPartLinkEnumerable, ProductPartLinkEnumerable));
}
}


/// <summary>
/// Dummy implementation of a <see cref="ProductType"/> with Files
/// </summary>
public class DummyProductTypeWithFiles : DummyProductType
{
/// <inheritdoc />
protected override ProductInstance Instantiate()
{
return new DummyProductInstance();
}

/// <summary>
/// First dummy ProductFile
/// </summary>
public ProductFile FirstProductFile { get; set; }

/// <summary>
/// Second dummy ProductFile
/// </summary>
public ProductFile SecondProductFile { get; set; }

public override bool Equals(object obj)
{
var toCompareWith = obj as DummyProductTypeWithFiles;
if (toCompareWith == null)
return false;

return base.Equals(toCompareWith) &&
(toCompareWith.FirstProductFile is null && FirstProductFile is null ||
FirstProductFile.GetType().GetProperties().All(prop => prop.GetValue(toCompareWith.FirstProductFile) == prop.GetValue(FirstProductFile)))
&& (toCompareWith.SecondProductFile is null && SecondProductFile is null ||
SecondProductFile.GetType().GetProperties().All(prop => prop.GetValue(toCompareWith.SecondProductFile) == prop.GetValue(SecondProductFile)));
}
}
}
23 changes: 23 additions & 0 deletions src/Moryx.AbstractionLayer.TestTools/DummyWorkplan.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2020, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using Moryx.Workflows;
using System.Linq;

namespace Moryx.AbstractionLayer.TestTools
{
public class DummyWorkplan : Workplan
{
public override bool Equals(object obj)
{
var toCompareWith = obj as DummyWorkplan;
if (toCompareWith == null)
return false;

return toCompareWith.Id == Id && toCompareWith.Name == Name
&& toCompareWith.Version == toCompareWith.Version && toCompareWith.State == State
&& ((toCompareWith.Connectors is null && Connectors is null) || Enumerable.SequenceEqual(toCompareWith.Connectors, Connectors))
&& ((toCompareWith.Steps is null && Steps is null) || Enumerable.SequenceEqual(toCompareWith.Steps, Steps));
}
}
}
12 changes: 12 additions & 0 deletions src/Moryx.AbstractionLayer/Products/IProductManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,16 @@ TInstance GetInstance<TInstance>(Expression<Func<TInstance, bool>> selector)
IReadOnlyList<TInstance> GetInstances<TInstance>(Expression<Func<TInstance, bool>> selector)
where TInstance : IProductInstance;
}

/// <summary>
/// Additional interface for type storage to search for product types by expression
/// TODO: Remove in AL 6
/// </summary>
public interface IProductManagementTypeSearch : IProductManagement
{
/// <summary>
/// Load types using filter expression
/// </summary>
IReadOnlyList<TType> LoadTypes<TType>(Expression<Func<TType, bool>> selector);
}
}
26 changes: 26 additions & 0 deletions src/Moryx.AbstractionLayer/Products/ProductFacadeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2021, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace Moryx.AbstractionLayer.Products
{
/// <summary>
/// Extensions for the <see cref="IProductManagement"/> facade
/// </summary>
public static class ProductFacadeExtensions
{
/// <summary>
/// Bridge extension for LoadTypes using filter expression
/// </summary>
public static IReadOnlyList<TType> LoadTypes<TType>(this IProductManagement facade, Expression<Func<TType, bool>> selector)
{
if (facade is IProductManagementTypeSearch typeSearch)
return typeSearch.LoadTypes(selector);

throw new NotSupportedException("Instance of product management does not support expression type search");
}
}
}
50 changes: 50 additions & 0 deletions src/Moryx.AbstractionLayer/Products/ProductQuery.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) 2020, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System.Collections.Generic;
using System.Runtime.Serialization;
using Moryx.Serialization;

namespace Moryx.AbstractionLayer.Products
{
Expand Down Expand Up @@ -65,6 +67,52 @@ public class ProductQuery
/// </summary>
[DataMember]
public Selector Selector { get; set; }

/// <summary>
/// List of property filters
/// </summary>
[DataMember]
public List<PropertyFilter> PropertyFilters { get; set; }
}

/// <summary>
/// Property filter wrapper for the filtered entry
/// </summary>
[DataContract]
public class PropertyFilter
{
/// <summary>
/// Entry to filter
/// </summary>
[DataMember]
public Entry Entry { get; set; }

/// <summary>
/// Operator for the filter expression
/// </summary>
[DataMember]
public PropertyFilterOperator Operator { get; set; }
}

/// <summary>
/// Property filter operator expression
/// </summary>
public enum PropertyFilterOperator
{
/// <summary>
/// Value equals
/// </summary>
Equals,

/// <summary>
/// Value is greater then
/// </summary>
GreaterThen,

/// <summary>
/// Value is less then
/// </summary>
LessThen
}

/// <summary>
Expand All @@ -76,10 +124,12 @@ public enum RevisionFilter
/// Fetch all revisions, this is the default
/// </summary>
All = 0,

/// <summary>
/// Fetch only the latest revision
/// </summary>
Latest = 1,

/// <summary>
/// Fetch only specific revisions
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Moryx.AbstractionLayer/Products/ProductType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public abstract class ProductType : IProductType
/// </returns>
public override string ToString()
{
return Identity.ToString();
return Identity?.ToString();
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/Moryx.AbstractionLayer/Resources/IResourceGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ TResource Instantiate<TResource>(string type)
/// <summary>
/// Remove a resource permanently and irreversible
/// </summary>
[Obsolete("Permanent removal of resources will be removed in the next major")]
bool Destroy(IResource resource, bool permanent);
}
}
Loading

0 comments on commit ffab69d

Please sign in to comment.