BeanItemContainer filters - private makes subclassing impossible

I’d like to add some filters to a BeanItemContainer, but it turns out that I cannot do it because the filters HashSet is private. Or perhaps I don’t understand how to add my own filters to the container. I am using Vaadin 6.3.3.

Currently, it seems that BeanItemContainer is limited to only a simple Filter by using the method:
addContainerFilter(Object propertyId, String filterString,boolean ignoreCase, boolean onlyMatchPrefix)

But I have needs to filter numbers in a range, or filter using an exact match (not just contains or starts with), or perhaps a RegEx expression.

I see how I can subclass Filter to then override ‘public boolean passesFilter(Item item)’ to do whatever I need. It appears I may also need to override equals/hashCode. Then I could create my own IntegerRangeFilter and ExactMatchFilter and RegExFilter to do what I need.

But I can’t get these filters added to the BeanItemContainer because there’s not ‘addFilter(Filter f)’ type method to use, and the addContainerFilter will only do that one built-in filter.

What I’d like is something like:

   // Add this method
    public void addFilter(Object propertyId, Filter f) {
        if (filters.isEmpty()) {
            filteredItems = (ListSet<BT>) allItems.clone();
        }
        // listen to change events to be able to update filtering
        for (BeanItem<BT> item : beanToItem.values()) {
            addValueChangeListener(item, propertyId);
        }
        filters.add(f);
        fireItemSetChange();
    }

   // And modify this current method
    public void addContainerFilter(Object propertyId, String filterString,
            boolean ignoreCase, boolean onlyMatchPrefix) {
        Filter f = new Filter(propertyId, filterString, ignoreCase,
                onlyMatchPrefix);
        addFilter(propertyId, f);
    }

Is this possible so I can do my own filters? Or is there a better way I should be approaching this?

Thanks much…

Is there any hope of this slight rework to provide a generic addFilter method? It seems like it should be seamless to existing apps and provide the ability for me to add my own filters.

We just found another need in which we have a single flag char that can take on any of several state values: Starting → In progress → Completed (with an optional end state of Canceled instead of Completed) and we’d like the user to be able to filter on any 1-4 of these states, so we’d like to have 4 checkboxes where the user can choose which to see and then have it filter the selected ones (if just one is chosen, it’s easy to do with the built in filter, and if all are chosen, it’s easy to do by removing the filter, but if 2 or 3 are chosen, there’s no good way currently to do this).

Yes, I also would like to have a more “generic” method to add a custom filter.
Currently I copied the whole IndexedContainer class and its dependencies and added such a method.

Is there really no interest at Vaadin to open up the adding of Filters to BeanItemContainer? If not, I guess I can copy your BeanItemContainer and make my own, but this and other threads (i.e. Filter Constructor/Member Visibilty) seem to indicate that allowing other Filters would be desirable. It seems like Filter was made to be subclassed, and so allowing us to add our own filters instead of the overly simple string filter (which doesn’t even support exact matches much less regex or multi-values or numbers/money/dates) would be really nice.

The code I wrote previously in this thread seems like it would do it just fine, working for current calls and allowing us to add our own Filters to properties. Or at the very least make the 'filter’s protected so I could just subclass.

Thanks for any ideas since I prefer not to clone code, especially BeanItemContainer which is used frequently in our app.

There is definitely interest in the Vaadin team for improving containers, including aspects such as filtering. For instance the Filter class (which should not have been a class but an interface in the first place) was meant to be generally applicable to situations where not all all data is in memory etc. but was not designed carefully enough. Then, we have been too reluctant to break this API.

As the container improvements will involve breaking some APIs, such work is targeted for Vaadin 7. Before that, there might be minimal changes, but we would prefer not opening up some API and immediately afterwards breaking it.

Thanks, Henri for you consideration.

For the change suggested, nothing should break the API. Either making ‘filters’ protected so we can subclass to add our own, or providing an addFilter(Filter t) method should not break any existing code.

It seems like Vaadin 7 has no anticipated release date, so it could be a very long time off. Also, the change suggested (perhaps it’s not sufficient?) would have to be considered a “minimal change” as it does not alter the existing API to add the one specific filter to the BeanItemContainer, but does open up the ability to add other Filters that could do more (like we’d like a filter that could test against more than one value, in which the user selects one or more ‘status’ values so that we can display those that match those checked statuses).

At least doing this change would allow us to develop within the Vaadin framework as it is now – seems like the ability to add other Filters was an oversight, not a design decision – rather than us having to do what others have done and that’s clone code and then modify it just to do what simple subclassing would allow.

If Vaadin 7 breaks the container APIs to be more robust/easier to use, I’m sure the Filter issue will be minor in comparison. When can we learn more about Vaadin 7 and begin coding against it?