Browse Source

Backported decoder optimizations and related polishing

Includes downgrade to Netty 4.1.31 for StringDecoderTests.
pull/23430/head
Juergen Hoeller 7 years ago
parent
commit
d175d280a0
  1. 2
      build.gradle
  2. 6
      spring-core/src/main/java/org/springframework/core/codec/ByteArrayDecoder.java
  3. 5
      spring-core/src/main/java/org/springframework/core/codec/ByteBufferDecoder.java
  4. 5
      spring-core/src/main/java/org/springframework/core/codec/DataBufferDecoder.java
  5. 6
      spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java
  6. 36
      spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java
  7. 13
      spring-core/src/test/java/org/springframework/core/codec/StringDecoderTests.java
  8. 10
      spring-tx/src/main/java/org/springframework/transaction/annotation/Isolation.java
  9. 14
      spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java
  10. 11
      spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java

2
build.gradle

@ -47,7 +47,7 @@ ext { @@ -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"

6
spring-core/src/main/java/org/springframework/core/codec/ByteArrayDecoder.java

@ -1,5 +1,5 @@ @@ -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; @@ -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[]> { @@ -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

5
spring-core/src/main/java/org/springframework/core/codec/ByteBufferDecoder.java

@ -1,5 +1,5 @@ @@ -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; @@ -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> { @@ -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

5
spring-core/src/main/java/org/springframework/core/codec/DataBufferDecoder.java

@ -1,5 +1,5 @@ @@ -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; @@ -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> { @@ -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

6
spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java

@ -1,5 +1,5 @@ @@ -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> { @@ -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> { @@ -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)) {

36
spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java

@ -82,8 +82,7 @@ public class StringDecoder extends AbstractDataBufferDecoder<String> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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> { @@ -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);
}
}

13
spring-core/src/test/java/org/springframework/core/codec/StringDecoderTests.java

@ -35,6 +35,7 @@ import static org.junit.Assert.*; @@ -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 { @@ -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 { @@ -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 { @@ -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());

10
spring-tx/src/main/java/org/springframework/transaction/annotation/Isolation.java

@ -1,5 +1,5 @@ @@ -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 { @@ -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;
}
}

14
spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java

@ -1,5 +1,5 @@ @@ -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 { @@ -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 { @@ -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 { @@ -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;
}
}

11
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java

@ -81,14 +81,9 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> { @@ -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

Loading…
Cancel
Save