Custom XStream converter creates unexpeted output for referenced objects
For ObjectProperty
I have created a custom converter for XStream
:
public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {
public ObjectPropertyConverter(Mapper mapper) {
super(ObjectProperty.class, mapper);
}
@Override
protected WritableValue<Object> createProperty() {
return new SimpleObjectProperty();
}
@Override
protected Class readType(HierarchicalStreamReader reader) {
return mapper.realClass(reader.getAttribute("propertyClass"));
}
@Override
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
final Class clazz = value.getClass();
final String propertyClass = mapper.serializedClass(clazz);
writer.addAttribute("propertyClass", propertyClass);
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<Object> property = createProperty();
if (reader.getAttribute("propertyClass") != null) {
final Object value = context.convertAnother(null, readType(reader));
property.setValue(value);
}
return property;
}
}
public abstract class AbstractPropertyConverter<T> implements Converter {
private final Class clazz;
protected final Mapper mapper;
public AbstractPropertyConverter(Class clazz, Mapper mapper) {
this.clazz = clazz;
this.mapper = mapper;
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
if (source != null) {
T value = ((ObservableValue<T>) source).getValue();
if (value != null) {
writeValue(writer, context, value);
}
}
}
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<T> property = createProperty();
final T value = (T) context.convertAnother(null, readType(reader));
property.setValue(value);
return property;
}
protected abstract WritableValue<T> createProperty();
protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);
public boolean canConvert(Class type) {
return clazz.isAssignableFrom(type);
}
}
In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty
. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
Here is the sample application to create said situation:
public class ObjectPropertyReferenceSerializer {
public static void main(String args) {
Item item1 = new Item("item1");
Item item2 = new Item("item2");
Item item3 = new Item("item3");
item2.setParent(item1);
item1.setParent(item3);
List<Item> list = asList(item1, item2, item3);
XStream xStream = getXstreamObject();
// Save to file
String filename = "xStreamCrayersWithReference.xml";
try {
xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
} catch (IOException e) {
e.printStackTrace();
}
}
private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
xstream.setMode(XStream.ID_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
return xstream;
}
}
And this output is created:
<java.util.Arrays_-ArrayList id="1">
<a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
<ch.sahits.game.openpatrician.app.model.Item id="3">
<uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
<name>item1</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
</parent>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="7">
<uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
<name>item2</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="9">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
</ch.sahits.game.openpatrician.app.model.Item>
</a>
</java.util.Arrays_-ArrayList>
The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty
it is inlined, meaning the outer most element () is missing.
How can I get the converter to produce output, that can be properly referenced?
java xstream converters
add a comment |
For ObjectProperty
I have created a custom converter for XStream
:
public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {
public ObjectPropertyConverter(Mapper mapper) {
super(ObjectProperty.class, mapper);
}
@Override
protected WritableValue<Object> createProperty() {
return new SimpleObjectProperty();
}
@Override
protected Class readType(HierarchicalStreamReader reader) {
return mapper.realClass(reader.getAttribute("propertyClass"));
}
@Override
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
final Class clazz = value.getClass();
final String propertyClass = mapper.serializedClass(clazz);
writer.addAttribute("propertyClass", propertyClass);
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<Object> property = createProperty();
if (reader.getAttribute("propertyClass") != null) {
final Object value = context.convertAnother(null, readType(reader));
property.setValue(value);
}
return property;
}
}
public abstract class AbstractPropertyConverter<T> implements Converter {
private final Class clazz;
protected final Mapper mapper;
public AbstractPropertyConverter(Class clazz, Mapper mapper) {
this.clazz = clazz;
this.mapper = mapper;
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
if (source != null) {
T value = ((ObservableValue<T>) source).getValue();
if (value != null) {
writeValue(writer, context, value);
}
}
}
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<T> property = createProperty();
final T value = (T) context.convertAnother(null, readType(reader));
property.setValue(value);
return property;
}
protected abstract WritableValue<T> createProperty();
protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);
public boolean canConvert(Class type) {
return clazz.isAssignableFrom(type);
}
}
In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty
. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
Here is the sample application to create said situation:
public class ObjectPropertyReferenceSerializer {
public static void main(String args) {
Item item1 = new Item("item1");
Item item2 = new Item("item2");
Item item3 = new Item("item3");
item2.setParent(item1);
item1.setParent(item3);
List<Item> list = asList(item1, item2, item3);
XStream xStream = getXstreamObject();
// Save to file
String filename = "xStreamCrayersWithReference.xml";
try {
xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
} catch (IOException e) {
e.printStackTrace();
}
}
private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
xstream.setMode(XStream.ID_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
return xstream;
}
}
And this output is created:
<java.util.Arrays_-ArrayList id="1">
<a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
<ch.sahits.game.openpatrician.app.model.Item id="3">
<uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
<name>item1</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
</parent>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="7">
<uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
<name>item2</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="9">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
</ch.sahits.game.openpatrician.app.model.Item>
</a>
</java.util.Arrays_-ArrayList>
The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty
it is inlined, meaning the outer most element () is missing.
How can I get the converter to produce output, that can be properly referenced?
java xstream converters
add a comment |
For ObjectProperty
I have created a custom converter for XStream
:
public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {
public ObjectPropertyConverter(Mapper mapper) {
super(ObjectProperty.class, mapper);
}
@Override
protected WritableValue<Object> createProperty() {
return new SimpleObjectProperty();
}
@Override
protected Class readType(HierarchicalStreamReader reader) {
return mapper.realClass(reader.getAttribute("propertyClass"));
}
@Override
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
final Class clazz = value.getClass();
final String propertyClass = mapper.serializedClass(clazz);
writer.addAttribute("propertyClass", propertyClass);
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<Object> property = createProperty();
if (reader.getAttribute("propertyClass") != null) {
final Object value = context.convertAnother(null, readType(reader));
property.setValue(value);
}
return property;
}
}
public abstract class AbstractPropertyConverter<T> implements Converter {
private final Class clazz;
protected final Mapper mapper;
public AbstractPropertyConverter(Class clazz, Mapper mapper) {
this.clazz = clazz;
this.mapper = mapper;
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
if (source != null) {
T value = ((ObservableValue<T>) source).getValue();
if (value != null) {
writeValue(writer, context, value);
}
}
}
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<T> property = createProperty();
final T value = (T) context.convertAnother(null, readType(reader));
property.setValue(value);
return property;
}
protected abstract WritableValue<T> createProperty();
protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);
public boolean canConvert(Class type) {
return clazz.isAssignableFrom(type);
}
}
In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty
. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
Here is the sample application to create said situation:
public class ObjectPropertyReferenceSerializer {
public static void main(String args) {
Item item1 = new Item("item1");
Item item2 = new Item("item2");
Item item3 = new Item("item3");
item2.setParent(item1);
item1.setParent(item3);
List<Item> list = asList(item1, item2, item3);
XStream xStream = getXstreamObject();
// Save to file
String filename = "xStreamCrayersWithReference.xml";
try {
xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
} catch (IOException e) {
e.printStackTrace();
}
}
private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
xstream.setMode(XStream.ID_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
return xstream;
}
}
And this output is created:
<java.util.Arrays_-ArrayList id="1">
<a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
<ch.sahits.game.openpatrician.app.model.Item id="3">
<uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
<name>item1</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
</parent>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="7">
<uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
<name>item2</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="9">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
</ch.sahits.game.openpatrician.app.model.Item>
</a>
</java.util.Arrays_-ArrayList>
The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty
it is inlined, meaning the outer most element () is missing.
How can I get the converter to produce output, that can be properly referenced?
java xstream converters
For ObjectProperty
I have created a custom converter for XStream
:
public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {
public ObjectPropertyConverter(Mapper mapper) {
super(ObjectProperty.class, mapper);
}
@Override
protected WritableValue<Object> createProperty() {
return new SimpleObjectProperty();
}
@Override
protected Class readType(HierarchicalStreamReader reader) {
return mapper.realClass(reader.getAttribute("propertyClass"));
}
@Override
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
final Class clazz = value.getClass();
final String propertyClass = mapper.serializedClass(clazz);
writer.addAttribute("propertyClass", propertyClass);
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<Object> property = createProperty();
if (reader.getAttribute("propertyClass") != null) {
final Object value = context.convertAnother(null, readType(reader));
property.setValue(value);
}
return property;
}
}
public abstract class AbstractPropertyConverter<T> implements Converter {
private final Class clazz;
protected final Mapper mapper;
public AbstractPropertyConverter(Class clazz, Mapper mapper) {
this.clazz = clazz;
this.mapper = mapper;
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
if (source != null) {
T value = ((ObservableValue<T>) source).getValue();
if (value != null) {
writeValue(writer, context, value);
}
}
}
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<T> property = createProperty();
final T value = (T) context.convertAnother(null, readType(reader));
property.setValue(value);
return property;
}
protected abstract WritableValue<T> createProperty();
protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);
public boolean canConvert(Class type) {
return clazz.isAssignableFrom(type);
}
}
In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty
. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
Here is the sample application to create said situation:
public class ObjectPropertyReferenceSerializer {
public static void main(String args) {
Item item1 = new Item("item1");
Item item2 = new Item("item2");
Item item3 = new Item("item3");
item2.setParent(item1);
item1.setParent(item3);
List<Item> list = asList(item1, item2, item3);
XStream xStream = getXstreamObject();
// Save to file
String filename = "xStreamCrayersWithReference.xml";
try {
xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
} catch (IOException e) {
e.printStackTrace();
}
}
private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
xstream.setMode(XStream.ID_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
return xstream;
}
}
And this output is created:
<java.util.Arrays_-ArrayList id="1">
<a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
<ch.sahits.game.openpatrician.app.model.Item id="3">
<uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
<name>item1</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
</parent>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="7">
<uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
<name>item2</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="9">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
</ch.sahits.game.openpatrician.app.model.Item>
</a>
</java.util.Arrays_-ArrayList>
The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty
it is inlined, meaning the outer most element () is missing.
How can I get the converter to produce output, that can be properly referenced?
java xstream converters
java xstream converters
edited Jan 1 at 12:31
hotzst
asked Jan 1 at 12:05


