Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: filter state by string #4829

Merged
merged 1 commit into from
Feb 20, 2025

Conversation

ndr-brt
Copy link
Member

@ndr-brt ndr-brt commented Feb 17, 2025

What this PR changes/adds

Supports filtering stateful entities by the state string representation.

The concept evolves around an interface that provides a way to convert a String state representation into int:

public interface StateResolver {

    int resolve(String stringState);

}

Different paths have been followed for in memory and sql stores.

In memory

The logic of the ReflectionBasedQueryResolver that takes care to apply a QuerySpec to a Stream was quite coupled, so a CriteriaToPredicate interface was introduced, it just converts a List<Criterion> into a Predicate<ENTITY>.
The default implementation has the same logic that was in the resolver:

    @Override
    public Predicate<T> convert(List<Criterion> criteria) {
        return criteria.stream()
                .map(criterionOperatorRegistry::<T>toPredicate)
                .reduce(x -> true, Predicate::and);
    }

The "stateful" implementation relies on a StateResolver to map the string status to int:

    @Override
    public Predicate<E> convert(List<Criterion> criteria) {
        return criteria.stream()
                .map(criterion -> {
                    if (criterion.getOperandLeft().equals("state") && criterion.getOperandRight() instanceof String stateString) {
                        return criterion(criterion.getOperandLeft(), criterion.getOperator(), stateResolver.resolve(stateString));
                    }
                    return criterion;
                })
                .map(criterionOperatorRegistry::<E>toPredicate)
                .reduce(x -> true, Predicate::and);
    }

Sql

The implementation for this branch is much easier because the design of the FieldTranslator permitted to implement an EntityStateFieldTranslator that, with the help of the StateResolver collaborator it provides the translation quite easily:

public class EntityStateFieldTranslator extends PlainColumnFieldTranslator {

    private final StateResolver stateResolver;

    public EntityStateFieldTranslator(String columnName, StateResolver stateResolver) {
        super(columnName);
        this.stateResolver = stateResolver;
    }

    @Override
    public Collection<Object> toParameters(Criterion criterion) {
        return super.toParameters(criterion)
                .stream()
                .map(it -> it instanceof String stringState ? stateResolver.resolve(stringState) : it)
                .collect(toList());
    }
}

Why it does that

permit entities state field to be queried both by the actual type int and by their String representation.

Further notes

List other areas of code that have changed but are not necessarily linked to the main feature. This could be method
signature changes, package declarations, bugs that were encountered and were fixed inline, etc.

Who will sponsor this feature?

Please @-mention the committer that will sponsor your feature.

Linked Issue(s)

Closes #4785

Please be sure to take a look at the contributing guidelines and our etiquette for pull requests.

@ndr-brt ndr-brt added the enhancement New feature or request label Feb 17, 2025
@ndr-brt ndr-brt force-pushed the 4785-filter-state-string branch from a954ffd to c2bc34b Compare February 17, 2025 08:41
*/
Stream<T> query(Stream<T> stream, QuerySpec spec, BinaryOperator<Predicate<Object>> accumulator, Predicate<Object> fallback);
@Deprecated(since = "0.12.0")
default Stream<T> query(Stream<T> stream, QuerySpec spec, BinaryOperator<Predicate<Object>> accumulator, Predicate<Object> fallback) {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'accumulator' is never used.
*/
Stream<T> query(Stream<T> stream, QuerySpec spec, BinaryOperator<Predicate<Object>> accumulator, Predicate<Object> fallback);
@Deprecated(since = "0.12.0")
default Stream<T> query(Stream<T> stream, QuerySpec spec, BinaryOperator<Predicate<Object>> accumulator, Predicate<Object> fallback) {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'fallback' is never used.
@ndr-brt ndr-brt force-pushed the 4785-filter-state-string branch 2 times, most recently from 1d80d57 to 3740856 Compare February 17, 2025 10:22
@ndr-brt ndr-brt force-pushed the 4785-filter-state-string branch from 3740856 to 13b7519 Compare February 17, 2025 12:40
Copy link
Contributor

@wolf4ood wolf4ood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@ndr-brt ndr-brt merged commit d957a50 into eclipse-edc:main Feb 20, 2025
21 checks passed
@ndr-brt ndr-brt deleted the 4785-filter-state-string branch February 20, 2025 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Filter expression on state
2 participants