context: So I've been trying to work with SPEL and Mono instance as input that would be parsed to an instance of Mono but SPEL isn't able to do the conversion and handle a Mono instance

@UtilityClass

public class ReactiveSpelUtil {

    private static ExpressionParser SPEL_PARSER = new SpelExpressionParser();

    private static final EvaluationContext STANDARD_EVALUATION_CONTEXT = new StandardEvaluationContext();

    @SuppressWarnings("ALL")
    public static Mono<Boolean> evaluate(final Object rootObject, String expression) {

        STANDARD_EVALUATION_CONTEXT.setVariable(rootObject.getClass().getSimpleName(),rootObject);

        return SPEL_PARSER.parseExpression(expression)
                .getValue(STANDARD_EVALUATION_CONTEXT, Mono.class);
    }
    // expression sample is #rootObject.age>20 , age is wrapped in Mono
}

The Problem: I usually get error like this EL1013E: Cannot compare instances of class reactor.core.publisher.MonoJust and class java.lang.Integer, and the problem is that I can't do the parsing inside the map of the mono instance itself age because the expressions are built in a way that can be parsed only as per the above code, so is there any way to achieve working with Mono instances as part of (within) SPEL expression?

Comment From: rstoyanchev

SpEL wasn't designed with this in mind and I'm not sure how it would work out more generally with both Flux and Mono potentially in the expression, and/or in the output type. Can you provide a little more on the context in which ReactiveSpelUtil is used so that the use case is more clear?

Comment From: saeed-abdelhalim

Hello, it will be more or less like the following

@UtilityClass
public class ReactiveSpelUtil {

    private static ExpressionParser SPEL_PARSER = new SpelExpressionParser();

    @SuppressWarnings("ALL")
    public static Mono<Boolean> evaluate(final RootObject rootObject, String expression) {

        EvaluationContext STANDARD_EVALUATION_CONTEXT = new StandardEvaluationContext(rootObject);
        STANDARD_EVALUATION_CONTEXT.setVariable(rootObject.getClass().getSimpleName(), rootObject);

        return SPEL_PARSER.parseExpression(expression)
                .getValue(STANDARD_EVALUATION_CONTEXT, Mono.class);
    }
    public static void main(String[] args) {

        RootObject rootObject = new RootObject(Mono.just(new Person(21f, "Saeed")));

        evaluate(rootObject, "getPerson().getAge()>20 and getPerson().getName().equalsIgnoreCase(\"Saeed\")")
                .subscribe(System.out::println);
    }

    @Getter
    @AllArgsConstructor
    static class Person {

        private float age;

        private String name;
    }

    @Getter
    @AllArgsConstructor
    static class RootObject {

        private Mono<Person> person;
    }
}

I know using getPerson().getAge() in the expression doesn't make sense because getPerson() is Mono, but that's how the expressions I want to parse is built, I tried to find a way to work with Mono like using something like this expression "{T(reactor.core.publisher.Mono).from(getPerson()).block().getAge()>20}" as I can't use .map(..) while SPEL doesn't supports lambdas but this expression is blocking which what I need to avoid and for sure it returns Boolean not Mono`

Comment From: rstoyanchev

You can add a transformation that resolves the Person before pass it to SpEL. Something like this:

public static Mono<Boolean> evaluate(final RootObject rootObject, String expression) {

    return rootObject.getPerson().map(person -> {

        EvaluationContext STANDARD_EVALUATION_CONTEXT = new StandardEvaluationContext(person);
        STANDARD_EVALUATION_CONTEXT.setVariable(person.getClass().getSimpleName(), person);

        return SPEL_PARSER.parseExpression(expression)
                .getValue(STANDARD_EVALUATION_CONTEXT, boolean.class);
    });
}

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.