hotzsthotzst
4,46931643
4,46931643
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Replacing the converter with a more straight forward approach seems to work:
public class ObjectPropertyConverterV2 implements Converter {
private Mapper mapper;
public ObjectPropertyConverterV2(Mapper mapper) {
this.mapper = mapper;
}
@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
ObjectProperty objProperty = (ObjectProperty) o;
if (objProperty.get() != null) {
hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
marshallingContext.convertAnother(objProperty.get());
hierarchicalStreamWriter.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
String type = hierarchicalStreamReader.getAttribute("class");
ObjectProperty objProperty;
try {
objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
} catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
log.warn("Failed to create instance of type " + type, e);
objProperty = new SimpleObjectProperty();
}
if (hierarchicalStreamReader.hasMoreChildren()) {
hierarchicalStreamReader.moveDown();
Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
hierarchicalStreamReader.moveUp();
objProperty.setValue(value);
}
return objProperty;
}
@Override
public boolean canConvert(Class aClass) {
return ObjectProperty.class.isAssignableFrom(aClass);
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995286%2fcustom-xstream-converter-creates-unexpeted-output-for-referenced-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Replacing the converter with a more straight forward approach seems to work:
public class ObjectPropertyConverterV2 implements Converter {
private Mapper mapper;
public ObjectPropertyConverterV2(Mapper mapper) {
this.mapper = mapper;
}
@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
ObjectProperty objProperty = (ObjectProperty) o;
if (objProperty.get() != null) {
hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
marshallingContext.convertAnother(objProperty.get());
hierarchicalStreamWriter.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
String type = hierarchicalStreamReader.getAttribute("class");
ObjectProperty objProperty;
try {
objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
} catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
log.warn("Failed to create instance of type " + type, e);
objProperty = new SimpleObjectProperty();
}
if (hierarchicalStreamReader.hasMoreChildren()) {
hierarchicalStreamReader.moveDown();
Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
hierarchicalStreamReader.moveUp();
objProperty.setValue(value);
}
return objProperty;
}
@Override
public boolean canConvert(Class aClass) {
return ObjectProperty.class.isAssignableFrom(aClass);
}
}
add a comment |
Replacing the converter with a more straight forward approach seems to work:
public class ObjectPropertyConverterV2 implements Converter {
private Mapper mapper;
public ObjectPropertyConverterV2(Mapper mapper) {
this.mapper = mapper;
}
@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
ObjectProperty objProperty = (ObjectProperty) o;
if (objProperty.get() != null) {
hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
marshallingContext.convertAnother(objProperty.get());
hierarchicalStreamWriter.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
String type = hierarchicalStreamReader.getAttribute("class");
ObjectProperty objProperty;
try {
objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
} catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
log.warn("Failed to create instance of type " + type, e);
objProperty = new SimpleObjectProperty();
}
if (hierarchicalStreamReader.hasMoreChildren()) {
hierarchicalStreamReader.moveDown();
Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
hierarchicalStreamReader.moveUp();
objProperty.setValue(value);
}
return objProperty;
}
@Override
public boolean canConvert(Class aClass) {
return ObjectProperty.class.isAssignableFrom(aClass);
}
}
add a comment |
Replacing the converter with a more straight forward approach seems to work:
public class ObjectPropertyConverterV2 implements Converter {
private Mapper mapper;
public ObjectPropertyConverterV2(Mapper mapper) {
this.mapper = mapper;
}
@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
ObjectProperty objProperty = (ObjectProperty) o;
if (objProperty.get() != null) {
hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
marshallingContext.convertAnother(objProperty.get());
hierarchicalStreamWriter.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
String type = hierarchicalStreamReader.getAttribute("class");
ObjectProperty objProperty;
try {
objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
} catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
log.warn("Failed to create instance of type " + type, e);
objProperty = new SimpleObjectProperty();
}
if (hierarchicalStreamReader.hasMoreChildren()) {
hierarchicalStreamReader.moveDown();
Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
hierarchicalStreamReader.moveUp();
objProperty.setValue(value);
}
return objProperty;
}
@Override
public boolean canConvert(Class aClass) {
return ObjectProperty.class.isAssignableFrom(aClass);
}
}
Replacing the converter with a more straight forward approach seems to work:
public class ObjectPropertyConverterV2 implements Converter {
private Mapper mapper;
public ObjectPropertyConverterV2(Mapper mapper) {
this.mapper = mapper;
}
@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
ObjectProperty objProperty = (ObjectProperty) o;
if (objProperty.get() != null) {
hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
marshallingContext.convertAnother(objProperty.get());
hierarchicalStreamWriter.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
String type = hierarchicalStreamReader.getAttribute("class");
ObjectProperty objProperty;
try {
objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
} catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
log.warn("Failed to create instance of type " + type, e);
objProperty = new SimpleObjectProperty();
}
if (hierarchicalStreamReader.hasMoreChildren()) {
hierarchicalStreamReader.moveDown();
Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
hierarchicalStreamReader.moveUp();
objProperty.setValue(value);
}
return objProperty;
}
@Override
public boolean canConvert(Class aClass) {
return ObjectProperty.class.isAssignableFrom(aClass);
}
}
answered Jan 1 at 13:21


hotzsthotzst
4,46931643
4,46931643
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995286%2fcustom-xstream-converter-creates-unexpeted-output-for-referenced-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown