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

Runway local filter does not work when Condition/Criteria contains Links #44

Open
jtnelson opened this issue Aug 11, 2024 · 0 comments
Open

Comments

@jtnelson
Copy link
Member

 /**
     * Perform local {@code criteria} resolution and return all the records in
     * {@code clazz} that match.
     * 
     * @param <T>
     * @param clazz
     * @param criteria
     * @param order
     * @param page
     * @param realms
     * @return the matching records in {@code clazz}
     */
    private <T extends Record> Set<T> filter(Class<T> clazz, Criteria criteria,
            @Nullable Order order, @Nullable Page page,
            @Nonnull Realms realms) {
        ConcourseCompiler compiler = ConcourseCompiler.get();
        ConditionTree ast = (ConditionTree) compiler
                .parse($Criteria.amongRealms(realms, criteria));
        String[] keys = compiler.analyze(ast).keys()
                .toArray(Array.containing());
        Predicate<T> filter = record -> compiler.evaluate(ast,
                record.mmap(keys));
        if(page != null) {
            return Pagination.applyFilterAndPage(
                    $page -> order == null ? load(clazz, $page)
                            : load(clazz, order, $page),
                    filter, page);
        }
        else {
            Set<T> records = order == null ? load(clazz) : load(clazz, order);
            return records.stream().filter(filter)
                    .collect(Collectors.toCollection(LinkedHashSet::new));
        }
    }

    /**
     * Perform local {@code criteria} resolution and return all the records in
     * the hierarchy of {@code clazz} that match.
     * 
     * @param <T>
     * @param clazz
     * @param criteria
     * @param order
     * @param page
     * @param realms
     * @return the matching records in the {@code clazz} hierarchy
     */
    private <T extends Record> Set<T> filterAny(Class<T> clazz,
            Criteria criteria, @Nullable Order order, @Nullable Page page,
            @Nonnull Realms realms) {
        ConcourseCompiler compiler = ConcourseCompiler.get();
        ConditionTree ast = (ConditionTree) compiler
                .parse($Criteria.amongRealms(realms, criteria));
        String[] keys = compiler.analyze(ast).keys()
                .toArray(Array.containing());
        Predicate<T> filter = record -> compiler.evaluate(ast,
                record.mmap(keys));
        if(page != null) {
            return Pagination
                    .applyFilterAndPage(
                            $page -> order == null ? loadAny(clazz, $page)
                                    : loadAny(clazz, order, $page),
                            filter, page);
        }
        else {
            Set<T> records = order == null ? loadAny(clazz)
                    : loadAny(clazz, order);
            return records.stream().filter(filter)
                    .collect(Collectors.toCollection(LinkedHashSet::new));
        }
    }

The code above needs to be modified to modify the output of record.mmap to change any Record values to Link.to values. this is because the Criteria that is passed in will feature Links as values (e.g., Operator.LINKS_TO) and that compiler will fail to match that against the actual Record objects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant