Grid custom converter on parameterized type

Hi and thank you for the fantastic new Grid component!

I have a question regarding converters and its getModelType() or getPresentationType() method on parameterized types. Lets say I have a List as the model. Then, to get it to actually run I had to write for getModelType():

return (Class<List<TelephoneNumber>>) (Class<?>) List.class;

I get the feeling I’m doing something wrong here.

What you provide there is simply List.class. Having the cast only helps you to get rid of the compile errors.

If your actual instances would be ArrayList, the right class to provide would be ArrayList.class.

Would be interesting to see how Grid behaves with 2 columns one using List and another one List.

Safest way would be to have your own type and return exactly that one.

Have a look a this small test:

List<Integer> integerList = new ArrayList<Integer>();
List<Float> floatList = new ArrayList<Float>();

// true
System.out.println((integerList.getClass() == floatList.getClass())
        + " - integerList.getClass() == floatList.getClass()");

// true
System.out.println((integerList.getClass() == ArrayList.class)
        + " - integerList.getClass() == ArrayList.class");

// false
System.out.println((integerList.getClass() == List.class)
        + " - integerList.getClass() == List.class");

Thanks for your reply! I understand that the cast is useless but I did get runtime exceptions when definig an ArrayList as you suggest. So should I change the type parameters in the class signature to:

... implements Converter<String, ArrayList<TelephoneNumber>>

Seems counter intuitive since it is implementation detail and the entity is defined as List.

Do you know exactly the type behind that List? Maybe it’s not ArrayList. It’s provided by JPA right, or something like that?

After all List.class is the class you need if your input is of type List, regardless the TelephoneNumber generic type parameter.

Another way to skip that cast is to wrap your list and use the wrapper type with the converter.

Something like:[code]
class PhoneList implements Serializable {

List<TelephoneNumber> phoneNumbers;

// getter, setter, etc...

}

class PhoneListConverter implements Converter<String, PhoneList> {

@Override
public Class<PhoneList> getModelType() {
    return PhoneList.class;
}

// the rest of converter implementation.

}
[/code]

Thank you, Bogdan, that seems reasonable - I will do that instead.

This is the runtime error I get when returning the class of an ArrayList with Converter<String, List> as the type parameters: javax.servlet.ServletException: com.vaadin.server.ServiceException: java.lang.IllegalArgumentException: The converter model type class java.util.ArrayList is not compatible with the property type interface java.util.List (in Column[propertyId:telephoneNumbers] )

OK, I guess that is an internal vaadin error preventing converter from having different generic and method parameter types.

And even if you’d know the actual type of that List, if it’s generated by any framework or even by your code, that type may change, so it’s not reliable. Best is to have a specific type you can rely on and won’t change in the future.

Have a great 1sh of May! We’ll have a small holiday here tomorrow, hopefully you have the same.

Thank you, have a great holiday you too!