Hi Remko,

Remko Tronçon wrote:

> Hi Jörg,
> 
> On 11 September 2013 21:48, Jörg Schaible
> <[email protected]> wrote:
>> UnmarshalingContext.getRequiredType contains normally the correct thing.
> 
> Well, it is correct, in the sense that it says it requires an
> "Optional".

Well, since Optional is abstract, it should contain the real type. I thought 
you talked about that.

> However, where would i get the actual generic type? (e.g.,
> for Optional<String>, I want to get 'String.class'). I don't think you
> can get this from the context.getRequiredType() Class return value,
> can you?

You might, but it depends on the concrete situation.

In any case, your converter has to know the proper type at deserialization 
time, it is your converter's responsibility. XStream's converters will write 
in such a case the class name into the attribute of the child element or use 
the class name directly as tag name of the child element and use that to 
create the proper type at deserialization. Assuming your converter receives 
the Mapper in its constructor, your marshalling code would normally look 
similar to:

============ %< ================
 Object object = ((Optional<?>)value).get();
 String name = mapper.serializableName(object.getClass())
 writer.startNode(name);
 context.convertAnother(object);
 writer.endNode();
============ %< ================

However, I simply guess that you try not to nest the value of the Optional 
in your converter.

Consider this type from your example:

============ %< ================
 class Bar {
   Optional<String> myField1;
 }
============ %< ================

Since Optional is abstract, "myfield" must have been populated with a 
concrete class, e.g. an instance of:

============ %< ================
 class OptionalString extends Optional<String> {
  ...
 }
============ %< ================

This will normally result in:

============ %< ================
 <Bar>
   <myField1 class="OptionalString">Hello, word!</myField1>
 </Bar>
============ %< ================

The class attribute is written (by the ReflectionCOnverter that handles 
"Bar" types), because the instance in "myField1" has a different type 
compared to the field's declaration. At deserialization time  
context.getRequiredType() should contain "OptionalString". And I am quite 
sure that you can find the generic type with:

============ %< ================
 Class optional=context.getRequiredType();
 while(!Optional.class.equals(optional)) {
   optional = optional.getSuperclass();
 }
 Class genericType = optional.getGenericType();
============ %< ================

- Jörg



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to