| | | 1 | | using Elsa.Extensions; |
| | | 2 | | using Elsa.Workflows.Management.Entities; |
| | | 3 | | using Elsa.Workflows.Models; |
| | | 4 | | using Humanizer; |
| | | 5 | | |
| | | 6 | | namespace Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity; |
| | | 7 | | |
| | | 8 | | public class WorkflowDefinitionActivityDescriptorFactory |
| | | 9 | | { |
| | | 10 | | public ActivityDescriptor CreateDescriptor(WorkflowDefinition definition, WorkflowDefinition? latestPublishedDefinit |
| | | 11 | | { |
| | 765 | 12 | | var typeName = definition.Name!.Pascalize(); |
| | | 13 | | |
| | 765 | 14 | | var ports = definition.Outcomes.Select(outcome => new Port |
| | 765 | 15 | | { |
| | 765 | 16 | | Name = outcome, |
| | 765 | 17 | | DisplayName = outcome, |
| | 765 | 18 | | IsBrowsable = true, |
| | 765 | 19 | | Type = PortType.Flow |
| | 765 | 20 | | }).ToList(); |
| | | 21 | | |
| | 765 | 22 | | var rootPort = new Port |
| | 765 | 23 | | { |
| | 765 | 24 | | Name = nameof(WorkflowDefinitionActivity.Root), |
| | 765 | 25 | | DisplayName = "Root", |
| | 765 | 26 | | IsBrowsable = false, |
| | 765 | 27 | | Type = PortType.Embedded |
| | 765 | 28 | | }; |
| | | 29 | | |
| | 765 | 30 | | ports.Insert(0, rootPort); |
| | | 31 | | |
| | 765 | 32 | | return new() |
| | 765 | 33 | | { |
| | 765 | 34 | | TypeName = typeName, |
| | 765 | 35 | | ClrType = typeof(WorkflowDefinitionActivity), |
| | 765 | 36 | | Name = typeName, |
| | 765 | 37 | | Version = definition.Version, |
| | 765 | 38 | | DisplayName = definition.Name, |
| | 765 | 39 | | Description = definition.Description, |
| | 765 | 40 | | Category = definition.Options.ActivityCategory ?? "Workflows", |
| | 765 | 41 | | Kind = ActivityKind.Action, |
| | 765 | 42 | | IsBrowsable = definition.IsPublished, |
| | 765 | 43 | | Inputs = DescribeInputs(definition).ToList(), |
| | 765 | 44 | | Outputs = DescribeOutputs(definition).ToList(), |
| | 765 | 45 | | Ports = ports, |
| | 765 | 46 | | CustomProperties = |
| | 765 | 47 | | { |
| | 765 | 48 | | ["RootType"] = nameof(WorkflowDefinitionActivity), |
| | 765 | 49 | | ["WorkflowDefinitionId"] = definition.DefinitionId, |
| | 765 | 50 | | ["WorkflowDefinitionVersionId"] = definition.Id |
| | 765 | 51 | | }, |
| | 765 | 52 | | ConstructionProperties = new Dictionary<string, object> |
| | 765 | 53 | | { |
| | 765 | 54 | | [nameof(WorkflowDefinitionActivity.WorkflowDefinitionId)] = definition.DefinitionId, |
| | 765 | 55 | | [nameof(WorkflowDefinitionActivity.WorkflowDefinitionVersionId)] = definition.Id, |
| | 765 | 56 | | [nameof(WorkflowDefinitionActivity.Version)] = definition.Version, |
| | 765 | 57 | | }, |
| | 765 | 58 | | Constructor = context => |
| | 765 | 59 | | { |
| | 520 | 60 | | var activity = context.CreateActivity<WorkflowDefinitionActivity>(); |
| | 520 | 61 | | activity.Type = typeName; |
| | 520 | 62 | | activity.WorkflowDefinitionId = definition.DefinitionId; |
| | 520 | 63 | | activity.WorkflowDefinitionVersionId = definition.Id; |
| | 520 | 64 | | activity.Version = definition.Version; |
| | 520 | 65 | | activity.LatestAvailablePublishedVersion = latestPublishedDefinition?.Version ?? definition.Version; |
| | 520 | 66 | | activity.LatestAvailablePublishedVersionId = latestPublishedDefinition?.Id ?? definition.Id; |
| | 765 | 67 | | |
| | 520 | 68 | | return activity; |
| | 765 | 69 | | } |
| | 765 | 70 | | }; |
| | | 71 | | } |
| | | 72 | | |
| | | 73 | | private static IEnumerable<InputDescriptor> DescribeInputs(WorkflowDefinition definition) |
| | | 74 | | { |
| | 765 | 75 | | var inputs = definition.Inputs.Select(inputDefinition => |
| | 765 | 76 | | { |
| | 64 | 77 | | var nakedType = inputDefinition.Type; |
| | 64 | 78 | | var inputName = inputDefinition.Name; |
| | 64 | 79 | | var safeInputName = PropertyNameHelper.GetSafePropertyName(typeof(WorkflowDefinitionActivity), inputName); |
| | 765 | 80 | | |
| | 64 | 81 | | return new InputDescriptor |
| | 64 | 82 | | { |
| | 64 | 83 | | Type = nakedType, |
| | 64 | 84 | | IsWrapped = true, |
| | 16 | 85 | | ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(safeInputName), |
| | 0 | 86 | | ValueSetter = (activity, value) => activity.SyntheticProperties[safeInputName] = value!, |
| | 64 | 87 | | Name = safeInputName, |
| | 64 | 88 | | DisplayName = inputDefinition.DisplayName, |
| | 64 | 89 | | Description = inputDefinition.Description, |
| | 64 | 90 | | Category = inputDefinition.Category, |
| | 64 | 91 | | UIHint = inputDefinition.UIHint, |
| | 64 | 92 | | StorageDriverType = inputDefinition.StorageDriverType, |
| | 64 | 93 | | IsSynthetic = true |
| | 64 | 94 | | }; |
| | 765 | 95 | | }); |
| | | 96 | | |
| | 1658 | 97 | | foreach (var input in inputs) |
| | 64 | 98 | | yield return input; |
| | 765 | 99 | | } |
| | | 100 | | |
| | | 101 | | private static IEnumerable<OutputDescriptor> DescribeOutputs(WorkflowDefinition definition) |
| | | 102 | | { |
| | 765 | 103 | | return definition.Outputs.Select(outputDefinition => |
| | 765 | 104 | | { |
| | 192 | 105 | | var nakedType = outputDefinition.Type; |
| | 192 | 106 | | var outputName = outputDefinition.Name; |
| | 192 | 107 | | var safeOutputName = PropertyNameHelper.GetSafePropertyName(typeof(WorkflowDefinitionActivity), outputName); |
| | 765 | 108 | | |
| | 192 | 109 | | return new OutputDescriptor |
| | 192 | 110 | | { |
| | 192 | 111 | | Type = nakedType, |
| | 9 | 112 | | ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(safeOutputName), |
| | 0 | 113 | | ValueSetter = (activity, value) => activity.SyntheticProperties[safeOutputName] = value!, |
| | 192 | 114 | | Name = safeOutputName, |
| | 192 | 115 | | DisplayName = outputDefinition.DisplayName, |
| | 192 | 116 | | Description = outputDefinition.Description, |
| | 192 | 117 | | IsSynthetic = true |
| | 192 | 118 | | }; |
| | 765 | 119 | | }); |
| | | 120 | | } |
| | | 121 | | } |