XStream get parent object in converter -
for local converter, when marshalling xml, there way access parent object ?
i need marshall collection items third-party source - using id stored in parent object.
alas, there seem no way query object path leading current object. or there ?
i found solution little bit reflaction:
import java.io.inputstream; import java.lang.reflect.field; import java.util.list; import java.util.map; import org.junit.test; import org.springframework.util.reflectionutils; import com.thoughtworks.xstream.xstream; import com.thoughtworks.xstream.annotations.xstreamalias; import com.thoughtworks.xstream.annotations.xstreamasattribute; import com.thoughtworks.xstream.converters.converter; import com.thoughtworks.xstream.converters.marshallingcontext; import com.thoughtworks.xstream.converters.unmarshallingcontext; import com.thoughtworks.xstream.core.abstractreferenceunmarshaller; import com.thoughtworks.xstream.io.hierarchicalstreamreader; import com.thoughtworks.xstream.io.hierarchicalstreamwriter; import com.thoughtworks.xstream.io.path.path; import lombok.data; public class xstreamgetinfofromparenttest { @test public void smoketest() { inputstream file = xstreamgetinfofromparenttest.class.getresourceasstream("xstreamgetinfofromparenttest.xml"); xstream xstream = new xstream() { @override public void registerconverter(converter converter, int priority) { converter myconverter = new myconverterwrapper(converter); super.registerconverter(myconverter, priority); } }; xstream.processannotations(papa.class); xstream.processannotations(baby.class); papa papa = (papa) xstream.fromxml(file); system.out.println(papa); } public class myconverterwrapper implements converter { private converter converter; private boolean isbabyclass; public myconverterwrapper(converter converter) { this.converter = converter; } @override public boolean canconvert(class type) { this.isbabyclass = type.equals(baby.class); return converter.canconvert(type); } @override public void marshal(object source, hierarchicalstreamwriter writer, marshallingcontext context) { this.converter.marshal(source, writer, context); } @suppresswarnings({ "unchecked", "rawtypes" }) @override public object unmarshal(hierarchicalstreamreader reader, unmarshallingcontext context) { if (isbabyclass) { abstractreferenceunmarshaller runm = (abstractreferenceunmarshaller) context; field field = reflectionutils.findfield(abstractreferenceunmarshaller.class, "values"); field.setaccessible(true); map values = (map) reflectionutils.getfield(field, runm); values.foreach((key, value) -> { system.out.println(key + " : " + value); }); papa papa = (papa) values.get(new path("/papa")); system.out.println(papa.firstname); } return converter.unmarshal(reader, context); } } @xstreamalias("papa") @data public class papa { @xstreamasattribute private string firstname; private int age; private list<baby> babies; } @xstreamalias("baby") @data public class baby { private string firstname; } }
xml:
<?xml version="1.0" encoding="utf-8"?> <papa firstname="adam"> <age>33</age> <babies> <baby> <firstname>eva</firstname> </baby> </babies> </papa>
Comments
Post a Comment