From c54fc82e475843f3fbaa2dc27644d662728f188d Mon Sep 17 00:00:00 2001 From: Alex Blekhman Date: Mon, 27 Mar 2023 19:47:25 +1100 Subject: [PATCH] Fix AtomicReference marshalling. Closes #326. --- .../extended/AtomicReferenceConverter.java | 30 +++++++++++-------- .../acceptance/Concurrent15TypesTest.java | 5 ++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/AtomicReferenceConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/AtomicReferenceConverter.java index a823f0de6..69de63d52 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/AtomicReferenceConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/AtomicReferenceConverter.java @@ -40,23 +40,29 @@ public boolean canConvert(final Class type) { } public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { - final AtomicReference ref = (AtomicReference)source; - writer.startNode(mapper.serializedMember(AtomicReference.class, "value")); - + final AtomicReference ref = (AtomicReference)source; final Object object = ref.get(); - final String name = mapper.serializedClass(object!= null ? object.getClass() : null); - writer.addAttribute(mapper.aliasForSystemAttribute("class"), name); - context.convertAnother(ref.get()); - writer.endNode(); + if (object != null) { + writer.startNode(mapper.serializedMember(AtomicReference.class, "value")); + + final String name = mapper.serializedClass(object.getClass()); + writer.addAttribute(mapper.aliasForSystemAttribute("class"), name); + context.convertAnother(object); + writer.endNode(); + } } public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { - reader.moveDown(); + if (reader.hasMoreChildren()) { + reader.moveDown(); - final Class type = HierarchicalStreams.readClassType(reader, mapper); - final Object value = context.convertAnother(context, type); - reader.moveUp(); - return new AtomicReference(value); + final Class type = HierarchicalStreams.readClassType(reader, mapper); + final Object value = context.convertAnother(context, type); + reader.moveUp(); + return new AtomicReference(value); + } else { + return new AtomicReference(); + } } } diff --git a/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java index 3670965fc..ea436fe08 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java @@ -117,6 +117,11 @@ public void testAtomicReferenceWithOldFormat() { + "")).get()); } + public void testEmptyAtomicReference() { + final AtomicReference atomicRef = new AtomicReference(); + assertBothWays(atomicRef, ""); + } + public void testAtomicReferenceWithAlias() { xstream.aliasField("junit", AtomicReference.class, "value"); final AtomicReference atomicRef = new AtomicReference("test");