diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBuffer.java index b225e07619..887f308a22 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DataBuffer.java @@ -25,10 +25,10 @@ import java.util.function.IntPredicate; * Basic abstraction over byte buffers. * *

{@code DataBuffer}s has a separate {@linkplain #readPosition() read} and - * {@linkplain #writePosition() write} position, as opposed to {@code ByteBuffer}'s single - * {@linkplain ByteBuffer#position() position}. As such, the {@code DataBuffer} does not require - * a {@linkplain ByteBuffer#flip() flip} to read after writing. In general, the following invariant - * holds for the read and write positions, and the capacity: + * {@linkplain #writePosition() write} position, as opposed to {@code ByteBuffer}'s + * single {@linkplain ByteBuffer#position() position}. As such, the {@code DataBuffer} + * does not require a {@linkplain ByteBuffer#flip() flip} to read after writing. In general, + * the following invariant holds for the read and write positions, and the capacity: * *

* 0 <= @@ -41,8 +41,8 @@ import java.util.function.IntPredicate; * similar to {@code StringBuilder}. * *

The main purpose of the {@code DataBuffer} abstraction is to provide a convenient wrapper - * around {@link ByteBuffer} that is similar to Netty's {@link io.netty.buffer.ByteBuf}, but that - * can also be used on non-Netty platforms (i.e. Servlet). + * around {@link ByteBuffer} which is similar to Netty's {@link io.netty.buffer.ByteBuf} but + * can also be used on non-Netty platforms (i.e. Servlet containers). * * @author Arjen Poutsma * @since 5.0 @@ -236,8 +236,8 @@ public interface DataBuffer { ByteBuffer asByteBuffer(); /** - * Expose a subsequence of this buffer's bytes as a {@link ByteBuffer}. Data between this - * {@code DataBuffer} and the returned {@code ByteBuffer} is shared; though + * Expose a subsequence of this buffer's bytes as a {@link ByteBuffer}. Data between + * this {@code DataBuffer} and the returned {@code ByteBuffer} is shared; though * changes in the returned buffer's {@linkplain ByteBuffer#position() position} * will not be reflected in the reading nor writing position of this data buffer. * @param index the index at which to start the byte buffer @@ -250,8 +250,8 @@ public interface DataBuffer { /** * Expose this buffer's data as an {@link InputStream}. Both data and read position are * shared between the returned stream and this data buffer. The underlying buffer will - * not be {@linkplain DataBufferUtils#release(DataBuffer) released} when the - * input stream is {@linkplain InputStream#close() closed}. + * not be {@linkplain DataBufferUtils#release(DataBuffer) released} + * when the input stream is {@linkplain InputStream#close() closed}. * @return this data buffer as an input stream * @see #asInputStream(boolean) */ 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 cd10a390eb..fe257ca022 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 @@ -20,8 +20,8 @@ import java.nio.ByteBuffer; import java.util.List; /** - * A factory for {@link DataBuffer}s, allowing for allocation and wrapping of - * data buffers. + * A factory for {@link DataBuffer DataBuffers}, allowing for allocation and + * wrapping of data buffers. * * @author Arjen Poutsma * @since 5.0 @@ -74,4 +74,5 @@ public interface DataBufferFactory { * @since 5.0.3 */ 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 0cce689ade..27d4eaf8e9 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 @@ -359,12 +359,10 @@ public abstract class DataBufferUtils { * process when subscribed to, and that publishes any writing errors and the completion signal * @since 5.0.10 */ - public static Flux write( - Publisher source, AsynchronousFileChannel channel) { + public static Flux write(Publisher source, AsynchronousFileChannel channel) { return write(source, channel, 0); } - /** * Write the given stream of {@link DataBuffer DataBuffers} to the given {@code AsynchronousFileChannel}. * Does not close the channel when the flux is terminated, and does diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java index b51b3f42ae..37fe545843 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java @@ -294,10 +294,7 @@ public class DefaultDataBuffer implements DataBuffer { @Override public DefaultDataBuffer write(DataBuffer... buffers) { if (!ObjectUtils.isEmpty(buffers)) { - ByteBuffer[] byteBuffers = - Arrays.stream(buffers).map(DataBuffer::asByteBuffer) - .toArray(ByteBuffer[]::new); - write(byteBuffers); + write(Arrays.stream(buffers).map(DataBuffer::asByteBuffer).toArray(ByteBuffer[]::new)); } return this; } @@ -381,6 +378,7 @@ public class DefaultDataBuffer implements DataBuffer { } /** + * Calculate the capacity of the buffer. * @see io.netty.buffer.AbstractByteBufAllocator#calculateNewCapacity(int, int) */ private int calculateCapacity(int neededCapacity) { @@ -430,7 +428,7 @@ public class DefaultDataBuffer implements DataBuffer { @Override public String toString() { - return String.format("DefaultDataBuffer (r: %d, w %d, c %d)", + return String.format("DefaultDataBuffer (r: %d, w: %d, c: %d)", this.readPosition, this.writePosition, this.capacity); } 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 67afdba079..2ccbc7b8f9 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 @@ -87,34 +87,28 @@ public class DefaultDataBufferFactory implements DataBufferFactory { ByteBuffer byteBuffer = (this.preferDirect ? ByteBuffer.allocateDirect(initialCapacity) : ByteBuffer.allocate(initialCapacity)); - return DefaultDataBuffer.fromEmptyByteBuffer(this, byteBuffer); } @Override public DefaultDataBuffer wrap(ByteBuffer byteBuffer) { - ByteBuffer sliced = byteBuffer.slice(); - return DefaultDataBuffer.fromFilledByteBuffer(this, sliced); + return DefaultDataBuffer.fromFilledByteBuffer(this, byteBuffer.slice()); } @Override public DataBuffer wrap(byte[] bytes) { - ByteBuffer wrapper = ByteBuffer.wrap(bytes); - return DefaultDataBuffer.fromFilledByteBuffer(this, wrapper); + return DefaultDataBuffer.fromFilledByteBuffer(this, ByteBuffer.wrap(bytes)); } /** * {@inheritDoc} - *

This implementation creates a single {@link DefaultDataBuffer} to contain the data - * in {@code dataBuffers}. + *

This implementation creates a single {@link DefaultDataBuffer} + * to contain the data in {@code dataBuffers}. */ @Override public DataBuffer join(List dataBuffers) { - Assert.notEmpty(dataBuffers, "'dataBuffers' must not be empty"); - - int capacity = dataBuffers.stream() - .mapToInt(DataBuffer::readableByteCount) - .sum(); + Assert.notEmpty(dataBuffers, "DataBuffer List must not be empty"); + int capacity = dataBuffers.stream().mapToInt(DataBuffer::readableByteCount).sum(); DefaultDataBuffer dataBuffer = allocateBuffer(capacity); DataBuffer result = dataBuffers.stream() .map(o -> (DataBuffer) o) @@ -123,6 +117,7 @@ public class DefaultDataBufferFactory implements DataBufferFactory { return result; } + @Override public String toString() { return "DefaultDataBufferFactory (preferDirect=" + this.preferDirect + ")"; diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBuffer.java index 2e6f6c8931..b3171da1eb 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/NettyDataBuffer.java @@ -27,6 +27,7 @@ import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; /** * Implementation of the {@code DataBuffer} interface that wraps a Netty @@ -43,7 +44,7 @@ public class NettyDataBuffer implements PooledDataBuffer { /** - * Creates a new {@code NettyDataBuffer} based on the given {@code ByteBuff}. + * Create a new {@code NettyDataBuffer} based on the given {@code ByteBuff}. * @param byteBuf the buffer to base this buffer on */ NettyDataBuffer(ByteBuf byteBuf, NettyDataBufferFactory dataBufferFactory) { @@ -69,7 +70,7 @@ public class NettyDataBuffer implements PooledDataBuffer { @Override public int indexOf(IntPredicate predicate, int fromIndex) { - Assert.notNull(predicate, "'predicate' must not be null"); + Assert.notNull(predicate, "IntPredicate must not be null"); if (fromIndex < 0) { fromIndex = 0; } @@ -82,7 +83,7 @@ public class NettyDataBuffer implements PooledDataBuffer { @Override public int lastIndexOf(IntPredicate predicate, int fromIndex) { - Assert.notNull(predicate, "'predicate' must not be null"); + Assert.notNull(predicate, "IntPredicate must not be null"); if (fromIndex < 0) { return -1; } @@ -175,9 +176,7 @@ public class NettyDataBuffer implements PooledDataBuffer { @Override public NettyDataBuffer write(DataBuffer... buffers) { - Assert.notNull(buffers, "'buffers' must not be null"); - - if (buffers.length > 0) { + if (!ObjectUtils.isEmpty(buffers)) { if (hasNettyDataBuffers(buffers)) { ByteBuf[] nativeBuffers = Arrays.stream(buffers) .map(b -> ((NettyDataBuffer) b).getNativeBuffer()) @@ -194,9 +193,9 @@ public class NettyDataBuffer implements PooledDataBuffer { return this; } - private static boolean hasNettyDataBuffers(DataBuffer[] dataBuffers) { - for (DataBuffer dataBuffer : dataBuffers) { - if (!(dataBuffer instanceof NettyDataBuffer)) { + private static boolean hasNettyDataBuffers(DataBuffer[] buffers) { + for (DataBuffer buffer : buffers) { + if (!(buffer instanceof NettyDataBuffer)) { return false; } } @@ -205,25 +204,25 @@ public class NettyDataBuffer implements PooledDataBuffer { @Override public NettyDataBuffer write(ByteBuffer... buffers) { - Assert.notNull(buffers, "'buffers' must not be null"); - - for (ByteBuffer buffer : buffers) { - this.byteBuf.writeBytes(buffer); + if (!ObjectUtils.isEmpty(buffers)) { + for (ByteBuffer buffer : buffers) { + this.byteBuf.writeBytes(buffer); + } } return this; } /** - * Writes one or more Netty {@link ByteBuf}s to this buffer, starting at the current - * writing position. + * Writes one or more Netty {@link ByteBuf}s to this buffer, + * starting at the current writing position. * @param byteBufs the buffers to write into this buffer * @return this buffer */ public NettyDataBuffer write(ByteBuf... byteBufs) { - Assert.notNull(byteBufs, "'byteBufs' must not be null"); - - for (ByteBuf byteBuf : byteBufs) { - this.byteBuf.writeBytes(byteBuf); + if (!ObjectUtils.isEmpty(byteBufs)) { + for (ByteBuf byteBuf : byteBufs) { + this.byteBuf.writeBytes(byteBuf); + } } return this; } @@ -272,7 +271,7 @@ public class NettyDataBuffer implements PooledDataBuffer { @Override public boolean equals(Object other) { - return (this == other || (other instanceof NettyDataBuffer && + return (this == other || (other instanceof NettyDataBuffer && this.byteBuf.equals(((NettyDataBuffer) other).byteBuf))); } 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 10272d8db7..fcff2f340a 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 @@ -42,7 +42,7 @@ public class NettyDataBufferFactory implements DataBufferFactory { /** - * Creates a new {@code NettyDataBufferFactory} based on the given factory. + * Create a new {@code NettyDataBufferFactory} based on the given factory. * @param byteBufAllocator the factory to use * @see io.netty.buffer.PooledByteBufAllocator * @see io.netty.buffer.UnpooledByteBufAllocator @@ -52,6 +52,7 @@ public class NettyDataBufferFactory implements DataBufferFactory { this.byteBufAllocator = byteBufAllocator; } + /** * Return the {@code ByteBufAllocator} used by this factory. */ @@ -133,4 +134,5 @@ public class NettyDataBufferFactory implements DataBufferFactory { public String toString() { return "NettyDataBufferFactory (" + this.byteBufAllocator + ")"; } + } diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/PooledDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/PooledDataBuffer.java index f12c6d0299..b821be4a63 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/PooledDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/PooledDataBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ public interface PooledDataBuffer extends DataBuffer { /** * Decrease the reference count for this buffer by one, and release it * once the count reaches zero. - * @return {@code true} if the buffer was released; {@code false} otherwise. + * @return {@code true} if the buffer was released; {@code false} otherwise */ boolean release(); diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index e66ed3fde0..226e680edd 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -449,7 +449,7 @@ public class HttpHeaders implements MultiValueMap, Serializable * @since 5.0 */ public void setAcceptLanguage(List languages) { - Assert.notNull(languages, "'languages' must not be null"); + Assert.notNull(languages, "LanguageRange List must not be null"); DecimalFormat decimal = new DecimalFormat("0.0", DECIMAL_FORMAT_SYMBOLS); List values = languages.stream() .map(range -> @@ -762,7 +762,7 @@ public class HttpHeaders implements MultiValueMap, Serializable * @see #getContentDisposition() */ public void setContentDispositionFormData(String name, @Nullable String filename) { - Assert.notNull(name, "'name' must not be null"); + Assert.notNull(name, "Name must not be null"); ContentDisposition.Builder disposition = ContentDisposition.builder("form-data").name(name); if (filename != null) { disposition.filename(filename); @@ -849,8 +849,8 @@ public class HttpHeaders implements MultiValueMap, Serializable */ public void setContentType(@Nullable MediaType mediaType) { if (mediaType != null) { - Assert.isTrue(!mediaType.isWildcardType(), "'Content-Type' cannot contain wildcard type '*'"); - Assert.isTrue(!mediaType.isWildcardSubtype(), "'Content-Type' cannot contain wildcard subtype '*'"); + Assert.isTrue(!mediaType.isWildcardType(), "Content-Type cannot contain wildcard type '*'"); + Assert.isTrue(!mediaType.isWildcardSubtype(), "Content-Type cannot contain wildcard subtype '*'"); set(CONTENT_TYPE, mediaType.toString()); } else { @@ -1222,13 +1222,6 @@ public class HttpHeaders implements MultiValueMap, Serializable set(headerName, formatDate(date)); } - // Package private: also used in ResponseCookie.. - static String formatDate(long date) { - Instant instant = Instant.ofEpochMilli(date); - ZonedDateTime time = ZonedDateTime.ofInstant(instant, GMT); - return DATE_FORMATTERS[0].format(time); - } - /** * Parse the first header value for the given header name as a date, * return -1 if there is no value, or raise {@link IllegalArgumentException} @@ -1330,10 +1323,7 @@ public class HttpHeaders implements MultiValueMap, Serializable List result = new ArrayList<>(); for (String value : values) { if (value != null) { - String[] tokens = StringUtils.tokenizeToStringArray(value, ","); - for (String token : tokens) { - result.add(token); - } + Collections.addAll(result, StringUtils.tokenizeToStringArray(value, ",")); } } return result; @@ -1392,7 +1382,7 @@ public class HttpHeaders implements MultiValueMap, Serializable */ protected String toCommaDelimitedString(List headerValues) { StringBuilder builder = new StringBuilder(); - for (Iterator it = headerValues.iterator(); it.hasNext(); ) { + for (Iterator it = headerValues.iterator(); it.hasNext();) { String val = it.next(); builder.append(val); if (it.hasNext()) { @@ -1565,4 +1555,11 @@ public class HttpHeaders implements MultiValueMap, Serializable return (headers.readOnly ? headers : new HttpHeaders(headers, true)); } + // Package-private: used in ResponseCookie + static String formatDate(long date) { + Instant instant = Instant.ofEpochMilli(date); + ZonedDateTime time = ZonedDateTime.ofInstant(instant, GMT); + return DATE_FORMATTERS[0].format(time); + } + } diff --git a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java index aac6acb9c5..964f751e42 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +64,7 @@ import org.springframework.util.ObjectUtils; * @author Arjen Poutsma * @author Brian Clozel * @since 3.0.2 + * @param the body type * @see #getStatusCode() */ public class ResponseEntity extends HttpEntity { @@ -293,8 +294,8 @@ public class ResponseEntity extends HttpEntity { /** * Defines a builder that adds headers to the response entity. - * @param the builder subclass * @since 4.1 + * @param the builder subclass */ public interface HeadersBuilder> { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java index 2ac629d119..adcc044f7c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultEntityResponseBuilder.java @@ -19,7 +19,6 @@ package org.springframework.web.reactive.function.server; import java.net.URI; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashSet; @@ -159,8 +158,7 @@ class DefaultEntityResponseBuilder implements EntityResponse.Builder { @Override public EntityResponse.Builder lastModified(ZonedDateTime lastModified) { ZonedDateTime gmt = lastModified.withZoneSameInstant(ZoneId.of("GMT")); - String headerValue = DateTimeFormatter.RFC_1123_DATE_TIME.format(gmt); - this.headers.set(HttpHeaders.LAST_MODIFIED, headerValue); + this.headers.setZonedDateTime(HttpHeaders.LAST_MODIFIED, gmt); return this; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java index 6de384821b..b7db95cf36 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerResponseBuilder.java @@ -272,6 +272,9 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder { } + /** + * Abstract base class for {@link ServerResponse} implementations. + */ abstract static class AbstractServerResponse implements ServerResponse { private static final Set SAFE_METHODS = EnumSet.of(HttpMethod.GET, HttpMethod.HEAD); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java index d54f78f1be..945d1d9c6a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/EntityResponse.java @@ -43,6 +43,7 @@ import org.springframework.web.reactive.function.BodyInserters; * @author Arjen Poutsma * @author Juergen Hoeller * @since 5.0 + * @param the entity type */ public interface EntityResponse extends ServerResponse { @@ -100,6 +101,8 @@ public interface EntityResponse extends ServerResponse { /** * Defines a builder for {@code EntityResponse}. + * + * @param a self reference to the builder type */ interface Builder { @@ -173,11 +176,11 @@ public interface EntityResponse extends ServerResponse { /** * Set the entity tag of the body, as specified by the {@code ETag} header. - * @param eTag the new entity tag + * @param etag the new entity tag * @return this builder * @see HttpHeaders#setETag(String) */ - Builder eTag(String eTag); + Builder eTag(String etag); /** * Set the time the resource was last changed, as specified by the diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java index 6c17558c23..aaaacbf7ae 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerResponse.java @@ -412,9 +412,9 @@ public interface ServerResponse { * Render the template with the given {@code name} using the given {@code modelAttributes}. * The model attributes are mapped under a * {@linkplain org.springframework.core.Conventions#getVariableName generated name}. - *

Note: Empty {@link Collection Collections} are not added to + *

Note: Empty {@link Collection Collections} are not added to * the model when using this method because we cannot correctly determine - * the true convention name. + * the true convention name. * @param name the name of the template to be rendered * @param modelAttributes the modelAttributes used to render the template * @return the built response