| | | 1 | | using ActivityNode = Elsa.Workflows.Models.ActivityNode; |
| | | 2 | | |
| | | 3 | | namespace Elsa.Workflows; |
| | | 4 | | |
| | | 5 | | /// <inheritdoc /> |
| | | 6 | | public class ActivityVisitor : IActivityVisitor |
| | | 7 | | { |
| | | 8 | | private readonly IServiceProvider _serviceProvider; |
| | | 9 | | private readonly IEnumerable<IActivityResolver> _portResolvers; |
| | | 10 | | |
| | | 11 | | /// <summary> |
| | | 12 | | /// Initializes a new instance of the <see cref="ActivityVisitor"/> class. |
| | | 13 | | /// </summary> |
| | 851 | 14 | | public ActivityVisitor(IEnumerable<IActivityResolver> portResolvers, IServiceProvider serviceProvider) |
| | | 15 | | { |
| | 851 | 16 | | _serviceProvider = serviceProvider; |
| | 3324 | 17 | | _portResolvers = portResolvers.OrderByDescending(x => x.Priority).ToList(); |
| | 851 | 18 | | } |
| | | 19 | | |
| | | 20 | | /// <inheritdoc /> |
| | | 21 | | public async Task<ActivityNode> VisitAsync(IActivity activity, CancellationToken cancellationToken = default) |
| | | 22 | | { |
| | 4185 | 23 | | var graph = new ActivityNode(activity, "Root"); |
| | 4185 | 24 | | var collectedNodes = new HashSet<ActivityNode>([ |
| | 4185 | 25 | | graph |
| | 4185 | 26 | | ]); |
| | 4185 | 27 | | var collectedActivities = new HashSet<IActivity>([ |
| | 4185 | 28 | | activity |
| | 4185 | 29 | | ]); |
| | 4185 | 30 | | var visitorContext = new ActivityVisitorContext |
| | 4185 | 31 | | { |
| | 4185 | 32 | | CollectedActivities = collectedActivities, |
| | 4185 | 33 | | CollectedNodes = collectedNodes |
| | 4185 | 34 | | }; |
| | | 35 | | |
| | 4185 | 36 | | await VisitRecursiveAsync((graph, activity), visitorContext, cancellationToken); |
| | 4185 | 37 | | return graph; |
| | 4185 | 38 | | } |
| | | 39 | | |
| | | 40 | | private async Task VisitRecursiveAsync((ActivityNode Node, IActivity Activity) pair, ActivityVisitorContext visitorC |
| | | 41 | | { |
| | 17443 | 42 | | if (pair.Activity is IInitializable initializable) |
| | | 43 | | { |
| | 785 | 44 | | var context = new InitializationContext(_serviceProvider, cancellationToken); |
| | 785 | 45 | | await initializable.InitializeAsync(context); |
| | | 46 | | } |
| | | 47 | | |
| | 17443 | 48 | | await VisitPortsRecursiveAsync(pair, visitorContext, cancellationToken); |
| | 17443 | 49 | | } |
| | | 50 | | |
| | | 51 | | private async Task VisitPortsRecursiveAsync((ActivityNode Node, IActivity Activity) pair, ActivityVisitorContext vis |
| | | 52 | | { |
| | 81400 | 53 | | var resolver = _portResolvers.FirstOrDefault(x => x.GetSupportsActivity(pair.Activity)); |
| | | 54 | | |
| | 17443 | 55 | | if (resolver == null) |
| | 0 | 56 | | return; |
| | | 57 | | |
| | 17443 | 58 | | var activityPorts = await resolver.GetActivityPortsAsync(pair.Activity, cancellationToken); |
| | 17443 | 59 | | var collectedActivities = visitorContext.CollectedActivities; |
| | 17443 | 60 | | var collectedNodes = visitorContext.CollectedNodes; |
| | | 61 | | |
| | 54926 | 62 | | foreach (var activityPort in activityPorts) |
| | | 63 | | { |
| | 46788 | 64 | | foreach (var activity in activityPort.GetActivities()) |
| | | 65 | | { |
| | | 66 | | // Continue if the specified activity was already encountered. |
| | 13374 | 67 | | if (collectedActivities.Contains(activity)) |
| | | 68 | | continue; |
| | | 69 | | |
| | 51674 | 70 | | var childNode = collectedNodes.FirstOrDefault(x => x.Activity == activity); |
| | | 71 | | |
| | 13258 | 72 | | if (childNode == null) |
| | | 73 | | { |
| | 13258 | 74 | | childNode = new(activity, activityPort.PortName); |
| | 13258 | 75 | | collectedNodes.Add(childNode); |
| | | 76 | | } |
| | | 77 | | |
| | 13258 | 78 | | childNode.AddParent(pair.Node); |
| | 13258 | 79 | | pair.Node.AddChild(childNode); |
| | 13258 | 80 | | collectedActivities.Add(activity); |
| | 13258 | 81 | | await VisitRecursiveAsync((childNode, activity), visitorContext, cancellationToken); |
| | | 82 | | } |
| | 10020 | 83 | | } |
| | 17443 | 84 | | } |
| | | 85 | | |
| | | 86 | | private class ActivityVisitorContext |
| | | 87 | | { |
| | 25813 | 88 | | public HashSet<IActivity> CollectedActivities { get; set; } = []; |
| | 25813 | 89 | | public HashSet<ActivityNode> CollectedNodes { get; set; } = []; |
| | | 90 | | } |
| | | 91 | | } |