Introduce SPI to configure the SpEL Indexer
The SpEL indexer doesn't provide support for Jackson's ArrayNode, and it seems to be non-extensible; whereas, a Jackson ObjectNode can be operated on within a SpEL expression via PropertyAccessor support.
Can you please describe your use case and explain why you want to parse Jackson types in a SpEL expression?
well, we are building up a code-less project which should store request context in JSON since it's data structure is completely dynamic. And this request context will be used by some handler by using config data.
For example, if the request context looks like this: {"a": {"b": [{"c": "dd"},{"c": "ee"}]}}.
there might be a handler which want to make a choice for the next handler base on the value of "a.b[0].c".
it is easy to implement only the fetch logic here. However we might also want to execute some functions and even a calculation. It is hard to finish it from scratch, and here SpEL comes into play, and that is why we need an extended mode for the Indexer class.
How are you evaluating your SpEL expressions?
Do you have custom setup for the SpelExpressionParser, EvaluationContext, etc.?
yes, the context can config property accessor,however, that is no the case for arrayNode. an array item is accessed by the Indexer class which doesn't allow for extending
yes, the context can config property accessor,however, that is no the case for arrayNode. an array item is accessed by the Indexer class which doesn't allow for extending
That is precisely why we asked if you have custom setup for the SpelExpressionParser, EvaluationContext, etc.
I'm assuming you answered "yes" to that question. If that is not what you were answering "yes" to, please expound.
In light of that, would it meet your needs if we made it possible to configure the Indexer so that you could provide your own support for treating a Jackson ArrayNode as an indexed collection -- for example, via a strategy interface that you could implement and register?
yes, it is totally enough.
@aclement, do you have time to introduce a new strategy for customizing the indexer?
If not, simply providing some pseudo-code style tips regarding how you best foresee accomplishing this might be enough for a core committer to take over.
Maybe I can help. I would try to provide a solution for this issue at weekend.
@aclement, do you have time to introduce a new strategy for customizing the indexer?
If not, simply providing some pseudo-code style tips regarding how you best foresee accomplishing this might be enough for a core committer to take over.
I just learned that Spring Integration has custom SpEL support for Jackson.
See their JsonPropertyAccessor (and its nested ArrayNodeAsList type) and SpelPropertyAccessorRegistrar.
Perhaps their is room for synergies between Spring Integration (SI) and Spring Framework regarding SI's current support, this issue, and #26323.
@garyrussell, @artembilan, @aclement, and @jhoeller : thoughts?
Right. We don't have any objections to move JsonPropertyAccessor from Spring Integration to Spring Framework.
The SpelPropertyAccessorRegistrar has direct interaction with the AbstractEvaluationContextFactoryBean which produces prototype instances of the EvaluationContext whenever we evaluation expressions in Spring Integration. Not sure if that is relevant for the current issue. Perhaps JsonPropertyAccessor for the target EvaluationContext is fully enough to satisfy this issue requirements.
To have a fix for #26323 would be a good addition, too.
warping ArrayNode in a list seems good. however, I still commit a pr for this problem as an alternative.
this solution looks like better than https://github.com/spring-projects/spring-framework/pull/26323
thus it would be possible for any type of indexer to make its own accessing implementation moreover it will leave the possibility for the JsonNode to be writable in SpEL one day IMO :)
Hi. We've recently migrated to the 5.3.18 version of spring, expecting this feature to be available.
Nevertheless, I've been surprised to check that it hasn't been merged yet.
This issue has been open several years to date. ¿Is there any problem preventing it to be merged on the main branch?
This issue has been open several years to date. ¿Is there any problem preventing it to be merged on the main branch?
I'm not sure how the time since Feb 9, 2021 (when we first signaled that we would implement the feature) qualifies as "several years".
In any case, this issue is currently assigned to the 6.0.x milestone which means that we will address it in the 6.0.x timeline. We are currently focusing on other topics; however, if we find time to implement this before 6.0 GA we will change the targeted milestone.
Thanks @sbrannen: you're right regarding the date, sorry. Perhaps I was confused by the dates of other issues I navigated before reaching this.
So, is there no possibilitiy of this new functionality being integrated in 5.3.x branch, isn't it?
Thanks @sbrannen: you're right regarding the date, sorry. Perhaps I was confused by the dates of other issues I navigated before reaching this.
No worries.
So, is there no possibilitiy of this new functionality being integrated in 5.3.x branch, isn't it?
It depends. ™️
Yes, I know that's not the answer you were hoping for. So, let me expound.
If the implementation is limited in scope in terms of complexity and possible negative side effects for existing applications, and if there is significant interest from the community, we would then consider backporting the feature to 5.3.x.
Thanks again for your prompt response! Regarding to "It depends. ™️":
If the implementation is limited in scope in terms of complexity and possible negative side effects for existing applications
Just my very humble (and very biased) opinion: revising the patch seems quite clean, as existing applications just don't register IndexAccessor's and, thus, the new code in Indexer.java won't be ever used by old applications. Seems, also, that the affected code is well covered by jUnits.
and if there is significant interest from the community, we would then consider backporting the feature to 5.3.x.
Consider me oficially and significantly interested :wink:
Hi Team,
I have another usecase that would help if we can implement our own Indexer.
consider a situation where I we want to use SpEL in Scala for example.
Map data Error: EL1027E: Indexing into type 'scala.collection.mutable.ListBuffer<Group>' is not supported
org.springframework.expression.spel.SpelEvaluationException: EL1027E: Indexing into type 'scala.collection.mutable.ListBuffer<Group>' is not supported
at org.springframework.expression.spel.ast.Indexer.getValueRef(Indexer.java:192)
at org.springframework.expression.spel.ast.Indexer.getValueInternal(Indexer.java:101)
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:61)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:309)
at org.viablespark.mapper.MapperExpression.getValue(MapperExpression.scala:26)
at org.viablespark.mapper.EntityMapperImpl.mapCollection$$anonfun$1$$anonfun$1(EntityMapper.scala:51)
Being able to register custom collections for index access would be very cool.
自动回复:你的邮件我已经收到,如果需要回复的我会尽快回复的。感谢你的谅解····
Hi @martin-jamszolik. Perhaps the use-case you describe could be covered by registering a Custom PropertyAccessor?
- superseded by #26478
自动回复:你的邮件我已经收到,如果需要回复的我会尽快回复的。感谢你的谅解····