using Elsa.Expressions;
using Elsa.Expressions.Contracts;
using Elsa.Expressions.Models;
using Elsa.Workflows.Core.Contracts;
using Elsa.Workflows.Core.Expressions;
namespace Elsa.Workflows.Management.Providers;
///
public class DefaultExpressionSyntaxProvider : IExpressionSyntaxProvider
{
private readonly IIdentityGenerator _identityGenerator;
///
/// Initializes a new instance of the class.
///
public DefaultExpressionSyntaxProvider(IIdentityGenerator identityGenerator)
{
_identityGenerator = identityGenerator;
}
///
public ValueTask> GetDescriptorsAsync(CancellationToken cancellationToken = default)
{
var literal = CreateLiteralDescriptor();
var @object = CreateObjectDescriptor();
var json = CreateJsonDescriptor();
var @delegate = CreateDelegateDescriptor();
return ValueTask.FromResult>(new[] { literal, @object, json, @delegate });
}
private ExpressionSyntaxDescriptor CreateLiteralDescriptor() => DefaultExpressionSyntaxProvider.CreateDescriptor(
"Literal",
CreateLiteralExpression,
context => new Literal(context.GetExpression().Value),
expression => expression.Value);
private ExpressionSyntaxDescriptor CreateObjectDescriptor() => DefaultExpressionSyntaxProvider.CreateDescriptor(
"Object",
CreateObjectExpression,
context => new ObjectLiteral(context.GetExpression().Value),
expression => expression.Value);
// TODO: this is replaced by the above and exists only for existing workflow definitions. To be removed in a future version.
[Obsolete]
private ExpressionSyntaxDescriptor CreateJsonDescriptor() => DefaultExpressionSyntaxProvider.CreateDescriptor(
"Json",
CreateObjectExpression,
context => new ObjectLiteral(context.GetExpression().Value),
expression => expression.Value);
private ExpressionSyntaxDescriptor CreateDelegateDescriptor() => DefaultExpressionSyntaxProvider.CreateDescriptor(
"Delegate",
CreateObjectExpression,
context => new DelegateBlockReference(),
expression => expression.DelegateBlockReference.Delegate?.ToString());
private static ExpressionSyntaxDescriptor CreateDescriptor(
string syntax,
Func constructor,
Func createBlockReference,
Func expressionValue) =>
new()
{
Syntax = syntax,
Type = typeof(TExpression),
CreateExpression = constructor,
CreateBlockReference = createBlockReference,
CreateSerializableObject = context => new
{
Type = syntax,
Value = expressionValue(context.GetExpression())
}
};
private static IExpression CreateLiteralExpression(ExpressionConstructorContext context)
{
return !context.Element.TryGetProperty("value", out var expressionValue)
? new LiteralExpression()
: new LiteralExpression(expressionValue.ToString());
}
private IExpression CreateObjectExpression(ExpressionConstructorContext context)
{
var expressionValue = context.Element.GetProperty("value").ToString();
return new ObjectExpression(expressionValue);
}
private string GenerateId() => _identityGenerator.GenerateId();
}