Binding nested Collection items

Hi,
I have a pojo object that is created from a RESTful API Json object.
It has several text and integer field, that get bound nicely to my custom FormLayout throuh FieldGroup’s buildAndBind method.
But it also have one entry that is a Set and I can’t get that bound into a ListSelect automatically.
I am trying to get a component extending FormLayout that will handle that structure when fed with a BeanItemDataSouce - because this scenario will return as I implement more screens.
I tried the bind with Field method, etc. to no avail. I can only get it to work if I extract it from the bean and wrap it in a container manually, and then bind it to a component seperately from the FormLayout component.
What would be the correct way to go?

Ok, I mamnaged to make the field be set to ListSelect by writing a FieldGroupFieldFactory extention.
But I still can’t get it to bind. What am I missing?
Looks like I should have somehow passed the Set to the ListSelect’s constructor.
In the form the field is added by addComponent(fieldGroup.buildAndBind(propertyId));
Here is the Field Factory class:

package com.watchdox.rotisserie.common.converters;

import java.util.Set;

import com.vaadin.data.fieldgroup.DefaultFieldGroupFieldFactory;
import com.vaadin.data.fieldgroup.FieldGroupFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.ListSelect;

public class ListSelectFieldFactory implements FieldGroupFieldFactory {

    private FieldGroupFieldFactory delegate = new DefaultFieldGroupFieldFactory();

    @Override
    public <T extends Field> T createField(Class<?> dataType, Class<T> fieldType) {
        if (dataType.isAssignableFrom(Set.class)) {
            return (T) new ListSelect();
        }
        return delegate.createField(dataType, fieldType);
    }
}

So. I got it to work reasonably by just wiritng a method in my custom form component that gets an Array of propertyIds, and then create the correct Select if the property is a Set, and feeds it with the Set.
Else it build and binds.
But it would have been nice if Vaadin would handle it out of the box binding fields that get a ContainerDataSource to Collection type properties in buildAndBind.
What I mean is that this doesn’t work:

[code]
addComponent(fieldGroup.buildAndBind(DefaultFieldFactory
                        .createCaptionByPropertyId(propertyId), propertyId, ListSelect.class));
[/code]

The more I think about it, more it seems just like a bug in vaadin.
The code that works in my custom form component is:

private void setBoundFields(Object[] propertyIds) { for (Object propertyId : propertyIds) { if (itemDataSource.getItemProperty(propertyId).getType().isAssignableFrom(Set.class)){ Set dataSet = (Set) itemDataSource.getItemProperty(propertyId).getValue(); ListSelectWithControls field = new ListSelectWithControls(DefaultFieldFactory .createCaptionByPropertyId(propertyId)); addComponent(field); if(dataSet!=null){ field.setContainerDataSource(new IndexedContainer(dataSet)); } } else { addComponent(fieldGroup.buildAndBind(propertyId)); } } } But it’s still problematic.
This way the component is not a member of the field group, and will not be commited together with it.
When replacing the first part of the if with the code from the post above, a ListSelect is created but is not bound to the data.
The same is when bypassing the condition and just adding with property id relying on the FieldFactory I mentioned two posts above.
It seems to me that fieldgroup should just be able to bind fields that receive a ContainerDataSource out of the box.

Hi, what String values are allowedd in the your domain models Set field? Any string value or some specific valeus from a pre-defined options?

I think either MultiSelectTable or ElementCollectionField from Viritin is what you are looking fo.

cheers,
matti

I this specific case it would be a set of email addresses.
Set emailAddresses;
I will look into your add on, it seems very cool!