Hi,
Can a truly lazy, possibly infinitely deep container be implemented cleanly in Vaadin, and if so, how?
Context
I’m looking at how to implement a custom hierarchical container. I want to make a container that lazily builds its children. The item hierarchy can be infinitely deep, so there is no way to enumerate all the items.
If that seems like a far-fetched use-case, take the “variables” view in a debugger (e.g. Eclipse) as an example, where cyclic references also give an infinite tree.
A container that is just very (but not infinitely) deep, and tries to be lazy runs into the same problems.
Details
Some methods in the Container and its sub-interfaces bother me, because they simply cannot be implemented for such a container. It looks to me like they only make sense for a flat container, but Hierarchical extends Container, so there’s no way around them.
To start there’s Container.size() and Container.getItemIds(). It’s not explicit in the api docs, but looking at some of the implementations it looks like this is about all the items in the container, not just the roots.
The only way to implement those is to recursively go into each item, which is not only bad for performance (which, for example for FilesystemContainer, in a big directory structure it definitely is), but in an infinite tree simply impossible.
Strictly speaking, getItemIds()
could
return an infinite Collection, but I don’t expect code that uses the Collection is going to deal with that properly.
To show the container in a tree, those methods shouldn’t be needed anyways. Letting those methods throw an exception works in my first tests, so they are indeed not called in practice. But it’s not a
right
solution: there’s no guarantee that nothing is going to call them when combining them with other feature (say, expandItemsRecursively), or in a future version,… They are not optional methods like the ones that throw UnsupportedOperationException.
In fact, if I use such a container in a TreeTable, it already fails because that tries to wrap it in a HierarchicalContainerOrderedWrapper which calls getItemIds(). I can try to work around that by implementing Ordered myself, but then I’m just stuck with even more methods that are impossible to implement, such as lastItemId() and prevItemId(): both may require to go infinitely deep again.
Do I misunderstand something, or is it impossible to have infinite, or even just truly lazy hierarchical containers cleanly?
Thanks.