/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.ebixio.virtmus.xml;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.mapper.Mapper;
import java.lang.reflect.Constructor;
/**
* This can be used for classes that have data members that are declared as
* "transient final". It invokes the default constructor to construct those
* objects, because final members can not be initialized in readResolve().
*
* <code>
* XStream xs = new XStream();
* xs.registerConverter(new DefaultConstructorConverter1(xs.getMapper(), xs.getReflectionProvider()));
*</code>
*
* @see <a href="http://www.blogs.uni-osnabrueck.de/rotapken/2010/08/20/let-xstream-call-the-default-constructor-where-possible/">
* Additional documentation.</a>
*/
public class DefaultConstructorConverter extends ReflectionConverter {
public DefaultConstructorConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
}
@Override
public boolean canConvert(Class clazz) {
for (Constructor c : clazz.getConstructors()) {
if (c.getParameterTypes().length == 0) {
return true;
}
}
return false;
}
@Override
protected Object instantiateNewInstance(HierarchicalStreamReader reader, UnmarshallingContext context) {
try {
//Class clazz = Class.forName(reader.getNodeName());
Class clazz = mapper.realClass(reader.getNodeName());
return clazz.newInstance();
} catch (Exception e) {
throw new ConversionException("Could not create instance of class " + reader.getNodeName(), e);
}
}
}