On Mar 20, 2012, at 3:37 PM, Jörg Schaible wrote:
> Hi Bjorn
>
> Bjorn Roche wrote:
>
>> Hey all,
>>
>> First off, I heart XStream. I just wanted to share a problem I had
>> recently and how I solved it. It seems to me the solution is unintuitive
>> and hard to find. This maybe isn't a bug, but at the very least I think it
>> should be easier to do what I needed to do, or maybe his needs to be a FAQ
>> or something.
>>
>> So here's my story:
>>
>> I noticed my dates were not being converted the way I wanted. After much
>> searching I found this: http://jira.codehaus.org/browse/XSTR-116 Ah hah!
>> that's all I need to do!
>>
>> - first comment: that should be a FAQ or something. ISO8601 dates are
>> pretty widely accepted as standard for XML, right? If they don't work
>> automatically, it should be easy for people to figure out how to make them
>> work, and I think the FAQ is the right place for that.
>
>
> The ISO8601 converters are listed:
> http://xstream.codehaus.org/converters.html
Fair enough. So much of xstream is automagic that when a widely accepted format
(standard?) is not default, it seems strange.
>
>
>> So I installed Jodatime, registered my converter and thought I was done
>> with it. But I wasn't. Unbeknownst to me, my persistence engine was
>> converting my java.util.date objects to java.sql.timestamp objects....
>> sometimes. One solution, of course, was to manually change that, since I
>> was using different objects for persistence and XML conversion, but that
>> seemed error-prone. Not a good solution. SO I thought the right was would
>> be to make XStream handle this.
>>
>> The problem was here:
>>
>> public class ISO8601DateConverter extends
>> ISO8601GregorianCalendarConverter {
>>
>> public boolean canConvert(Class type) {
>> return type.equals(Date.class);
>> }
>> ...
>> }
>>
>> The date converter was only handling java.util.Date classes and not
>> subclasses. Was that intentional? I don't know, but my solution was to do
>> this:
>>
>> public static ISO8601DateConverter DATE_CONVERTER = new
>> ISO8601DateConverter() { @Override
>> public boolean canConvert(Class type) {
>> return Date.class.isAssignableFrom(type);
>> }
>> };
>>
>> That worked! horray! Now java.util.Date AND ALL SUBCLASSES are converted
>> to ISO8601 dates, like I wanted.
>>
>> - Second Comment/question: Is this a bug, or was that intentional?
>
> Intentional. How can XStream know what additional fields/data a derived
> class might have? The ISO8601DateConverter will never produce a different
> string representation.
Okay. Makes sense.
>
>> If it
>> was intentional, is my subclassed cade safe?
>
> No.
>
>> Now here's the problem I don't really understand: the timestamp objects
>> still converted like this:
>>
>> <cTime class="sql-timestamp">2012-03-17T20:44:00.490Z</cTime>
>>
>> So the date/time format is right, but the class annotation confuses
>> XStream when trying to deserialize this.
>
> No, it is simply ignored, because the ISO8601DateConverter only creates Date
> instances. And XStream will throw an exception afterwards, since it expected
> the converter to produce a Timestamp.
You say "No", but I think we are in agreement: this is a problem.
>
>> The solution, which was
>> counterintuitive to me, was this:
>>
>> XStream xstream = super.createXstream(mediaType);
>>
> xstream.addDefaultImplementation(java.sql.Date.class,java.util.Date.class);
>>
> xstream.addDefaultImplementation(java.sql.Timestamp.class,java.util.Date.class);
>>
> xstream.addDefaultImplementation(java.sql.Time.class,java.util.Date.class);
>> xstream.registerConverter(DATE_CONVERTER);
>>
>> That gets rid of the pesky annotation, although I suppose some other
>> subclass could come along and mess things up.
>
> You simply suppressed the check of XStream. You still create only Date
> instances. XStream will no longer care if your data structures (and your
> application afterwards) expect something else. ClassCastExceptions are to be
> expected.
>
>> - Third comment/question: Is this the best way? Am I missing something? If
>> this is the best way, I think there should be a better way as this is
>> unintuitive and potentially error prone if another date subclass comes
>> along.
>
> Registering the ISO8601SqlTimestampConverter?
>
Okay. I'll try it.
thanks,
bjorn
> Cheers,
> Jörg
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>
-----------------------------
Bjorn Roche
http://www.xonami.com
Audio Collaboration
http://blog.bjornroche.com