Backported decoder optimizations and related polishing

Includes downgrade to Netty 4.1.31 for StringDecoderTests.
This commit is contained in:
Juergen Hoeller
2018-12-03 22:57:00 +01:00
parent 8bc06d20ac
commit d175d280a0
10 changed files with 51 additions and 57 deletions

View File

@@ -47,7 +47,7 @@ ext {
junitVintageVersion = "4.12.3"
kotlinVersion = "1.2.71"
log4jVersion = "2.11.1"
nettyVersion = "4.1.32.Final"
nettyVersion = "4.1.31.Final" // constrained by StringDecoderTests
reactorVersion = "Bismuth-SR14"
rxjavaVersion = "1.3.8"
rxjavaAdapterVersion = "1.2.1"

View File

@@ -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.
@@ -34,7 +34,6 @@ import org.springframework.util.MimeTypeUtils;
*/
public class ByteArrayDecoder extends AbstractDataBufferDecoder<byte[]> {
public ByteArrayDecoder() {
super(MimeTypeUtils.ALL);
}
@@ -42,8 +41,7 @@ public class ByteArrayDecoder extends AbstractDataBufferDecoder<byte[]> {
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.getRawClass();
return (super.canDecode(elementType, mimeType) && byte[].class == clazz);
return (elementType.getRawClass() == byte[].class && super.canDecode(elementType, mimeType));
}
@Override

View File

@@ -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.
@@ -36,7 +36,6 @@ import org.springframework.util.MimeTypeUtils;
*/
public class ByteBufferDecoder extends AbstractDataBufferDecoder<ByteBuffer> {
public ByteBufferDecoder() {
super(MimeTypeUtils.ALL);
}
@@ -45,7 +44,7 @@ public class ByteBufferDecoder extends AbstractDataBufferDecoder<ByteBuffer> {
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.getRawClass();
return (super.canDecode(elementType, mimeType) && clazz != null && ByteBuffer.class.isAssignableFrom(clazz));
return (clazz != null && ByteBuffer.class.isAssignableFrom(clazz) && super.canDecode(elementType, mimeType));
}
@Override

View File

@@ -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.
@@ -39,7 +39,6 @@ import org.springframework.util.MimeTypeUtils;
*/
public class DataBufferDecoder extends AbstractDataBufferDecoder<DataBuffer> {
public DataBufferDecoder() {
super(MimeTypeUtils.ALL);
}
@@ -48,7 +47,7 @@ public class DataBufferDecoder extends AbstractDataBufferDecoder<DataBuffer> {
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.getRawClass();
return (super.canDecode(elementType, mimeType) && clazz != null && DataBuffer.class.isAssignableFrom(clazz));
return (clazz != null && DataBuffer.class.isAssignableFrom(clazz) && super.canDecode(elementType, mimeType));
}
@Override

View File

@@ -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.
@@ -51,7 +51,7 @@ public class ResourceDecoder extends AbstractDataBufferDecoder<Resource> {
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.getRawClass();
return clazz != null && Resource.class.isAssignableFrom(clazz) && super.canDecode(elementType, mimeType);
return (clazz != null && Resource.class.isAssignableFrom(clazz) && super.canDecode(elementType, mimeType));
}
@Override
@@ -72,7 +72,7 @@ public class ResourceDecoder extends AbstractDataBufferDecoder<Resource> {
Class<?> clazz = elementType.getRawClass();
Assert.state(clazz != null, "No resource class");
if (InputStreamResource.class == clazz) {
if (clazz == InputStreamResource.class) {
return new InputStreamResource(new ByteArrayInputStream(bytes));
}
else if (Resource.class.isAssignableFrom(clazz)) {

View File

@@ -82,8 +82,7 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
return (super.canDecode(elementType, mimeType) &&
String.class.equals(elementType.getRawClass()));
return (elementType.getRawClass() == String.class && super.canDecode(elementType, mimeType));
}
@Override
@@ -107,8 +106,8 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
}
/**
* Splits the given data buffer on delimiter boundaries. The returned Flux contains a
* {@link #END_FRAME} buffer after each delimiter.
* Split the given data buffer on delimiter boundaries.
* The returned Flux contains an {@link #END_FRAME} buffer after each delimiter.
*/
private Flux<DataBuffer> splitOnDelimiter(DataBuffer dataBuffer, List<byte[]> delimiterBytes) {
List<DataBuffer> frames = new ArrayList<>();
@@ -116,9 +115,9 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
int length = Integer.MAX_VALUE;
byte[] matchingDelimiter = null;
for (byte[] delimiter : delimiterBytes) {
int idx = indexOf(dataBuffer, delimiter);
if (idx >= 0 && idx < length) {
length = idx;
int index = indexOf(dataBuffer, delimiter);
if (index >= 0 && index < length) {
length = index;
matchingDelimiter = delimiter;
}
}
@@ -149,8 +148,8 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
}
/**
* Finds the given delimiter in the given data buffer. Return the index of the delimiter, or
* -1 if not found.
* Find the given delimiter in the given data buffer.
* @return the index of the delimiter, or -1 if not found.
*/
private static int indexOf(DataBuffer dataBuffer, byte[] delimiter) {
for (int i = dataBuffer.readPosition(); i < dataBuffer.writePosition(); i++) {
@@ -169,7 +168,6 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
}
delimiterPos++;
}
if (delimiterPos == delimiter.length) {
return i - dataBuffer.readPosition();
}
@@ -178,14 +176,14 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
}
/**
* Checks whether the given buffer is {@link #END_FRAME}.
* Check whether the given buffer is {@link #END_FRAME}.
*/
private static boolean isEndFrame(DataBuffer dataBuffer) {
return dataBuffer == END_FRAME;
}
/**
* Joins the given list of buffers into a single buffer.
* Join the given list of buffers into a single buffer.
*/
private static Mono<DataBuffer> joinUntilEndFrame(List<DataBuffer> dataBuffers) {
if (!dataBuffers.isEmpty()) {
@@ -222,7 +220,7 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
* Create a {@code StringDecoder} for {@code "text/plain"}.
* @param ignored ignored
* @deprecated as of Spring 5.0.4, in favor of {@link #textPlainOnly()} or
* {@link #textPlainOnly(List, boolean)}.
* {@link #textPlainOnly(List, boolean)}
*/
@Deprecated
public static StringDecoder textPlainOnly(boolean ignored) {
@@ -238,17 +236,19 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
/**
* Create a {@code StringDecoder} for {@code "text/plain"}.
* @param delimiters delimiter strings to use to split the input stream
* @param stripDelimiter whether to remove delimiters from the resulting
* input strings
*/
public static StringDecoder textPlainOnly(List<String> delimiters, boolean stripDelimiter) {
return new StringDecoder(delimiters, stripDelimiter,
new MimeType("text", "plain", DEFAULT_CHARSET));
return new StringDecoder(delimiters, stripDelimiter, new MimeType("text", "plain", DEFAULT_CHARSET));
}
/**
* Create a {@code StringDecoder} that supports all MIME types.
* @param ignored ignored
* @deprecated as of Spring 5.0.4, in favor of {@link #allMimeTypes()} or
* {@link #allMimeTypes(List, boolean)}.
* {@link #allMimeTypes(List, boolean)}
*/
@Deprecated
public static StringDecoder allMimeTypes(boolean ignored) {
@@ -264,11 +264,13 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> {
/**
* Create a {@code StringDecoder} that supports all MIME types.
* @param delimiters delimiter strings to use to split the input stream
* @param stripDelimiter whether to remove delimiters from the resulting
* input strings
*/
public static StringDecoder allMimeTypes(List<String> delimiters, boolean stripDelimiter) {
return new StringDecoder(delimiters, stripDelimiter,
new MimeType("text", "plain", DEFAULT_CHARSET), MimeTypeUtils.ALL);
}
}

View File

@@ -35,6 +35,7 @@ import static org.junit.Assert.*;
/**
* Unit tests for {@link StringDecoder}.
*
* @author Sebastien Deleuze
* @author Brian Clozel
* @author Mark Paluch
@@ -46,23 +47,16 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
@Test
public void canDecode() {
assertTrue(this.decoder.canDecode(
ResolvableType.forClass(String.class), MimeTypeUtils.TEXT_PLAIN));
assertTrue(this.decoder.canDecode(
ResolvableType.forClass(String.class), MimeTypeUtils.TEXT_HTML));
assertTrue(this.decoder.canDecode(
ResolvableType.forClass(String.class), MimeTypeUtils.APPLICATION_JSON));
assertTrue(this.decoder.canDecode(
ResolvableType.forClass(String.class), MimeTypeUtils.parseMimeType("text/plain;charset=utf-8")));
assertFalse(this.decoder.canDecode(
ResolvableType.forClass(Integer.class), MimeTypeUtils.TEXT_PLAIN));
assertFalse(this.decoder.canDecode(
ResolvableType.forClass(Object.class), MimeTypeUtils.APPLICATION_JSON));
}
@@ -119,8 +113,7 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
@Test
public void decodeNewLineIncludeDelimiters() {
decoder = StringDecoder.allMimeTypes(StringDecoder.DEFAULT_DELIMITERS, false);
this.decoder = StringDecoder.allMimeTypes(StringDecoder.DEFAULT_DELIMITERS, false);
Flux<DataBuffer> source = Flux.just(
stringBuffer("\r\nabc\n"),
@@ -186,7 +179,7 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
}
@Test
public void decodeToMonoWithEmptyFlux() throws InterruptedException {
public void decodeToMonoWithEmptyFlux() {
Flux<DataBuffer> source = Flux.empty();
Mono<String> output = this.decoder.decodeToMono(source,
ResolvableType.forClass(String.class), null, Collections.emptyMap());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -81,8 +81,12 @@ public enum Isolation {
private final int value;
Isolation(int value) { this.value = value; }
Isolation(int value) {
this.value = value;
}
public int value() { return this.value; }
public int value() {
return this.value;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 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.
@@ -62,7 +62,7 @@ public enum Propagation {
* on all transaction managers. This in particular applies to
* {@link org.springframework.transaction.jta.JtaTransactionManager},
* which requires the {@code javax.transaction.TransactionManager} to be
* made available it to it (which is server-specific in standard Java EE).
* made available to it (which is server-specific in standard Java EE).
* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
*/
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
@@ -74,7 +74,7 @@ public enum Propagation {
* on all transaction managers. This in particular applies to
* {@link org.springframework.transaction.jta.JtaTransactionManager},
* which requires the {@code javax.transaction.TransactionManager} to be
* made available it to it (which is server-specific in standard Java EE).
* made available to it (which is server-specific in standard Java EE).
* @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
*/
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
@@ -100,8 +100,12 @@ public enum Propagation {
private final int value;
Propagation(int value) { this.value = value; }
Propagation(int value) {
this.value = value;
}
public int value() { return this.value; }
public int value() {
return this.value;
}
}

View File

@@ -81,14 +81,9 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
if (super.canDecode(elementType, mimeType)) {
Class<?> outputClass = elementType.getRawClass();
return (outputClass != null && (outputClass.isAnnotationPresent(XmlRootElement.class) ||
outputClass.isAnnotationPresent(XmlType.class)));
}
else {
return false;
}
Class<?> outputClass = elementType.getRawClass();
return (outputClass != null && (outputClass.isAnnotationPresent(XmlRootElement.class) ||
outputClass.isAnnotationPresent(XmlType.class)) && super.canDecode(elementType, mimeType));
}
@Override