Context in SingleValueConverter

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Context in SingleValueConverter

Carlos Ferreyra
I see XSTR-367 has been closed.

I have a case where I read an attribute with the date format used in dates strings in subsequent tags. I wanted to read this date format using a SingleValueConverter that would store it in the context data holder, but SingleValueConverter does not receive such context.

I'd like to know if it is possible to override this behaviour.

Example:

<root format="yyyy/MM/dd">
    <entry date="1980/01/09">
        <some-terribly-important-values>...
    </entry>
   ...
</root>

As it stands, the only solution I see is to construct a Converter for the whole entry object. I wanted to avoid this since the entry is a complex object and I want to keep the coding to marshall/unmarshall to a minimum.

I'd like to propose this scenario and ask for reopen of XSTR-367.

Thanks,
Carlos.

Reply | Threaded
Open this post in threaded view
|

Re: Context in SingleValueConverter

Jörg Schaible-3
Hi Carlos,

Carlos Ferreyra wrote:

> I see XSTR-367 <http://jira.codehaus.org/browse/XSTR-367> has been closed.
>
> I have a case where I read an attribute with the date format used in dates
> strings in subsequent tags. I wanted to read this date format using a
> SingleValueConverter that would store it in the context data holder, but
> SingleValueConverter does not receive such context.
>
> I'd like to know if it is possible to override this behaviour.
>
> Example:
>
> <root format="yyyy/MM/dd">
>     <entry date="1980/01/09">
>         <some-terribly-important-values>...
>     </entry>
>    ...
> </root>
>
> As it stands, the only solution I see is to construct a Converter for the
> whole entry object. I wanted to avoid this since the entry is a complex
> object and I want to keep the coding to marshall/unmarshall to a minimum.
>
> I'd like to propose this scenario and ask for reopen of
> XSTR-367<http://jira.codehaus.org/browse/XSTR-367>

Isn't it possible for you to do so? Your use case is actually valid.

However, don't expect a fast solution here. The main problem is, that there
*is* actually no proper context for a SingleValueConverter. The
UnmarshallingContext is a construct of the MarshallingStrategy. It can be
called for every XML *element* to find the proper converter and will execute
the conversion.

Attributes are handled completely differently. A SingleValueConverter can be
requested by every converter that uses the Mapper instance of XStream. To
support at least the custom values from the UnmarshallingContext means that
all those converters that currently use the SingleValueConverter have to
support a modified interface, not to mention from all custom converters of
the XStream clients using or implementing SingleValueConverter...

As current alternative you may derive the EntryConverter from the
ReflectionConverter (assuming that this one will handle the Entry by
default) and handle the date before calling the super class. You will have
to configure XStream to omit the field containing the date though, because
you're handling it "manually":

=================== %< ============
 class EntryConverter extends ReflectionConverter {
   EntryConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
     super(mapper, reflectionProvider);
   }

   boolean canConvert(Class type) {
     return type = Entry.class;
   }

   void marshal(Object original, HierarchicalStreamWriter writer,
MarshallingContext context) {
     Entry entry = (Entry)original;
     DateFormat format = (DateFormat)context.get("format");
     writer.addAttribute("date", format.format(entry.getDate()));
     super.marshal(original, writer, context);
   }

   Object unmarshal(Object result, HierarchicalStreamReader reader,
UnmarshallingContext context) {
     DateFormat format = (DateFormat)context.get("format");
     Date date = format.parse(reader.getAttribute("date"));
     Entry entry = (Entry)super.unmarshal(result, reader, context);
     entry.setDate(date);
     return entry;
   }
 }

=================== %< ============

Regards,
Jörg



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

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Context in SingleValueConverter

Carlos Ferreyra
Hi Jörg,

Thanks for your explanation. 
I do understand the amount of work required to provide such context to SingleValueConverter instances.
I'll go with the approach of extending ReflectionConverter.

Regards,
Carlos.


2013/10/14 Jörg Schaible <[hidden email]>
Hi Carlos,

Carlos Ferreyra wrote:

> I see XSTR-367 <http://jira.codehaus.org/browse/XSTR-367> has been closed.
>
> I have a case where I read an attribute with the date format used in dates
> strings in subsequent tags. I wanted to read this date format using a
> SingleValueConverter that would store it in the context data holder, but
> SingleValueConverter does not receive such context.
>
> I'd like to know if it is possible to override this behaviour.
>
> Example:
>
> <root format="yyyy/MM/dd">
>     <entry date="1980/01/09">
>         <some-terribly-important-values>...
>     </entry>
>    ...
> </root>
>
> As it stands, the only solution I see is to construct a Converter for the
> whole entry object. I wanted to avoid this since the entry is a complex
> object and I want to keep the coding to marshall/unmarshall to a minimum.
>
> I'd like to propose this scenario and ask for reopen of
> XSTR-367<http://jira.codehaus.org/browse/XSTR-367>

Isn't it possible for you to do so? Your use case is actually valid.

However, don't expect a fast solution here. The main problem is, that there
*is* actually no proper context for a SingleValueConverter. The
UnmarshallingContext is a construct of the MarshallingStrategy. It can be
called for every XML *element* to find the proper converter and will execute
the conversion.

Attributes are handled completely differently. A SingleValueConverter can be
requested by every converter that uses the Mapper instance of XStream. To
support at least the custom values from the UnmarshallingContext means that
all those converters that currently use the SingleValueConverter have to
support a modified interface, not to mention from all custom converters of
the XStream clients using or implementing SingleValueConverter...

As current alternative you may derive the EntryConverter from the
ReflectionConverter (assuming that this one will handle the Entry by
default) and handle the date before calling the super class. You will have
to configure XStream to omit the field containing the date though, because
you're handling it "manually":

=================== %< ============
 class EntryConverter extends ReflectionConverter {
   EntryConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
     super(mapper, reflectionProvider);
   }

   boolean canConvert(Class type) {
     return type = Entry.class;
   }

   void marshal(Object original, HierarchicalStreamWriter writer,
MarshallingContext context) {
     Entry entry = (Entry)original;
     DateFormat format = (DateFormat)context.get("format");
     writer.addAttribute("date", format.format(entry.getDate()));
     super.marshal(original, writer, context);
   }

   Object unmarshal(Object result, HierarchicalStreamReader reader,
UnmarshallingContext context) {
     DateFormat format = (DateFormat)context.get("format");
     Date date = format.parse(reader.getAttribute("date"));
     Entry entry = (Entry)super.unmarshal(result, reader, context);
     entry.setDate(date);
     return entry;
   }
 }

=================== %< ============

Regards,
Jörg



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

    http://xircles.codehaus.org/manage_email