Polishing

This commit is contained in:
Juergen Hoeller 2017-03-21 17:44:47 +01:00
parent 85f64706a8
commit e892e02f41
19 changed files with 162 additions and 137 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -186,7 +186,7 @@ class ConfigurationClassBeanDefinitionReader {
// Consider name and any aliases // Consider name and any aliases
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name"))); List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (names.size() > 0 ? names.remove(0) : methodName); String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
// Register aliases even when overridden // Register aliases even when overridden
for (String alias : names) { for (String alias : names) {
@ -336,7 +336,7 @@ class ConfigurationClassBeanDefinitionReader {
} }
readerInstanceCache.put(readerClass, reader); readerInstanceCache.put(readerClass, reader);
} }
catch (Exception ex) { catch (Throwable ex) {
throw new IllegalStateException( throw new IllegalStateException(
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]"); "Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -102,7 +102,7 @@ public class ReactiveAdapter {
/** /**
* Adapt the given instance to a Reactive Streams Publisher. * Adapt the given instance to a Reactive Streams Publisher.
* @param source the source object to adapt from * @param source the source object to adapt from
* @return the Publisher repesenting the adaptation * @return the Publisher representing the adaptation
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> Publisher<T> toPublisher(Object source) { public <T> Publisher<T> toPublisher(Object source) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,10 +30,7 @@ import rx.RxReactiveStreams;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import static org.springframework.core.ReactiveTypeDescriptor.multiValue; import static org.springframework.core.ReactiveTypeDescriptor.*;
import static org.springframework.core.ReactiveTypeDescriptor.noValue;
import static org.springframework.core.ReactiveTypeDescriptor.singleOptionalValue;
import static org.springframework.core.ReactiveTypeDescriptor.singleRequiredValue;
/** /**
* A registry of adapters to adapt a Reactive Streams {@link Publisher} to/from * A registry of adapters to adapt a Reactive Streams {@link Publisher} to/from
@ -69,15 +66,12 @@ public class ReactiveAdapterRegistry {
* Create a registry and auto-register default adapters. * Create a registry and auto-register default adapters.
*/ */
public ReactiveAdapterRegistry() { public ReactiveAdapterRegistry() {
if (reactorPresent) { if (reactorPresent) {
new ReactorRegistrar().registerAdapters(this); new ReactorRegistrar().registerAdapters(this);
} }
if (rxJava1Present && rxJava1Adapter) { if (rxJava1Present && rxJava1Adapter) {
new RxJava1Registrar().registerAdapters(this); new RxJava1Registrar().registerAdapters(this);
} }
if (rxJava2Present) { if (rxJava2Present) {
new RxJava2Registrar().registerAdapters(this); new RxJava2Registrar().registerAdapters(this);
} }
@ -111,15 +105,16 @@ public class ReactiveAdapterRegistry {
* Get the adapter for the given reactive type. Or if a "source" object is * Get the adapter for the given reactive type. Or if a "source" object is
* provided, its actual type is used instead. * provided, its actual type is used instead.
* @param reactiveType the reactive type * @param reactiveType the reactive type
* @param source an instance of the reactive type (i.e. to adapt from) * (may be {@code null} if a concrete source object is given)
* @param source an instance of the reactive type
* (i.e. to adapt from; may be {@code null} if the reactive type is specified)
*/ */
public ReactiveAdapter getAdapter(Class<?> reactiveType, Object source) { public ReactiveAdapter getAdapter(Class<?> reactiveType, Object source) {
Object sourceToUse = (source instanceof Optional ? ((Optional<?>) source).orElse(null) : source);
source = (source instanceof Optional ? ((Optional<?>) source).orElse(null) : source); Class<?> clazz = (sourceToUse != null ? sourceToUse.getClass() : reactiveType);
Class<?> clazz = (source != null ? source.getClass() : reactiveType);
return this.adapters.stream() return this.adapters.stream()
.filter(adapter -> adapter.getReactiveType().equals(clazz)) .filter(adapter -> adapter.getReactiveType() == clazz)
.findFirst() .findFirst()
.orElseGet(() -> .orElseGet(() ->
this.adapters.stream() this.adapters.stream()
@ -132,7 +127,6 @@ public class ReactiveAdapterRegistry {
private static class ReactorRegistrar { private static class ReactorRegistrar {
void registerAdapters(ReactiveAdapterRegistry registry) { void registerAdapters(ReactiveAdapterRegistry registry) {
// Flux and Mono ahead of Publisher... // Flux and Mono ahead of Publisher...
registry.registerReactiveType( registry.registerReactiveType(
@ -161,6 +155,7 @@ public class ReactiveAdapterRegistry {
} }
} }
private static class RxJava1Registrar { private static class RxJava1Registrar {
void registerAdapters(ReactiveAdapterRegistry registry) { void registerAdapters(ReactiveAdapterRegistry registry) {
@ -182,6 +177,7 @@ public class ReactiveAdapterRegistry {
} }
} }
private static class RxJava2Registrar { private static class RxJava2Registrar {
void registerAdapters(ReactiveAdapterRegistry registry) { void registerAdapters(ReactiveAdapterRegistry registry) {
@ -213,6 +209,7 @@ public class ReactiveAdapterRegistry {
} }
} }
/** /**
* Extension of ReactiveAdapter that wraps adapted (raw) Publisher's as * Extension of ReactiveAdapter that wraps adapted (raw) Publisher's as
* {@link Flux} or {@link Mono} depending on the underlying reactive type's * {@link Flux} or {@link Mono} depending on the underlying reactive type's

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,16 +21,23 @@ package org.springframework.jdbc.core.metadata;
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 2.5 * @since 2.5
* @see GenericCallMetaDataProvider
*/ */
public class CallParameterMetaData { public class CallParameterMetaData {
private String parameterName; private String parameterName;
private int parameterType; private int parameterType;
private int sqlType; private int sqlType;
private String typeName; private String typeName;
private boolean nullable; private boolean nullable;
/** /**
* Constructor taking all the properties * Constructor taking all the properties.
*/ */
public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) { public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) {
this.parameterName = columnName; this.parameterName = columnName;
@ -45,34 +52,35 @@ public class CallParameterMetaData {
* Get the parameter name. * Get the parameter name.
*/ */
public String getParameterName() { public String getParameterName() {
return parameterName; return this.parameterName;
} }
/** /**
* Get the parameter type. * Get the parameter type.
*/ */
public int getParameterType() { public int getParameterType() {
return parameterType; return this.parameterType;
} }
/** /**
* Get the parameter SQL type. * Get the parameter SQL type.
*/ */
public int getSqlType() { public int getSqlType() {
return sqlType; return this.sqlType;
} }
/** /**
* Get the parameter type name. * Get the parameter type name.
*/ */
public String getTypeName() { public String getTypeName() {
return typeName; return this.typeName;
} }
/** /**
* Get whether the parameter is nullable. * Get whether the parameter is nullable.
*/ */
public boolean isNullable() { public boolean isNullable() {
return nullable; return this.nullable;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2007 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ package org.springframework.jdbc.core.metadata;
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 2.5 * @since 2.5
* @see GenericTableMetaDataProvider
*/ */
public class TableParameterMetaData { public class TableParameterMetaData {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -426,7 +426,8 @@ public abstract class EntityManagerFactoryUtils {
/** /**
* Callback for resource cleanup at the end of a non-JPA transaction * Callback for resource cleanup at the end of a non-JPA transaction
* (e.g. when participating in a JtaTransactionManager transaction). * (e.g. when participating in a JtaTransactionManager transaction),
* fully synchronized with the ongoing transaction.
* @see org.springframework.transaction.jta.JtaTransactionManager * @see org.springframework.transaction.jta.JtaTransactionManager
*/ */
private static class TransactionalEntityManagerSynchronization private static class TransactionalEntityManagerSynchronization
@ -441,6 +442,7 @@ public abstract class EntityManagerFactoryUtils {
public TransactionalEntityManagerSynchronization( public TransactionalEntityManagerSynchronization(
EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) { EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) {
super(emHolder, emf); super(emHolder, emf);
this.transactionData = txData; this.transactionData = txData;
this.jpaDialect = (emf instanceof EntityManagerFactoryInfo ? this.jpaDialect = (emf instanceof EntityManagerFactoryInfo ?
@ -488,7 +490,9 @@ public abstract class EntityManagerFactoryUtils {
} }
@Override @Override
protected void cleanupResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) { protected void cleanupResource(
EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) {
if (!committed) { if (!committed) {
// Clear all pending inserts/updates/deletes in the EntityManager. // Clear all pending inserts/updates/deletes in the EntityManager.
// Necessary for pre-bound EntityManagers, to avoid inconsistent state. // Necessary for pre-bound EntityManagers, to avoid inconsistent state.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,8 +30,11 @@ import org.testng.ITestResult;
public class TrackingTestNGTestListener implements ITestListener { public class TrackingTestNGTestListener implements ITestListener {
public int testStartCount = 0; public int testStartCount = 0;
public int testSuccessCount = 0; public int testSuccessCount = 0;
public int testFailureCount = 0; public int testFailureCount = 0;
public int failedConfigurationsCount = 0; public int failedConfigurationsCount = 0;
@ -66,4 +69,5 @@ public class TrackingTestNGTestListener implements ITestListener {
public void onTestSuccess(ITestResult testResult) { public void onTestSuccess(ITestResult testResult) {
this.testSuccessCount++; this.testSuccessCount++;
} }
}
}

View File

@ -32,8 +32,7 @@ import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ExchangeFunction; import org.springframework.web.reactive.function.client.ExchangeFunction;
import org.springframework.web.reactive.function.client.ExchangeFunctions; import org.springframework.web.reactive.function.client.ExchangeFunctions;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
/** /**
* Unit tests for {@link WiretapConnector}. * Unit tests for {@link WiretapConnector}.
@ -46,7 +45,6 @@ public class WebTestClientConnectorTests {
@Test @Test
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void captureAndClaim() throws Exception { public void captureAndClaim() throws Exception {
ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test"); ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test");
ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK); ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response)); ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response));

View File

@ -64,13 +64,15 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
} }
/** /**
* Indicates whether this request factory should buffer the {@linkplain ClientHttpRequest#getBody() request body} * Indicate whether this request factory should buffer the
* internally. * {@linkplain ClientHttpRequest#getBody() request body} internally.
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended * <p>Default is {@code true}. When sending large amounts of data via POST or PUT,
* to change this property to {@code false}, so as not to run out of memory. This will result in a * it is recommended to change this property to {@code false}, so as not to run
* {@link ClientHttpRequest} that either streams directly to the underlying {@link HttpURLConnection} * out of memory. This will result in a {@link ClientHttpRequest} that either
* (if the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} is known in advance), * streams directly to the underlying {@link HttpURLConnection} (if the
* or that will use "Chunked transfer encoding" (if the {@code Content-Length} is not known in advance). * {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length}
* is known in advance), or that will use "Chunked transfer encoding"
* (if the {@code Content-Length} is not known in advance).
* @see #setChunkSize(int) * @see #setChunkSize(int)
* @see HttpURLConnection#setFixedLengthStreamingMode(int) * @see HttpURLConnection#setFixedLengthStreamingMode(int)
*/ */
@ -79,9 +81,11 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
} }
/** /**
* Sets the number of bytes to write in each chunk when not buffering request bodies locally. * Set the number of bytes to write in each chunk when not buffering request
* <p>Note that this parameter is only used when {@link #setBufferRequestBody(boolean) bufferRequestBody} is set * bodies locally.
* to {@code false}, and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} * <p>Note that this parameter is only used when
* {@link #setBufferRequestBody(boolean) bufferRequestBody} is set to {@code false},
* and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length}
* is not known in advance. * is not known in advance.
* @see #setBufferRequestBody(boolean) * @see #setBufferRequestBody(boolean)
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -248,11 +248,11 @@ public class WebDataBinder extends DataBinder {
* Determine an empty value for the specified field. * Determine an empty value for the specified field.
* <p>Default implementation returns: * <p>Default implementation returns:
* <ul> * <ul>
* <li>{@code Boolean.FALSE} for boolean fields * <li>{@code Boolean.FALSE} for boolean fields
* <li>an empty array for array types * <li>an empty array for array types
* <li>Collection implementations for Collection types * <li>Collection implementations for Collection types
* <li>Map implementations for Map types * <li>Map implementations for Map types
* <li>else, {@code null} is used as default * <li>else, {@code null} is used as default
* </ul> * </ul>
* @param field the name of the field * @param field the name of the field
* @param fieldType the type of the field * @param fieldType the type of the field

View File

@ -24,6 +24,7 @@ import java.util.TreeMap;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.MutablePropertyValues;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -82,16 +83,14 @@ public class WebExchangeDataBinder extends WebDataBinder {
for (Map.Entry<String, List<String>> entry : params.entrySet()) { for (Map.Entry<String, List<String>> entry : params.entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
List<String> values = entry.getValue(); List<String> values = entry.getValue();
if (values == null || values.isEmpty()) { if (CollectionUtils.isEmpty(values)) {
// Do nothing, no values found at all. // Do nothing, no values found at all.
} }
else if (values.size() == 1) {
result.put(name, values.get(0));
}
else { else {
if (values.size() > 1) { result.put(name, values);
result.put(name, values);
}
else {
result.put(name, values.get(0));
}
} }
} }
return result; return result;
@ -113,7 +112,7 @@ public class WebExchangeDataBinder extends WebDataBinder {
/** /**
* Extension point that subclasses can use to add extra bind values for a * Extension point that subclasses can use to add extra bind values for a
* request. Invoked before {@link #doBind(MutablePropertyValues)}. * request. Invoked before {@link #doBind(MutablePropertyValues)}.
* The default implementation is empty. * <p>The default implementation is empty.
* @param exchange the current exchange * @param exchange the current exchange
*/ */
protected Map<String, ?> getExtraValuesToBind(ServerWebExchange exchange) { protected Map<String, ?> getExtraValuesToBind(ServerWebExchange exchange) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,8 @@ import java.io.IOException;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
/** /**
* Strategy interface used by the {@link RestTemplate} to determine whether a particular response has an error or not. * Strategy interface used by the {@link RestTemplate} to determine
* whether a particular response has an error or not.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 3.0 * @since 3.0
@ -29,9 +30,9 @@ import org.springframework.http.client.ClientHttpResponse;
public interface ResponseErrorHandler { public interface ResponseErrorHandler {
/** /**
* Indicates whether the given response has any errors. * Indicate whether the given response has any errors.
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus} * <p>Implementations will typically inspect the
* of the response. * {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
* @param response the response to inspect * @param response the response to inspect
* @return {@code true} if the response has an error; {@code false} otherwise * @return {@code true} if the response has an error; {@code false} otherwise
* @throws IOException in case of I/O errors * @throws IOException in case of I/O errors
@ -39,10 +40,12 @@ public interface ResponseErrorHandler {
boolean hasError(ClientHttpResponse response) throws IOException; boolean hasError(ClientHttpResponse response) throws IOException;
/** /**
* Handles the error in the given response. * Handle the error in the given response.
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned {@code true}. * <p>This method is only called when {@link #hasError(ClientHttpResponse)}
* has returned {@code true}.
* @param response the response with the error * @param response the response with the error
* @throws IOException in case of I/O errors * @throws IOException in case of I/O errors
*/ */
void handleError(ClientHttpResponse response) throws IOException; void handleError(ClientHttpResponse response) throws IOException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2008 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,90 +45,88 @@ class HtmlCharacterEntityDecoder {
public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) { public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) {
this.characterEntityReferences = characterEntityReferences; this.characterEntityReferences = characterEntityReferences;
this.originalMessage = original; this.originalMessage = original;
this.decodedMessage = new StringBuilder(originalMessage.length()); this.decodedMessage = new StringBuilder(original.length());
} }
public String decode() { public String decode() {
while (currentPosition < originalMessage.length()) { while (this.currentPosition < this.originalMessage.length()) {
findNextPotentialReference(currentPosition); findNextPotentialReference(this.currentPosition);
copyCharactersTillPotentialReference(); copyCharactersTillPotentialReference();
processPossibleReference(); processPossibleReference();
} }
return decodedMessage.toString(); return this.decodedMessage.toString();
} }
private void findNextPotentialReference(int startPosition) { private void findNextPotentialReference(int startPosition) {
nextPotentialReferencePosition = Math.max(startPosition, nextSemicolonPosition - MAX_REFERENCE_SIZE); this.nextPotentialReferencePosition = Math.max(startPosition, this.nextSemicolonPosition - MAX_REFERENCE_SIZE);
do { do {
nextPotentialReferencePosition = this.nextPotentialReferencePosition =
originalMessage.indexOf('&', nextPotentialReferencePosition); this.originalMessage.indexOf('&', this.nextPotentialReferencePosition);
if (nextSemicolonPosition != -1 && if (this.nextSemicolonPosition != -1 &&
nextSemicolonPosition < nextPotentialReferencePosition) this.nextSemicolonPosition < this.nextPotentialReferencePosition)
nextSemicolonPosition = originalMessage.indexOf(';', nextPotentialReferencePosition + 1); this.nextSemicolonPosition = this.originalMessage.indexOf(';', this.nextPotentialReferencePosition + 1);
boolean isPotentialReference = boolean isPotentialReference = (this.nextPotentialReferencePosition != -1 &&
nextPotentialReferencePosition != -1 this.nextSemicolonPosition != -1 &&
&& nextSemicolonPosition != -1 this.nextPotentialReferencePosition - this.nextSemicolonPosition < MAX_REFERENCE_SIZE);
&& nextPotentialReferencePosition - nextSemicolonPosition < MAX_REFERENCE_SIZE;
if (isPotentialReference) { if (isPotentialReference) {
break; break;
} }
if (nextPotentialReferencePosition == -1) { if (this.nextPotentialReferencePosition == -1) {
break; break;
} }
if (nextSemicolonPosition == -1) { if (this.nextSemicolonPosition == -1) {
nextPotentialReferencePosition = -1; this.nextPotentialReferencePosition = -1;
break; break;
} }
nextPotentialReferencePosition = nextPotentialReferencePosition + 1; this.nextPotentialReferencePosition = this.nextPotentialReferencePosition + 1;
} }
while (nextPotentialReferencePosition != -1); while (this.nextPotentialReferencePosition != -1);
} }
private void copyCharactersTillPotentialReference() { private void copyCharactersTillPotentialReference() {
if (nextPotentialReferencePosition != currentPosition) { if (this.nextPotentialReferencePosition != this.currentPosition) {
int skipUntilIndex = nextPotentialReferencePosition != -1 ? int skipUntilIndex = (this.nextPotentialReferencePosition != -1 ?
nextPotentialReferencePosition : originalMessage.length(); this.nextPotentialReferencePosition : this.originalMessage.length());
if (skipUntilIndex - currentPosition > 3) { if (skipUntilIndex - this.currentPosition > 3) {
decodedMessage.append(originalMessage.substring(currentPosition, skipUntilIndex)); this.decodedMessage.append(this.originalMessage.substring(this.currentPosition, skipUntilIndex));
currentPosition = skipUntilIndex; this.currentPosition = skipUntilIndex;
} }
else { else {
while (currentPosition < skipUntilIndex) while (this.currentPosition < skipUntilIndex)
decodedMessage.append(originalMessage.charAt(currentPosition++)); this.decodedMessage.append(this.originalMessage.charAt(this.currentPosition++));
} }
} }
} }
private void processPossibleReference() { private void processPossibleReference() {
if (nextPotentialReferencePosition != -1) { if (this.nextPotentialReferencePosition != -1) {
boolean isNumberedReference = originalMessage.charAt(currentPosition + 1) == '#'; boolean isNumberedReference = (this.originalMessage.charAt(this.currentPosition + 1) == '#');
boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference(); boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference();
if (wasProcessable) { if (wasProcessable) {
currentPosition = nextSemicolonPosition + 1; this.currentPosition = this.nextSemicolonPosition + 1;
} }
else { else {
char currentChar = originalMessage.charAt(currentPosition); char currentChar = this.originalMessage.charAt(this.currentPosition);
decodedMessage.append(currentChar); this.decodedMessage.append(currentChar);
currentPosition++; this.currentPosition++;
} }
} }
} }
private boolean processNumberedReference() { private boolean processNumberedReference() {
boolean isHexNumberedReference = char referenceChar = this.originalMessage.charAt(this.nextPotentialReferencePosition + 2);
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'x' || boolean isHexNumberedReference = (referenceChar == 'x' || referenceChar == 'X');
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'X';
try { try {
int value = (!isHexNumberedReference) ? int value = (!isHexNumberedReference ?
Integer.parseInt(getReferenceSubstring(2)) : Integer.parseInt(getReferenceSubstring(2)) :
Integer.parseInt(getReferenceSubstring(3), 16); Integer.parseInt(getReferenceSubstring(3), 16));
decodedMessage.append((char) value); this.decodedMessage.append((char) value);
return true; return true;
} }
catch (NumberFormatException ex) { catch (NumberFormatException ex) {
@ -138,16 +136,17 @@ class HtmlCharacterEntityDecoder {
private boolean processNamedReference() { private boolean processNamedReference() {
String referenceName = getReferenceSubstring(1); String referenceName = getReferenceSubstring(1);
char mappedCharacter = characterEntityReferences.convertToCharacter(referenceName); char mappedCharacter = this.characterEntityReferences.convertToCharacter(referenceName);
if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) { if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) {
decodedMessage.append(mappedCharacter); this.decodedMessage.append(mappedCharacter);
return true; return true;
} }
return false; return false;
} }
private String getReferenceSubstring(int referenceOffset) { private String getReferenceSubstring(int referenceOffset) {
return originalMessage.substring(nextPotentialReferencePosition + referenceOffset, nextSemicolonPosition); return this.originalMessage.substring(
this.nextPotentialReferencePosition + referenceOffset, this.nextSemicolonPosition);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,7 +43,7 @@ import static org.junit.Assert.*;
*/ */
public class GsonHttpMessageConverterTests { public class GsonHttpMessageConverterTests {
private GsonHttpMessageConverter converter = new GsonHttpMessageConverter(); private final GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,13 +45,13 @@ import static org.junit.Assert.assertTrue;
*/ */
public class WebExchangeDataBinderTests { public class WebExchangeDataBinderTests {
private WebExchangeDataBinder binder;
private TestBean testBean; private TestBean testBean;
private WebExchangeDataBinder binder;
@Before @Before
public void setUp() throws Exception { public void setup() throws Exception {
this.testBean = new TestBean(); this.testBean = new TestBean();
this.binder = new WebExchangeDataBinder(this.testBean, "person"); this.binder = new WebExchangeDataBinder(this.testBean, "person");
this.binder.registerCustomEditor(ITestBean.class, new TestBeanPropertyEditor()); this.binder.registerCustomEditor(ITestBean.class, new TestBeanPropertyEditor());
@ -177,6 +177,7 @@ public class WebExchangeDataBinderTests {
assertEquals("test", this.testBean.getSpouse().getName()); assertEquals("test", this.testBean.getSpouse().getName());
} }
private String generateForm(MultiValueMap<String, String> form) { private String generateForm(MultiValueMap<String, String> form) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
try { try {

View File

@ -41,10 +41,17 @@ public class BindingContext {
private final Model model = new BindingAwareConcurrentModel(); private final Model model = new BindingAwareConcurrentModel();
/**
* Create a new {@code BindingContext}.
*/
public BindingContext() { public BindingContext() {
this(null); this(null);
} }
/**
* Create a new {@code BindingContext} with the given initializer.
* @param initializer the binding initializer to apply (may be {@code null})
*/
public BindingContext(WebBindingInitializer initializer) { public BindingContext(WebBindingInitializer initializer) {
this.initializer = initializer; this.initializer = initializer;
} }
@ -61,11 +68,9 @@ public class BindingContext {
/** /**
* Create a {@link WebExchangeDataBinder} to apply data binding and * Create a {@link WebExchangeDataBinder} to apply data binding and
* validation with on the target, command object. * validation with on the target, command object.
*
* @param exchange the current exchange * @param exchange the current exchange
* @param target the object to create a data binder for * @param target the object to create a data binder for
* @param name the name of the target object * @param name the name of the target object
*
* @return the created data binder * @return the created data binder
*/ */
public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, Object target, String name) { public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, Object target, String name) {
@ -86,10 +91,8 @@ public class BindingContext {
/** /**
* Create a {@link WebExchangeDataBinder} without a target object for type * Create a {@link WebExchangeDataBinder} without a target object for type
* conversion of request values to simple types. * conversion of request values to simple types.
*
* @param exchange the current exchange * @param exchange the current exchange
* @param name the name of the target object * @param name the name of the target object
*
* @return the created data binder * @return the created data binder
*/ */
public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, String name) { public WebExchangeDataBinder createDataBinder(ServerWebExchange exchange, String name) {

View File

@ -49,10 +49,10 @@ import reactor.core.publisher.Mono
* } * }
* ``` * ```
* *
* @author Sebastien Deleuze
* @author Yevhenii Melnyk
* @since 5.0 * @since 5.0
* @see <a href="https://youtrack.jetbrains.com/issue/KT-15667">Kotlin issue about supporting ::foo for member functions</a> * @see <a href="https://youtrack.jetbrains.com/issue/KT-15667">Kotlin issue about supporting ::foo for member functions</a>
* @author Sebastien De leuze
* @author Yevhenii Melnyk
*/ */
typealias Routes = RouterDsl.() -> Unit typealias Routes = RouterDsl.() -> Unit
@ -177,7 +177,6 @@ class RouterDsl {
fun pathExtension(predicate: (String) -> Boolean) = RequestPredicates.pathExtension(predicate) fun pathExtension(predicate: (String) -> Boolean) = RequestPredicates.pathExtension(predicate)
fun queryParam(name: String, predicate: (String) -> Boolean, f: (ServerRequest) -> Mono<ServerResponse>) { fun queryParam(name: String, predicate: (String) -> Boolean, f: (ServerRequest) -> Mono<ServerResponse>) {
routes += RouterFunctions.route(RequestPredicates.queryParam(name, predicate), HandlerFunction { f(it) }) routes += RouterFunctions.route(RequestPredicates.queryParam(name, predicate), HandlerFunction { f(it) })
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -54,6 +54,7 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder {
super(target, objectName); super(target, objectName);
} }
/** /**
* Merge URI variables into the property values to use for data binding. * Merge URI variables into the property values to use for data binding.
*/ */
@ -65,8 +66,10 @@ public class ExtendedServletRequestDataBinder extends ServletRequestDataBinder {
if (uriVars != null) { if (uriVars != null) {
for (Entry<String, String> entry : uriVars.entrySet()) { for (Entry<String, String> entry : uriVars.entrySet()) {
if (mpvs.contains(entry.getKey())) { if (mpvs.contains(entry.getKey())) {
logger.warn("Skipping URI variable '" + entry.getKey() if (logger.isWarnEnabled()) {
+ "' since the request contains a bind value with the same name."); logger.warn("Skipping URI variable '" + entry.getKey() +
"' since the request contains a bind value with the same name.");
}
} }
else { else {
mpvs.addPropertyValue(entry.getKey(), entry.getValue()); mpvs.addPropertyValue(entry.getKey(), entry.getValue());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -48,6 +48,7 @@ import org.springframework.web.servlet.HandlerMapping;
public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor { public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodProcessor {
/** /**
* Class constructor.
* @param annotationNotRequired if "true", non-simple method arguments and * @param annotationNotRequired if "true", non-simple method arguments and
* return values are considered model attributes with or without a * return values are considered model attributes with or without a
* {@code @ModelAttribute} annotation * {@code @ModelAttribute} annotation
@ -87,19 +88,19 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
* a URI variable first and then a request parameter. * a URI variable first and then a request parameter.
* @param attributeName the model attribute name * @param attributeName the model attribute name
* @param request the current request * @param request the current request
* @return the request value to try to convert or {@code null} * @return the request value to try to convert, or {@code null} if none
*/ */
protected String getRequestValueForAttribute(String attributeName, NativeWebRequest request) { protected String getRequestValueForAttribute(String attributeName, NativeWebRequest request) {
Map<String, String> variables = getUriTemplateVariables(request); Map<String, String> variables = getUriTemplateVariables(request);
if (StringUtils.hasText(variables.get(attributeName))) { String variableValue = variables.get(attributeName);
return variables.get(attributeName); if (StringUtils.hasText(variableValue)) {
return variableValue;
} }
else if (StringUtils.hasText(request.getParameter(attributeName))) { String parameterValue = request.getParameter(attributeName);
return request.getParameter(attributeName); if (StringUtils.hasText(parameterValue)) {
} return parameterValue;
else {
return null;
} }
return null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -115,11 +116,12 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
* <p>The default implementation converts only if there a registered * <p>The default implementation converts only if there a registered
* {@link Converter} that can perform the conversion. * {@link Converter} that can perform the conversion.
* @param sourceValue the source value to create the model attribute from * @param sourceValue the source value to create the model attribute from
* @param attributeName the name of the attribute, never {@code null} * @param attributeName the name of the attribute (never {@code null})
* @param methodParam the method parameter * @param methodParam the method parameter
* @param binderFactory for creating WebDataBinder instance * @param binderFactory for creating WebDataBinder instance
* @param request the current request * @param request the current request
* @return the created model attribute, or {@code null} * @return the created model attribute, or {@code null} if no suitable
* conversion found
* @throws Exception * @throws Exception
*/ */
protected Object createAttributeFromRequestValue(String sourceValue, String attributeName, protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,