Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converters for collection elements #62

Open
morvael opened this issue Aug 10, 2016 · 5 comments
Open

Converters for collection elements #62

morvael opened this issue Aug 10, 2016 · 5 comments
Assignees

Comments

@morvael
Copy link

morvael commented Aug 10, 2016

I would like to see the ability to easily define custom converters for elements inside collections (maps, lists, arrays), especially using annotations, added to XStream. Currently it's only possible to declare custom converters for a type (which results in all conversions of that type to use specified converter), or field (which results in conversion of that field to use specified converter). However, there is no easy way to specify converters for elements in collection fields, which means they are only able to use default or type converters, alternatively one has to write a custom collection converter. It all boils down to being able to affect the selection of item converter in various collection-converting classes. For example in the all-important AbstractReflectionConverter map entries are written using writeItem method which simply calls
context.convertAnother(item);
while other fields are written using more sophisticated writeField and marshallField methods, which call
context.convertAnother(newObj, mapper.getLocalConverter(field.getDeclaringClass(), field.getName()));
looking for a local converter. I don't think it would be very hard to extend the first call to look for the same information, maybe just extend the XStreamConverter annotation to allow specifying whether given converter applies to the field itself, keys of the map, or values of the collection.

@joehni joehni self-assigned this Aug 15, 2016
@joehni
Copy link
Member

joehni commented Aug 16, 2016

Definitions for a local converter are currently bound to a field declaration.

Definitions for items of a collection, array of map has been always too complex to do it properly for all cases:

  • for a specific collection/array/map of a class only and is the definition 
    inherited?
  • only for special element types?
  • support for more than one local converter to handle different element 
    types?
  • what happens if these elements are based on derived types?
  • how to define all of this for the keys in case of a map?

And this complete configuration should be respected by any converter 
handling collection or map and arrays are not even handled by a converter 
...

It has always been easier to write a specialized custom converter for a 
collection.

@morvael
Copy link
Author

morvael commented Aug 16, 2016

I think the problems mentioned are a bit superficial. Similar ones could be asked about non-collection local field converters, which throw exception if they can't handle type referenced by the field. All that is needed is handling an extra annotation type(s) specifying converter(s) for collection values and/or keys. Then it's just a matter of asking a mapper whether there are local value and/or key converters before calling context.convertAnother. Yes, some converters will have to be updated to make it work, and writeItem in AbstractCollectionConverter should be parameterized to know whether it's writing key or value and the name and class of the field being written. It's 100% doable, but of course some pieces of code will have to be altered to make it possible. That's why I called it a new feature.

@joehni
Copy link
Member

joehni commented Aug 16, 2016

Don't get me wrong, my list just reflects, what has to be considered for such an enhancement, I did not close this issue. And remember that any functionality in XStream can be triggered without using any annotation. They are used as syntactic sugar.

@morvael
Copy link
Author

morvael commented Aug 16, 2016

I'm pretty sure these issues can be resolved. I'd see these converters added in parallel to local field converters so that existing API is not affected.

XStreamValueConverter to define local collection value converter (and similarly called method in XStream class to add the same function without annotation; related method in Mapper interface to query this information from converters; finally converter extension when applicable to read this information and apply when necessary instead of relying on default behavior of convertAnother with no converter is specified). Then an XStreamValueConverters annotation to specify multiple local collection value converters in Java older than 8. Finally, a similar set for keys (XStreamKeyConverter). That would be it, I believe.

@morvael
Copy link
Author

morvael commented Feb 1, 2017

I was looking at Jackson these days, and it seems they didn't have problems with including using, keyUsing, and contentUsing attributes in @JsonSerialize and @JsonDeserialize annotations, that allow to define what custom JsonSerializers/JsonDeserializers (Converters in XStream's language) are to be used. First one is used for field itself, second for keys (if the field is a map), third for values (if the field is a map or collection).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants