diff --git a/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java b/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java index b7907787..3f564a40 100644 --- a/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java +++ b/src/main/java/org/springframework/hateoas/server/core/EmbeddedWrappers.java @@ -19,10 +19,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Optional; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.aop.support.AopUtils; +import org.springframework.core.ResolvableType; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.LinkRelation; import org.springframework.lang.NonNull; @@ -36,6 +38,8 @@ import org.springframework.util.Assert; */ public class EmbeddedWrappers { + private static ResolvableType SUPPLIER_OF_STREAM = ResolvableType.forClassWithGenerics(Supplier.class, Stream.class); + private final boolean preferCollections; /** @@ -83,9 +87,12 @@ public class EmbeddedWrappers { return (EmbeddedWrapper) source; } - return source instanceof Collection || source instanceof Stream || preferCollections - ? new EmbeddedCollection(asCollection(source), rel) - : new EmbeddedElement(source, rel); + return source instanceof Collection // + || source instanceof Stream // + || preferCollections // + || SUPPLIER_OF_STREAM.isAssignableFrom(source.getClass()) // + ? new EmbeddedCollection(asCollection(source), rel) // + : new EmbeddedElement(source, rel); } @SuppressWarnings("unchecked") @@ -107,6 +114,10 @@ public class EmbeddedWrappers { return Arrays.asList((Object[]) source); } + if (SUPPLIER_OF_STREAM.isInstance(source)) { + return asCollection(((Supplier>) source).get()); + } + return Collections.singleton(source); } diff --git a/src/test/java/org/springframework/hateoas/server/core/EmbeddedWrappersUnitTest.java b/src/test/java/org/springframework/hateoas/server/core/EmbeddedWrappersUnitTest.java index 012bb3a3..d4880382 100755 --- a/src/test/java/org/springframework/hateoas/server/core/EmbeddedWrappersUnitTest.java +++ b/src/test/java/org/springframework/hateoas/server/core/EmbeddedWrappersUnitTest.java @@ -17,8 +17,12 @@ package org.springframework.hateoas.server.core; import static org.assertj.core.api.Assertions.*; +import lombok.RequiredArgsConstructor; + import java.util.Collection; import java.util.Collections; +import java.util.function.Supplier; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.springframework.hateoas.LinkRelation; @@ -69,10 +73,36 @@ class EmbeddedWrappersUnitTest { }); } + @Test // #1335 + @SuppressWarnings("unchecked") + void addsSupplierOfStreamByResolvingIt() { + + EmbeddedWrapper wrap = wrappers.wrap(new Streamable<>(Stream.of(1, 2, 3))); + + assertThat(wrap.getValue()).isInstanceOfSatisfying(Collection.class, it -> { + assertThat(it).containsExactly(1, 2, 3); + }); + } + @SuppressWarnings("unchecked") private static void assertEmptyCollectionValue(EmbeddedWrapper wrapper) { assertThat(wrapper.getValue()) // .isInstanceOfSatisfying(Collection.class, it -> assertThat(it).isEmpty()); } + + @RequiredArgsConstructor + static class Streamable implements Supplier> { + + private final Stream stream; + + /* + * (non-Javadoc) + * @see java.util.function.Supplier#get() + */ + @Override + public Stream get() { + return stream; + } + } }