Help with filterExpression method in notification filters

I’m creating global notification filter that filters hidden documents.

I created new component based on role org.xwiki.notifications.NotificationFilter as documented here

There inside filterEvent method i have this

    return event.getDocument().isHidden()
            ? FilterPolicy.FILTER : FilterPolicy.NO_EFFECT;

But Im struggling how do I rewrite this condition in filterExpression method

@Override
public ExpressionNode filterExpression(DocumentReference user,
        Collection<NotificationFilterPreference> filterPreferences,
        NotificationFilterType type, NotificationFormat format)
{
    // what comes here??
}

Any help greatly appreciated.

I don’t know this topic and can’t help you much but the way I’d approach it is to check for example code implementing NotificationFilter and see how they do it.

Screenshot 2020-12-11 at 13.04.53

Note that I agree that the javadoc is pretty bad:

    /**
     * Filtering expression to use when retrieving notifications.
     *
     * @param user the user interested in the notifications
     * @param filterPreferences the collection of all preferences to take into account
     * @param preference the notification preference associated with the filter
     * @return the updated query
     *
     * @since 9.7RC1
     */
    ExpressionNode filterExpression(DocumentReference user, Collection<NotificationFilterPreference> filterPreferences,
            NotificationPreference preference);

It says the updated query but it doesn’t explain where is the query? I don’t see any query being passed!

cc @gdelhumeau

I understand that filterEventExpression is just condition rewritten as an expression, for example
in existing SystemUserNotificationFilter (for filtering system events) the filterEvent is

{
    return event.getUser() != null && event.getUser().getLocalDocumentReference().equals(SYSTEM_USER)
            ? FilterPolicy.FILTER : FilterPolicy.NO_EFFECT;
}

and corresponding FilterExpression is

    {
        if (type == NotificationFilterType.EXCLUSIVE) {
            return value(EventProperty.USER).notEq(value(serializer.serialize(SYSTEM_USER)));
        }
        return null;
    }

I still have no clue how to rewrite condition in my first post.

what do you need to rewrite?

are you saying there are no code example that is not returning null?

I see for ex:

    @Override
    public ExpressionNode filterExpression(DocumentReference user,
        Collection<NotificationFilterPreference> filterPreferences, NotificationFilterType type,
        NotificationFormat format)
    {
        if (user != null && type == NotificationFilterType.EXCLUSIVE && format == this.format) {
            ForUserNode node = new ForUserNode(user, this.read, this.format);

            return this.not ? not(node) : node;
        }

        return null;
    }

or:

    @Override
    public ExpressionNode filterExpression(DocumentReference user,
            Collection<NotificationFilterPreference> filterPreferences,
            NotificationFilterType type, NotificationFormat format)
    {
        if (type == NotificationFilterType.EXCLUSIVE && format == this.format) {
            return not(
                    value(EventProperty.TYPE).eq(value(UPDATE_TYPE)).and(
                        not(value(EventProperty.DOCUMENT_VERSION).endsWith(value(VERSION_SCHEME)))
                    )
            );
        }
        return null;
    }

etc

I m struggling to rewrite event.getDocument().isHidden() as filterExpression

well it turned out that filterEvent method only was sufficient enough (no filterExpression necessary)

I set it like this

public FilterPolicy filterEvent(Event event, DocumentReference user,
        Collection<NotificationFilterPreference> filterPreferences, NotificationFormat format)
{
    return event.getHidden() ? FilterPolicy.FILTER : FilterPolicy.NO_EFFECT;
}

then compiled and my global hidden files filter works!