Skip to content

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

@jtnelson

Description

@jtnelson
 /**
     * 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions