Polishing

This commit is contained in:
Juergen Hoeller 2017-03-24 13:41:34 +01:00
parent c4fda0e811
commit 21ac764e5c
12 changed files with 130 additions and 105 deletions

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");
* you may not use this file except in compliance with the License.
@ -186,7 +186,7 @@ class ConfigurationClassBeanDefinitionReader {
// Consider name and any aliases
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
List<String> names = new ArrayList<String>(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
for (String alias : names) {
@ -336,7 +336,7 @@ class ConfigurationClassBeanDefinitionReader {
}
readerInstanceCache.put(readerClass, reader);
}
catch (Exception ex) {
catch (Throwable ex) {
throw new IllegalStateException(
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
}

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");
* 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
* @since 2.5
* @see GenericCallMetaDataProvider
*/
public class CallParameterMetaData {
private String parameterName;
private int parameterType;
private int sqlType;
private String typeName;
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) {
this.parameterName = columnName;
@ -45,34 +52,35 @@ public class CallParameterMetaData {
* Get the parameter name.
*/
public String getParameterName() {
return parameterName;
return this.parameterName;
}
/**
* Get the parameter type.
*/
public int getParameterType() {
return parameterType;
return this.parameterType;
}
/**
* Get the parameter SQL type.
*/
public int getSqlType() {
return sqlType;
return this.sqlType;
}
/**
* Get the parameter type name.
*/
public String getTypeName() {
return typeName;
return this.typeName;
}
/**
* Get whether the parameter is nullable.
*/
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");
* 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
* @since 2.5
* @see GenericTableMetaDataProvider
*/
public class TableParameterMetaData {

View File

@ -450,7 +450,8 @@ public abstract class EntityManagerFactoryUtils {
/**
* 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
*/
private static class TransactionalEntityManagerSynchronization
@ -465,6 +466,7 @@ public abstract class EntityManagerFactoryUtils {
public TransactionalEntityManagerSynchronization(
EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) {
super(emHolder, emf);
this.transactionData = txData;
this.jpaDialect = (emf instanceof EntityManagerFactoryInfo ?
@ -512,7 +514,9 @@ public abstract class EntityManagerFactoryUtils {
}
@Override
protected void cleanupResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) {
protected void cleanupResource(
EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) {
if (!committed) {
// Clear all pending inserts/updates/deletes in the EntityManager.
// 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");
* 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 int testStartCount = 0;
public int testSuccessCount = 0;
public int testFailureCount = 0;
public int failedConfigurationsCount = 0;
@ -66,4 +69,5 @@ public class TrackingTestNGTestListener implements ITestListener {
public void onTestSuccess(ITestResult testResult) {
this.testSuccessCount++;
}
}
}

View File

@ -64,13 +64,15 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory,
}
/**
* Indicates whether this request factory should buffer the {@linkplain ClientHttpRequest#getBody() request body}
* internally.
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended
* to change this property to {@code false}, so as not to run out of memory. This will result in a
* {@link ClientHttpRequest} that either streams directly to the underlying {@link HttpURLConnection}
* (if the {@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).
* Indicate whether this request factory should buffer the
* {@linkplain ClientHttpRequest#getBody() request body} internally.
* <p>Default is {@code true}. When sending large amounts of data via POST or PUT,
* it is recommended to change this property to {@code false}, so as not to run
* out of memory. This will result in a {@link ClientHttpRequest} that either
* streams directly to the underlying {@link HttpURLConnection} (if the
* {@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 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.
* <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}
* Set the number of bytes to write in each chunk when not buffering request
* bodies locally.
* <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.
* @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");
* 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.
* <p>Default implementation returns:
* <ul>
* <li>{@code Boolean.FALSE} for boolean fields
* <li>an empty array for array types
* <li>Collection implementations for Collection types
* <li>Map implementations for Map types
* <li>else, {@code null} is used as default
* <li>{@code Boolean.FALSE} for boolean fields
* <li>an empty array for array types
* <li>Collection implementations for Collection types
* <li>Map implementations for Map types
* <li>else, {@code null} is used as default
* </ul>
* @param field the name of the field
* @param fieldType the type of the field

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");
* 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;
/**
* 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
* @since 3.0
@ -29,9 +30,9 @@ import org.springframework.http.client.ClientHttpResponse;
public interface ResponseErrorHandler {
/**
* Indicates whether the given response has any errors.
* Implementations will typically inspect the {@link ClientHttpResponse#getStatusCode() HttpStatus}
* of the response.
* Indicate whether the given response has any errors.
* <p>Implementations will typically inspect the
* {@link ClientHttpResponse#getStatusCode() HttpStatus} of the response.
* @param response the response to inspect
* @return {@code true} if the response has an error; {@code false} otherwise
* @throws IOException in case of I/O errors
@ -39,10 +40,12 @@ public interface ResponseErrorHandler {
boolean hasError(ClientHttpResponse response) throws IOException;
/**
* Handles the error in the given response.
* This method is only called when {@link #hasError(ClientHttpResponse)} has returned {@code true}.
* Handle the error in the given response.
* <p>This method is only called when {@link #hasError(ClientHttpResponse)}
* has returned {@code true}.
* @param response the response with the error
* @throws IOException in case of I/O errors
*/
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");
* you may not use this file except in compliance with the License.
@ -45,90 +45,88 @@ class HtmlCharacterEntityDecoder {
public HtmlCharacterEntityDecoder(HtmlCharacterEntityReferences characterEntityReferences, String original) {
this.characterEntityReferences = characterEntityReferences;
this.originalMessage = original;
this.decodedMessage = new StringBuilder(originalMessage.length());
this.decodedMessage = new StringBuilder(original.length());
}
public String decode() {
while (currentPosition < originalMessage.length()) {
findNextPotentialReference(currentPosition);
while (this.currentPosition < this.originalMessage.length()) {
findNextPotentialReference(this.currentPosition);
copyCharactersTillPotentialReference();
processPossibleReference();
}
return decodedMessage.toString();
return this.decodedMessage.toString();
}
private void findNextPotentialReference(int startPosition) {
nextPotentialReferencePosition = Math.max(startPosition, nextSemicolonPosition - MAX_REFERENCE_SIZE);
this.nextPotentialReferencePosition = Math.max(startPosition, this.nextSemicolonPosition - MAX_REFERENCE_SIZE);
do {
nextPotentialReferencePosition =
originalMessage.indexOf('&', nextPotentialReferencePosition);
this.nextPotentialReferencePosition =
this.originalMessage.indexOf('&', this.nextPotentialReferencePosition);
if (nextSemicolonPosition != -1 &&
nextSemicolonPosition < nextPotentialReferencePosition)
nextSemicolonPosition = originalMessage.indexOf(';', nextPotentialReferencePosition + 1);
if (this.nextSemicolonPosition != -1 &&
this.nextSemicolonPosition < this.nextPotentialReferencePosition)
this.nextSemicolonPosition = this.originalMessage.indexOf(';', this.nextPotentialReferencePosition + 1);
boolean isPotentialReference =
nextPotentialReferencePosition != -1
&& nextSemicolonPosition != -1
&& nextPotentialReferencePosition - nextSemicolonPosition < MAX_REFERENCE_SIZE;
boolean isPotentialReference = (this.nextPotentialReferencePosition != -1 &&
this.nextSemicolonPosition != -1 &&
this.nextPotentialReferencePosition - this.nextSemicolonPosition < MAX_REFERENCE_SIZE);
if (isPotentialReference) {
break;
}
if (nextPotentialReferencePosition == -1) {
if (this.nextPotentialReferencePosition == -1) {
break;
}
if (nextSemicolonPosition == -1) {
nextPotentialReferencePosition = -1;
if (this.nextSemicolonPosition == -1) {
this.nextPotentialReferencePosition = -1;
break;
}
nextPotentialReferencePosition = nextPotentialReferencePosition + 1;
this.nextPotentialReferencePosition = this.nextPotentialReferencePosition + 1;
}
while (nextPotentialReferencePosition != -1);
while (this.nextPotentialReferencePosition != -1);
}
private void copyCharactersTillPotentialReference() {
if (nextPotentialReferencePosition != currentPosition) {
int skipUntilIndex = nextPotentialReferencePosition != -1 ?
nextPotentialReferencePosition : originalMessage.length();
if (skipUntilIndex - currentPosition > 3) {
decodedMessage.append(originalMessage.substring(currentPosition, skipUntilIndex));
currentPosition = skipUntilIndex;
if (this.nextPotentialReferencePosition != this.currentPosition) {
int skipUntilIndex = (this.nextPotentialReferencePosition != -1 ?
this.nextPotentialReferencePosition : this.originalMessage.length());
if (skipUntilIndex - this.currentPosition > 3) {
this.decodedMessage.append(this.originalMessage.substring(this.currentPosition, skipUntilIndex));
this.currentPosition = skipUntilIndex;
}
else {
while (currentPosition < skipUntilIndex)
decodedMessage.append(originalMessage.charAt(currentPosition++));
while (this.currentPosition < skipUntilIndex)
this.decodedMessage.append(this.originalMessage.charAt(this.currentPosition++));
}
}
}
private void processPossibleReference() {
if (nextPotentialReferencePosition != -1) {
boolean isNumberedReference = originalMessage.charAt(currentPosition + 1) == '#';
if (this.nextPotentialReferencePosition != -1) {
boolean isNumberedReference = (this.originalMessage.charAt(this.currentPosition + 1) == '#');
boolean wasProcessable = isNumberedReference ? processNumberedReference() : processNamedReference();
if (wasProcessable) {
currentPosition = nextSemicolonPosition + 1;
this.currentPosition = this.nextSemicolonPosition + 1;
}
else {
char currentChar = originalMessage.charAt(currentPosition);
decodedMessage.append(currentChar);
currentPosition++;
char currentChar = this.originalMessage.charAt(this.currentPosition);
this.decodedMessage.append(currentChar);
this.currentPosition++;
}
}
}
private boolean processNumberedReference() {
boolean isHexNumberedReference =
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'x' ||
originalMessage.charAt(nextPotentialReferencePosition + 2) == 'X';
char referenceChar = this.originalMessage.charAt(this.nextPotentialReferencePosition + 2);
boolean isHexNumberedReference = (referenceChar == 'x' || referenceChar == 'X');
try {
int value = (!isHexNumberedReference) ?
int value = (!isHexNumberedReference ?
Integer.parseInt(getReferenceSubstring(2)) :
Integer.parseInt(getReferenceSubstring(3), 16);
decodedMessage.append((char) value);
Integer.parseInt(getReferenceSubstring(3), 16));
this.decodedMessage.append((char) value);
return true;
}
catch (NumberFormatException ex) {
@ -138,16 +136,17 @@ class HtmlCharacterEntityDecoder {
private boolean processNamedReference() {
String referenceName = getReferenceSubstring(1);
char mappedCharacter = characterEntityReferences.convertToCharacter(referenceName);
char mappedCharacter = this.characterEntityReferences.convertToCharacter(referenceName);
if (mappedCharacter != HtmlCharacterEntityReferences.CHAR_NULL) {
decodedMessage.append(mappedCharacter);
this.decodedMessage.append(mappedCharacter);
return true;
}
return false;
}
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-2015 the original author or authors.
* Copyright 2002-2017 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.
@ -94,7 +94,7 @@ public class GsonHttpMessageConverterTests {
assertEquals(42, n.longValue());
n = (Number) result.get("fraction");
assertEquals(42D, n.doubleValue(), 0D);
List<String> array = new ArrayList<String>();
List<String> array = new ArrayList<>();
array.add("Foo");
array.add("Bar");
assertEquals(array, result.get("array"));
@ -118,15 +118,14 @@ public class GsonHttpMessageConverterTests {
body.setBool(true);
body.setBytes(new byte[]{0x1, 0x2});
this.converter.write(body, null, outputMessage);
Charset utf8 = Charset.forName("UTF-8");
String result = outputMessage.getBodyAsString(utf8);
String result = outputMessage.getBodyAsString(UTF8);
assertTrue(result.contains("\"string\":\"Foo\""));
assertTrue(result.contains("\"number\":42"));
assertTrue(result.contains("fraction\":42.0"));
assertTrue(result.contains("\"array\":[\"Foo\",\"Bar\"]"));
assertTrue(result.contains("\"bool\":true"));
assertTrue(result.contains("\"bytes\":[1,2]"));
assertEquals("Invalid content-type", new MediaType("application", "json", utf8),
assertEquals("Invalid content-type", new MediaType("application", "json", UTF8),
outputMessage.getHeaders().getContentType());
}
@ -166,8 +165,7 @@ public class GsonHttpMessageConverterTests {
};
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(
body.getBytes(UTF8));
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(UTF8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
List<MyBean> results = (List<MyBean>) converter.read(List.class, inputMessage);
@ -189,8 +187,7 @@ public class GsonHttpMessageConverterTests {
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(
body.getBytes(UTF8));
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(UTF8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
GsonHttpMessageConverter converter = new GsonHttpMessageConverter();

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

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");
* 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 {
/**
* Class constructor.
* @param annotationNotRequired if "true", non-simple method arguments and
* return values are considered model attributes with or without a
* {@code @ModelAttribute} annotation
@ -87,19 +88,19 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
* a URI variable first and then a request parameter.
* @param attributeName the model attribute name
* @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) {
Map<String, String> variables = getUriTemplateVariables(request);
if (StringUtils.hasText(variables.get(attributeName))) {
return variables.get(attributeName);
String variableValue = variables.get(attributeName);
if (StringUtils.hasText(variableValue)) {
return variableValue;
}
else if (StringUtils.hasText(request.getParameter(attributeName))) {
return request.getParameter(attributeName);
}
else {
return null;
String parameterValue = request.getParameter(attributeName);
if (StringUtils.hasText(parameterValue)) {
return parameterValue;
}
return null;
}
@SuppressWarnings("unchecked")
@ -115,11 +116,12 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
* <p>The default implementation converts only if there a registered
* {@link Converter} that can perform the conversion.
* @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 binderFactory for creating WebDataBinder instance
* @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
*/
protected Object createAttributeFromRequestValue(String sourceValue, String attributeName,