Thanks Jörg. It works for me. Best regards, Pawel
-----Original Message----- From: Jörg Schaible [mailto:joerg.schai...@swisspost.com] Sent: Monday, February 03, 2014 2:53 PM To: user@xstream.codehaus.org Subject: [xstream-user] Re: Alternative converter invocation when previous's call failed Hi Pawel, Kowalski, Pawel wrote: > > Hi, > > I have plenty of data (joda DateTime objects) serialized with default > (ReflectionConverter) now I'd like to simplify serialization and > created my own Converter for these objects. The issue is I'd like to > have possibility to support both versions at the same time as there is > no possibility to convert already exiting records. What I'm trying to > do is simply create new converter that will work more or less like following: > > Try to unmarshall in new version > If failed > Do something to call another converter (in my case > Reflection Converter)??? > > Is there possibility to manage above with existing XStream API? I mean > is there any way like throwing some exception to call alternative > converter once previous failed, or should I register converters in > some specific way? No. > How to get access to one converter from another? How to reset the > reader to point the same element as it was primary called with (once > data read multiple times moveDown/moveUp etc. and then failed)? Actually this last question is the problem, why it cannot work this way. XStream is stream-based and relies on the underlaying XML parser. There is no possibility to reset the individual parsers to a specific mark nor can you control the input stream because the parsers also use different caching mechanisms i.e. you never know how many of the read bytes have actually been processed by the XML parser. The best option is to use a version attribute in your root element: ========== %< ============ <root version="2"> [...] </root> ========== %< ============ Derive from the converter that will normally handle this element and get the version in the unmarshal method: ========== %< ============ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { String version = reader.getAttribute("version"); context.put("version", version == null ? "1" : version); return super.unmarshal(reader, context); } ========== %< ============ Now you take a similar approach for the Joda-Time types you want to handle. Simply derive from the converter that handled the type in the last version (assuming ReflectionConverter for now): ========== %< ============ class JodaTimeTypeConverter extends ReflectionConverter { public JodaTimeTypeConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper, reflectionProvider); } boolean canConvert(Class type) { return <true for the Joda-Time-Type this converter handles>; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { // your implementation for the new representation } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { String version = content.get("version"); if ("1".equals(version)) { // old format return super.unmarshal(reader, context); } else { // your implementation for the new representation } } } ========== %< ============ Cheers, Jörg --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email