Remove obsolete transformer code

This commit is contained in:
Sipke Schoorstra 2022-06-27 12:37:52 +02:00
parent 47c4e5900f
commit 091430f9ff
5 changed files with 0 additions and 191 deletions

View file

@ -1,95 +0,0 @@
using Elsa.Workflows.Core.Activities.Flowchart.Extensions;
using Elsa.Workflows.Core.Activities.Flowchart.Models;
using Elsa.Workflows.Core.Activities.Flowchart.Services;
using Elsa.Workflows.Core.Services;
namespace Elsa.Workflows.Core.Activities.Flowchart.Implementations;
using Flowchart = Activities.Flowchart;
public class Transformer : ITransformer
{
private readonly IActivityNodeDescriber _activityNodeDescriber;
private readonly IIdentityGenerator _identityGenerator;
public Transformer(IActivityNodeDescriber activityNodeDescriber, IIdentityGenerator identityGenerator)
{
_activityNodeDescriber = activityNodeDescriber;
_identityGenerator = identityGenerator;
}
public void Transpose(Flowchart flowchart)
{
var start = flowchart.Start;
if (start == null)
return;
var activities = flowchart.Activities;
var activityTypes = activities.Select(x => x.GetType()).Distinct().ToList();
var activityDescriptors = activityTypes.Select(_activityNodeDescriber.DescribeActivity).ToDictionary(x => x.ActivityRuntimeType);
TransposeInternal(flowchart, activityDescriptors);
}
private void TransposeInternal(Flowchart flowchart, IDictionary<Type, ActivityNodeDescriptor> descriptors)
{
var connections = flowchart.Connections.ToList();
foreach (var connection in connections)
{
var portName = connection.SourcePort;
// If the connection has no source port name, it cannot be mapped to an outbound port property on an activity.
if (portName == null)
continue;
var source = connection.Source;
var sourceType = source.GetType();
var sourceDescriptor = descriptors[sourceType];
var sourcePort = sourceDescriptor.OutPorts.FirstOrDefault(x => x.Name == portName);
// If the connection source port does not match any outbound port properties on the source activity, the target cannot be transposed onto it.
if (sourcePort == null)
continue;
var target = connection.Target;
var descendantConnections = connections.Descendants(target).ToList();
// Remove all descendant connections and activities from the current flowchart level.
// They are either no longer necessary because they are transposed, or they will be added to a child flowchart.
flowchart.Connections.Remove(connection);
flowchart.Activities.Remove(target);
if (!descendantConnections.Any())
{
// There were no descendant connections, which means we can transpose the current target as-is.
source.SetPropertyValue(portName, target);
}
else
{
// There was at least one descendant, which means we need to capture them into a child flow.
// TODO: Add logic to try and determine if we can add a sequence instead.
var activities = descendantConnections.Select(x => x.Source).Concat(descendantConnections.Select(x => x.Target)).ToHashSet();
var subFlow = new Flowchart
{
Id = _identityGenerator.GenerateId(),
Activities = activities,
Connections = descendantConnections,
Start = target
};
// Remove transported connections and activities from the current flowchart.
flowchart.Connections = flowchart.Connections.Except(descendantConnections).ToList();
flowchart.Activities = flowchart.Activities.Except(activities).ToHashSet();
// Transpose the child flow into the current source.
source.SetPropertyValue(portName, subFlow);
// Recurse into the subflow.
TransposeInternal(subFlow, descriptors);
}
}
}
}

View file

@ -11,13 +11,6 @@ public class FlowchartJsonConverter : JsonConverter<Activities.Flowchart>
private const string AllActivitiesKey = "AllActivities";
private const string AllConnectionsKey = "AllConnections";
private readonly ITransformer _transformer;
public FlowchartJsonConverter(ITransformer transformer)
{
_transformer = transformer;
}
public override Activities.Flowchart Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (!JsonDocument.TryParseValue(ref reader, out var doc))
@ -50,8 +43,6 @@ public class FlowchartJsonConverter : JsonConverter<Activities.Flowchart>
[AllConnectionsKey] = connections.ToList()
}
};
_transformer.Transpose(flowChart);
return flowChart;
}

