diff --git a/src/main/java/org/joda/beans/ser/bin/BeanReferences.java b/src/main/java/org/joda/beans/ser/bin/BeanReferences.java index fb38cb3b..58401786 100644 --- a/src/main/java/org/joda/beans/ser/bin/BeanReferences.java +++ b/src/main/java/org/joda/beans/ser/bin/BeanReferences.java @@ -132,13 +132,13 @@ private void findReferencesBean( return; } - // has this object been seen before, if so no need to check it again - var result = objects.compute(base, BeanReferences::incrementOrOne); - if (result > 1) { - return; - } + if (base instanceof Bean) { + // has this object been seen before, if so no need to check it again + var result = objects.compute(base, BeanReferences::incrementOrOne); + if (result > 1) { + return; + } - if (base instanceof Bean bean) { addClassInfo(base, declaredClass); if (settings.getConverter().isConvertible(bean.getClass())) { return; @@ -165,11 +165,25 @@ private void findReferencesBean( } else if (parentIterator != null) { var childIterator = settings.getIteratorFactory().createChild(base, parentIterator); if (childIterator != null) { + if (childIterator.metaTypeRequired()) { + objects.compute(childIterator.metaTypeName(), BeanReferences::incrementOrOne); + } + // shouldn't try and reuse references to collections findReferencesIterable(childIterator, objects); } else { + // has this object been seen before, if so no need to check it again + int result = objects.compute(base, BeanReferences::incrementOrOne); + if (result > 1) { + return; + } addClassInfo(base, declaredClass); } } else { + // has this object been seen before, if so no need to check it again + int result = objects.compute(base, BeanReferences::incrementOrOne); + if (result > 1) { + return; + } addClassInfo(base, declaredClass); } } diff --git a/src/test/java/org/joda/beans/ser/SerTestHelper.java b/src/test/java/org/joda/beans/ser/SerTestHelper.java index 5f8b400d..e75f0384 100644 --- a/src/test/java/org/joda/beans/ser/SerTestHelper.java +++ b/src/test/java/org/joda/beans/ser/SerTestHelper.java @@ -19,10 +19,12 @@ import java.util.Currency; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import java.util.TreeSet; import org.joda.beans.sample.Address; import org.joda.beans.sample.Company; @@ -256,6 +258,17 @@ public static ImmGenericCollections testGenericInterfaces( .build(); } + public static ImmGenericCollections testGenericInterfacesCollections() { + return ImmGenericCollections.builder() + .map(ImmutableMap.of( + "First", Arrays.asList("A", "B"), + "First1", ImmutableList.of("A", "B"), + "Third1", new TreeSet<>(ImmutableList.of("A", "B")), + "Third", new HashSet<>(Arrays.asList("A", "B")), + "Second", testCollections())) + .build(); + } + public static ImmKeyList testIntermediateInterfaces() { // second serialized as JodaConvertInterface, non-bean // third and fourth are serialized as an intermediate Joda-Convert interface INamedKey diff --git a/src/test/java/org/joda/beans/ser/bin/TestSerializeReferencingBin.java b/src/test/java/org/joda/beans/ser/bin/TestSerializeReferencingBin.java index 85951380..34825bba 100644 --- a/src/test/java/org/joda/beans/ser/bin/TestSerializeReferencingBin.java +++ b/src/test/java/org/joda/beans/ser/bin/TestSerializeReferencingBin.java @@ -130,6 +130,17 @@ void test_writeJodaConvertInterface() { BeanAssert.assertBeanEquals(bean, parsed); } + @Test + void test_writeJodaConvertInterfaceCollections() { + var bean = SerTestHelper.testGenericInterfacesCollections(); + + var bytes = JodaBeanSer.COMPACT.binWriterReferencing().write(bean); +// System.out.println(JodaBeanBinReader.visualize(bytes)); + + var parsed = JodaBeanSer.COMPACT.binReader().read(bytes); + BeanAssert.assertBeanEquals(parsed, bean); + } + @Test void test_writeIntermediateInterface() { var bean = SerTestHelper.testIntermediateInterfaces();