diff --git a/spring-core/src/main/java/org/springframework/core/codec/AbstractDataBufferDecoder.java b/spring-core/src/main/java/org/springframework/core/codec/AbstractDataBufferDecoder.java index 944bf6fca78..8da7a326125 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/AbstractDataBufferDecoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/AbstractDataBufferDecoder.java @@ -63,7 +63,7 @@ public abstract class AbstractDataBufferDecoder extends AbstractDecoder { public Mono decodeToMono(Publisher inputStream, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) { - return DataBufferUtils.compose(inputStream) + return DataBufferUtils.join(inputStream) .map(buffer -> decodeDataBuffer(buffer, elementType, mimeType, hints)); } diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferFactory.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferFactory.java index 5deade308f4..cd10a390ebb 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferFactory.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferFactory.java @@ -63,13 +63,15 @@ public interface DataBufferFactory { DataBuffer wrap(byte[] bytes); /** - * Create a composite data buffer from the list of provided data buffers. Depending on the - * implementation, the returned buffer may be a single buffer containing all data of the - * provided buffers, or it may be a true composite that contains references to the buffers. + * Return a new {@code DataBuffer} composed of the {@code dataBuffers} elements joined together. + * Depending on the implementation, the returned buffer may be a single buffer containing all + * data of the provided buffers, or it may be a true composite that contains references to the + * buffers. *

Note that the given data buffers do not have to be released, as they are * released as part of the returned composite. * @param dataBuffers the data buffers to be composed - * @return a buffer that composes {@code dataBuffers} into one + * @return a buffer that is composed from the {@code dataBuffers} argument + * @since 5.0.3 */ - DataBuffer compose(List dataBuffers); + DataBuffer join(List dataBuffers); } diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java index dbf577ca512..5140a152ad5 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java @@ -507,23 +507,23 @@ public abstract class DataBufferUtils { } /** - * Composes the buffers in the given {@link Publisher} into a single data buffer. Depending on - * the {@code DataBuffer} implementation, the returned buffer may be a single buffer containing - * all data of the provided buffers, or it may be a true composite that contains references to - * the buffers. - * @param publisher the data buffers that are to be composed - * @return the composed data buffer + * Return a new {@code DataBuffer} composed of the {@code dataBuffers} elements joined together. + * Depending on the {@link DataBuffer} implementation, the returned buffer may be a single + * buffer containing all data of the provided buffers, or it may be a true composite that + * contains references to the buffers. + * @param dataBuffers the data buffers that are to be composed + * @return a buffer that is composed from the {@code dataBuffers} argument + * @since 5.0.3 */ - public static Mono compose(Publisher publisher) { - Assert.notNull(publisher, "'publisher' must not be null"); + public static Mono join(Publisher dataBuffers) { + Assert.notNull(dataBuffers, "'dataBuffers' must not be null"); - Flux source = Flux.from(publisher); - - return source.collectList() - .filter(dataBuffers -> !dataBuffers.isEmpty()) - .map(dataBuffers -> { - DataBufferFactory bufferFactory = dataBuffers.get(0).factory(); - return bufferFactory.compose(dataBuffers); + return Flux.from(dataBuffers) + .collectList() + .filter(list -> !list.isEmpty()) + .map(list -> { + DataBufferFactory bufferFactory = list.get(0).factory(); + return bufferFactory.join(list); }); } diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBufferFactory.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBufferFactory.java index c04829c5a14..67afdba0797 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBufferFactory.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBufferFactory.java @@ -109,15 +109,18 @@ public class DefaultDataBufferFactory implements DataBufferFactory { * in {@code dataBuffers}. */ @Override - public DataBuffer compose(List dataBuffers) { + public DataBuffer join(List dataBuffers) { Assert.notEmpty(dataBuffers, "'dataBuffers' must not be empty"); int capacity = dataBuffers.stream() .mapToInt(DataBuffer::readableByteCount) .sum(); DefaultDataBuffer dataBuffer = allocateBuffer(capacity); - return dataBuffers.stream() + DataBuffer result = dataBuffers.stream() + .map(o -> (DataBuffer) o) .reduce(dataBuffer, DataBuffer::write); + dataBuffers.forEach(DataBufferUtils::release); + return result; } @Override diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBufferFactory.java b/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBufferFactory.java index 2b2eaba0aec..18b55a5e578 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBufferFactory.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBufferFactory.java @@ -87,7 +87,7 @@ public class NettyDataBufferFactory implements DataBufferFactory { *

This implementation uses Netty's {@link CompositeByteBuf}. */ @Override - public DataBuffer compose(List dataBuffers) { + public DataBuffer join(List dataBuffers) { Assert.notNull(dataBuffers, "'dataBuffers' must not be null"); CompositeByteBuf composite = this.byteBufAllocator.compositeBuffer(dataBuffers.size()); for (DataBuffer dataBuffer : dataBuffers) { diff --git a/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferTests.java b/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferTests.java index 89f3f111a26..e3b9fbb1dce 100644 --- a/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferTests.java @@ -480,8 +480,8 @@ public class DataBufferTests extends AbstractDataBufferAllocatingTestCase { } @Test - public void composite() { - DataBuffer composite = this.bufferFactory.compose(Arrays.asList(stringBuffer("a"), + public void join() { + DataBuffer composite = this.bufferFactory.join(Arrays.asList(stringBuffer("a"), stringBuffer("b"), stringBuffer("c"))); assertEquals(3, composite.readableByteCount()); byte[] bytes = new byte[3]; diff --git a/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java b/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java index e62b72ba561..de737fc5c43 100644 --- a/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferUtilsTests.java @@ -322,13 +322,13 @@ public class DataBufferUtilsTests extends AbstractDataBufferAllocatingTestCase { } @Test - public void compose() { + public void join() { DataBuffer foo = stringBuffer("foo"); DataBuffer bar = stringBuffer("bar"); DataBuffer baz = stringBuffer("baz"); Flux flux = Flux.just(foo, bar, baz); - DataBuffer result = DataBufferUtils.compose(flux).block(Duration.ofSeconds(5)); + DataBuffer result = DataBufferUtils.join(flux).block(Duration.ofSeconds(5)); assertEquals("foobarbaz", DataBufferTestUtils.dumpString(result, StandardCharsets.UTF_8)); diff --git a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java index 2be7b91c8f2..8611d2fb09e 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/FormHttpMessageReader.java @@ -96,7 +96,7 @@ public class FormHttpMessageReader implements HttpMessageReader { CharBuffer charBuffer = charset.decode(buffer.asByteBuffer()); String body = charBuffer.toString(); diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java index 4e7b24167d9..465d968d42e 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java @@ -103,7 +103,7 @@ public class XmlEventDecoder extends AbstractDecoder { .doFinally(signalType -> aaltoMapper.endOfInput()); } else { - Mono singleBuffer = DataBufferUtils.compose(flux); + Mono singleBuffer = DataBufferUtils.join(flux); return singleBuffer. flatMapMany(dataBuffer -> { try { diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReaderTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReaderTests.java index 2502bb9b628..a0b85b3c4d4 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReaderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReaderTests.java @@ -89,7 +89,7 @@ public class SynchronossPartHttpMessageReaderTests { assertTrue(part instanceof FilePart); assertEquals("fooPart", part.name()); assertEquals("foo.txt", ((FilePart) part).filename()); - DataBuffer buffer = DataBufferUtils.compose(part.content()).block(); + DataBuffer buffer = DataBufferUtils.join(part.content()).block(); assertEquals(12, buffer.readableByteCount()); byte[] byteContent = new byte[12]; buffer.read(byteContent); diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java index 13a5df723a4..5f97aa889b9 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/MultipartIntegrationTests.java @@ -103,7 +103,7 @@ public class MultipartIntegrationTests extends AbstractHttpHandlerIntegrationTes assertEquals("fooPart", part.name()); assertTrue(part instanceof FilePart); assertEquals("foo.txt", ((FilePart) part).filename()); - DataBuffer buffer = DataBufferUtils.compose(part.content()).block(); + DataBuffer buffer = DataBufferUtils.join(part.content()).block(); assertEquals(12, buffer.readableByteCount()); byte[] byteContent = new byte[12]; buffer.read(byteContent); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java index 5f5a123fbd2..f62b83218fc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java @@ -457,7 +457,7 @@ class DefaultWebClient implements WebClient { private static Mono createResponseException(ClientResponse response) { - return DataBufferUtils.compose(response.body(BodyExtractors.toDataBuffers())) + return DataBufferUtils.join(response.body(BodyExtractors.toDataBuffers())) .map(dataBuffer -> { byte[] bytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(bytes); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java index 024cce9fea1..d7e017b089c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java @@ -112,7 +112,7 @@ public class AppCacheManifestTransformer extends ResourceTransformerSupport { DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory(); Flux flux = DataBufferUtils .read(outputResource, bufferFactory, StreamUtils.BUFFER_SIZE); - return DataBufferUtils.compose(flux) + return DataBufferUtils.join(flux) .flatMap(dataBuffer -> { CharBuffer charBuffer = DEFAULT_CHARSET.decode(dataBuffer.asByteBuffer()); DataBufferUtils.release(dataBuffer); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ContentVersionStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ContentVersionStrategy.java index 4f45ab50901..876908b86e3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ContentVersionStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ContentVersionStrategy.java @@ -46,7 +46,7 @@ public class ContentVersionStrategy extends AbstractFileNameVersionStrategy { public Mono getResourceVersion(Resource resource) { Flux flux = DataBufferUtils.read(resource, dataBufferFactory, StreamUtils.BUFFER_SIZE); - return DataBufferUtils.compose(flux) + return DataBufferUtils.join(flux) .map(buffer -> { byte[] result = new byte[buffer.readableByteCount()]; buffer.read(result); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java index fa30b7f7750..ee656a70f69 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java @@ -89,7 +89,7 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory(); Flux flux = DataBufferUtils .read(ouptputResource, bufferFactory, StreamUtils.BUFFER_SIZE); - return DataBufferUtils.compose(flux) + return DataBufferUtils.join(flux) .flatMap(dataBuffer -> { CharBuffer charBuffer = DEFAULT_CHARSET.decode(dataBuffer.asByteBuffer()); DataBufferUtils.release(dataBuffer); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyInsertersTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyInsertersTests.java index 03fbcd28712..40c51f98e42 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyInsertersTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/BodyInsertersTests.java @@ -332,7 +332,7 @@ public class BodyInsertersTests { Mono result = inserter.insert(request, this.context); StepVerifier.create(result).expectComplete().verify(); - StepVerifier.create(DataBufferUtils.compose(request.getBody())) + StepVerifier.create(DataBufferUtils.join(request.getBody())) .consumeNextWith(dataBuffer -> { byte[] resultBytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(resultBytes);