View file

@ -1,10 +0,0 @@
namespace Elsa.Workflows.Core.Activities.Flowchart.Services;
using Flowchart = Activities.Flowchart;
/// <summary>
/// Transforms the specified <see cref="Flowchart"/> into a sequential structure by transposing connected activities into outbound activity properties of the source activity.
/// </summary>
public interface ITransformer
{
void Transpose(Flowchart flowchart);
}

View file

@ -17,10 +17,6 @@ public class FlowchartFeature : FeatureBase
public override void Apply()
{
Services
//.AddSingleton<DefaultTransformation>()
//.AddSingleton<ITransformationRegistry, TransformationRegistry>()
//.AddSingleton<ITransformation, DefaultTransformation>()
.AddSingleton<ITransformer, Transformer>()
.AddSingleton<IActivityNodeDescriber, ActivityNodeDescriber>()
.AddSingleton<ISerializationOptionsConfigurator, FlowchartSerializationOptionConfigurator>()
;

View file

@ -1,73 +0,0 @@
using System.Linq;
using System.Threading.Tasks;
using Elsa.Testing.Shared;
using Elsa.Workflows.Core.Activities.Flowchart.Services;
using Elsa.Workflows.Core.Services;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
using Xunit.Abstractions;
namespace Elsa.IntegrationTests.Activities.Flowchart.Services;
using Flowchart = Workflows.Core.Activities.Flowchart.Activities.Flowchart;
public class TransformerTests
{
private readonly ITransformer _transformer;
private readonly CapturingTextWriter _capturingTextWriter = new();
private readonly IWorkflowRunner _workflowRunner;
private readonly IWorkflowDefinitionBuilderFactory _workflowBuilderFactory;
public TransformerTests(ITestOutputHelper testOutputHelper)
{
var services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
_transformer = services.GetRequiredService<ITransformer>();
_workflowBuilderFactory = services.GetRequiredService<IWorkflowDefinitionBuilderFactory>();
_workflowRunner = services.GetRequiredService<IWorkflowRunner>();
}
[Fact(DisplayName = "Transforming a flowchart correctly transposes connected nodes")]
public async Task Test1()
{
var languages = new[] { "C#", "Rust", "Go" };
var builder = _workflowBuilderFactory.CreateBuilder();
var workflow = await builder.BuildWorkflowAsync(new Workflow1(languages));
var flowchart = (Flowchart)workflow.Root;
_transformer.Transpose(flowchart);
await _workflowRunner.RunAsync(workflow);
var lines = _capturingTextWriter.Lines.ToList();
var expectedLines = new[] { "Start!", "Current Item", "C#", "Current Item", "Rust", "Current Item", "Go", "Done!" };
Assert.Equal(expectedLines, lines);
}
[Fact(DisplayName = "Transforming a flowchart correctly transposes connected nodes")]
public async Task Test2()
{
var languages = new[] { "C#", "Rust", "Go" };
var builder = _workflowBuilderFactory.CreateBuilder();
var workflow = await builder.BuildWorkflowAsync(new Workflow2(languages));
var flowchart = (Flowchart)workflow.Root;
_transformer.Transpose(flowchart);
await _workflowRunner.RunAsync(workflow);
var lines = _capturingTextWriter.Lines.ToList();
var expectedLines = new[] { "Start!", "C#", "Rust", "Go", "Done!" };
Assert.Equal(expectedLines, lines);
}
[Fact(DisplayName = "Transforming a flowchart correctly transposes connected nodes")]
public async Task Test3()
{
var languages = new[] { "C#", "Rust", "Go" };
var builder = _workflowBuilderFactory.CreateBuilder();
var workflow = await builder.BuildWorkflowAsync(new Workflow3(languages));
var flowchart = (Flowchart)workflow.Root;
_transformer.Transpose(flowchart);
await _workflowRunner.RunAsync(workflow);
var lines = _capturingTextWriter.Lines.ToList();
var expectedLines = new[] { "Start!", "C#", "Rust", "Go", "Done!" };
Assert.Equal(expectedLines, lines);
}
}